Webhooks
Events
Every event a webhook endpoint can be sent, and the body each one carries.
Every delivery's body is an event: its type, the timestamp it happened at (ISO 8601), and its data. How deliveries are sent, signed and retried is in webhooks.
| type | Sent when |
|---|---|
chapter.finished | Every language of a chapter is translated. |
chapter.failed | A chapter's run failed, stalled, or was cut short. |
export.ready | A chapter's file is packaged, by its run or on request. |
ping | Someone pressed Test on the API screen. Sent whatever the endpoint's events. |
An endpoint is sent the events it was set up for. New events may be added; ignore a type you do not know, and answer it with a 2xx all the same.
chapter.finished
Every run of the chapter has ended, and none failed: each language is translated. The files follow, each with its own export.ready, and may arrive before this does.
{
"type": "chapter.finished",
"timestamp": "2026-09-28T12:46:51.500Z",
"data": {
"chapterId": "f56d2008-9c47-4554-9deb-7edc73255de9",
"projectId": "0cf217a0-c404-4fd7-8732-5f83b9e766ca",
"position": 1,
"title": null,
"pageCount": 18,
"languages": [
{ "languageCode": "en", "status": "needs_review", "failed": false },
{ "languageCode": "es", "status": "needs_review", "failed": false }
]
}
}interface ChapterFinished {
type: 'chapter.finished'
timestamp: string
data: ChapterEventData
}
interface ChapterEventData {
chapterId: string
projectId: string
position: number
title: string | null
pageCount: number
languages: {
languageCode: string
status: 'translating' | 'needs_review' | 'reviewed'
failed: boolean
}[]
}| Field | What it is |
|---|---|
chapterId, projectId | The chapter, and its project. |
position | The chapter number. |
title | Its title, or null. |
pageCount | Its pages. |
languages[] | Each target language: its status (translating, needs_review or reviewed) and whether its run failed. |
A chapter that runs again is announced again: after a re-scan, pages added to it, or a language added to its project. Each announcement is a new event, with its own webhook-id.
chapter.failed
A run of the chapter failed, stalled, or was cut short when the server restarted, and none is still going. The same fields as chapter.finished, and:
| Field | What it is |
|---|---|
failureReason | Why, in a sentence. |
languages[].failed | True for the languages whose run failed. |
{
"type": "chapter.failed",
"timestamp": "2026-09-28T13:02:10.114Z",
"data": {
"chapterId": "f56d2008-9c47-4554-9deb-7edc73255de9",
"projectId": "0cf217a0-c404-4fd7-8732-5f83b9e766ca",
"position": 1,
"title": null,
"pageCount": 18,
"languages": [
{ "languageCode": "en", "status": "needs_review", "failed": false },
{ "languageCode": "es", "status": "translating", "failed": true }
],
"failureReason": "The server restarted during this run, retry it"
}
}interface ChapterFailed {
type: 'chapter.failed'
timestamp: string
data: ChapterEventData & { failureReason: string }
}Re-scanning the chapter runs it again, and is announced with a chapter.finished once it succeeds.
export.ready
A file is ready to download: one a run packaged by itself, or one asked for with export/prepare. The same file is announced once; a file packaged again after the chapter changed is announced again.
{
"type": "export.ready",
"timestamp": "2026-09-28T12:46:51.473Z",
"data": {
"chapterId": "f56d2008-9c47-4554-9deb-7edc73255de9",
"projectId": "0cf217a0-c404-4fd7-8732-5f83b9e766ca",
"language": "en",
"format": "zip",
"filename": "chapter-1-en.zip",
"byteSize": 9862711,
"pageCount": 18,
"downloadUrl": "https://tinypica.com/api/v1/chapters/f56d2008-9c47-4554-9deb-7edc73255de9/export/download?language=en&format=zip"
}
}interface ExportReady {
type: 'export.ready'
timestamp: string
data: {
chapterId: string
projectId: string
language: string
format: 'zip' | 'clean' | 'txt' | 'docx' | 'source'
filename: string
byteSize: number
pageCount: number
downloadUrl: string
}
}| Field | What it is |
|---|---|
chapterId, projectId | The chapter, and its project. |
language | The language it was packaged under. clean and source are the same in every language, and are announced once, under the first. |
format | zip, clean, txt, docx or source. |
filename, byteSize | The file's name and size in bytes. |
pageCount | The chapter's pages in it. |
downloadUrl | Where a key downloads it, with GET and the key in its Authorization header. |
ping
Sent by the Test button, to see that an endpoint answers. Its webhook-id starts with ping_, and it is not retried.
{ "type": "ping", "timestamp": "2026-09-28T12:46:52.173Z", "data": {} }