Endpoints
Chapters
Create a chapter, add its pages, run it, read where it stands, and run it again.
A chapter is created in a project, given its pages, and run. Uploads are multipart/form-data; the rest take JSON or no body at all.
Create a chapter
POST/api/v1/projects/:id/chapters
A comic chapter with its pages, which runs at once; an empty one with staged=1, for its pages to follow; or a novel's chapter with its text, which runs at once. See uploading chapters for which to use.
| Form field | Type | What it is |
|---|---|---|
pages | file, repeated | A comic's page images, in reading order. Ignored with staged=1. |
staged | 1 | Create the chapter empty. Its pages come with POST /chapters/:id/pages. |
text | string | A novel's chapter, up to 200,000 characters. |
position | integer | The chapter number, 1 or more. The next one after the project's highest when left out. |
curl https://tinypica.com/api/v1/projects/$PROJECT/chapters \
-H "Authorization: Bearer $TINYPICA_KEY" \
-F staged=1{
"id": "f56d2008-9c47-4554-9deb-7edc73255de9",
"projectId": "0cf217a0-c404-4fd7-8732-5f83b9e766ca",
"position": 1,
"title": null,
"summary": null,
"assignedUserId": null,
"createdByUserId": null,
"deletedAt": null,
"createdAt": "2026-09-28T12:46:50.526Z",
"pages": []
}interface Chapter {
id: string
projectId: string
position: number
title: string | null
summary: string | null
createdAt: string
}
interface Page {
id: string
chapterId: string
position: number
createdAt: string
}
interface NewChapter extends Chapter {
pages: Page[]
}The answer is the chapter, with the pages it was given. It comes once the run has been started, not when it is done.
| Status | When |
|---|---|
400 | No page image and not staged; empty text; a chapter number that is not a whole number of 1 or more. |
402 | Not enough credits for the run. |
404 | Project not found. |
409 | This project already has a chapter 12. |
413, 415, 422 | A page image that is too large, an SVG, or one that cannot be opened. Text over 200,000 characters. |
List a project's chapters
GET/api/v1/projects/:id/chapters
Every chapter of the project that is not in the trash, by chapter number, each with where its run stands and the files it has.
[
{
"id": "f56d2008-9c47-4554-9deb-7edc73255de9",
"position": 1,
"title": null,
"summary": "Two people alone in a room, wary of each other.",
"pageCount": 18,
"started": true,
"processing": false,
"failed": false,
"failureReason": null,
"status": "needs_review",
"languages": [
{ "languageCode": "en", "status": "needs_review", "models": ["@cf/deepseek-ai/deepseek-v4-flash-0731"], "covered": 212, "failed": false, "exporting": false },
{ "languageCode": "es", "status": "needs_review", "models": ["@cf/deepseek-ai/deepseek-v4-flash-0731"], "covered": 212, "failed": false, "exporting": false }
],
"preparedExports": [
{ "languageCode": "en", "format": "cbz", "filename": "chapter-1-en.cbz", "byteSize": 9862711, "pageCount": 18, "preparedAt": "2026-09-28T12:51:51.463Z" }
],
"creditsSpent": 234,
"createdAt": "2026-09-28T12:46:50.526Z",
"lastActivityAt": "2026-09-28T12:51:50.979Z"
}
]type ChapterStatus = 'translating' | 'needs_review' | 'reviewed'
interface ChapterListItem extends Chapter {
pageCount: number
started: boolean
processing: boolean
failed: boolean
failureReason: string | null
status: ChapterStatus
languages: {
languageCode: string
status: ChapterStatus
covered: number
failed: boolean
exporting: boolean
models: string[]
}[]
preparedExports: {
languageCode: string
format: 'cbz' | 'zip' | 'psd' | 'clean' | 'txt' | 'docx' | 'source'
filename: string
byteSize: number
pageCount: number
preparedAt: string
}[]
creditsSpent: number
lastActivityAt: string
}| Field | What it is |
|---|---|
position | The chapter number. |
started | False for a staged chapter that was never started. |
processing, failed, failureReason, status | As on a single chapter. |
languages[] | Each target language: its status, how many lines are translated (covered), whether its run failed, whether its file is being packaged (exporting), and the models that translated it. |
preparedExports[] | The files ready to download. A cbz here is the run's finished pages, which a key downloads as zip. A psd is prepared in the dashboard, and a key cannot download it. |
creditsSpent | What the chapter has cost so far. |
Get a chapter
GET/api/v1/chapters/:id
Where one chapter stands. The route to ask while it runs.
{
"id": "f56d2008-9c47-4554-9deb-7edc73255de9",
"projectId": "0cf217a0-c404-4fd7-8732-5f83b9e766ca",
"position": 1,
"title": null,
"summary": "Two people alone in a room, wary of each other.",
"pageCount": 18,
"processing": false,
"detecting": false,
"failed": false,
"failureReason": null,
"status": "needs_review",
"languages": [
{ "languageCode": "en", "status": "needs_review", "untranslated": 0 },
{ "languageCode": "es", "status": "needs_review", "untranslated": 0 }
],
"project": { "id": "0cf217a0-…", "name": "Pepper & Carrot", "kind": "comic", "processSteps": "full", "…": "…" },
"assignee": null,
"createdAt": "2026-09-28T12:46:50.526Z"
}interface ChapterDetail extends Chapter {
pageCount: number
processing: boolean
detecting: boolean
failed: boolean
failureReason: string | null
status: ChapterStatus
languages: {
languageCode: string
status: ChapterStatus
untranslated: number
}[]
project: Project
}| Field | What it is |
|---|---|
processing | True while anything runs on the chapter: reading its pages, translating, packaging its files. |
detecting | True while its pages are being read, before any language starts. |
failed | True once a run failed or stalled. It stays true until the chapter is re-scanned, and can be true while processing is too. |
failureReason | Why, in a sentence, such as The run stalled and was abandoned, retry it. |
status | translating while a run goes or nothing is translated yet, needs_review once translated, reviewed once every line has been reviewed in the editor. |
languages[] | Each target language, with its own status and how many lines are still untranslated. |
summary | What happens in the chapter, written by the translation for the next one. Null until then. |
project | The chapter's project. |
404, Chapter not found, for a chapter that does not exist, is in the trash or is another workspace's.
Add pages
POST/api/v1/chapters/:id/pages
Pages for a comic chapter. On a chapter that has not run yet, a page without hold starts its run with every page it has; on one that has run, it runs by itself.
| Form field | Type | What it is |
|---|---|---|
pages | file, repeated | The page images. Required. |
hold | 1 | Keep the pages without running them. |
position | integer | The page number, with exactly one page. A page already there is replaced. Refused once the chapter has run: new pages go after the last one. |
curl https://tinypica.com/api/v1/chapters/$CHAPTER/pages \
-H "Authorization: Bearer $TINYPICA_KEY" \
-F "[email protected]" -F hold=1 -F position=1{
"chapterId": "f56d2008-9c47-4554-9deb-7edc73255de9",
"pages": [
{
"id": "3e28f20f-fd54-453e-b3cf-a5d52186af48",
"chapterId": "f56d2008-9c47-4554-9deb-7edc73255de9",
"position": 1,
"sourceImageR2Key": "projects/0cf217a0-…/chapters/f56d2008-…/pages/1.webp",
"createdAt": "2026-09-28T12:46:50.613Z"
}
]
}| Status | When |
|---|---|
400 | No page image; a page number with more than one page; a novel's chapter. |
402 | A balance of zero, or, when the pages would run, not enough credits for them. |
404 | Chapter not found. |
409 | The chapter is still running, or a page number was sent after it ran. |
413, 415, 422 | A page image that is too large, an SVG, or one that cannot be opened. |
Start a run
POST/api/v1/chapters/:id/start
Runs a staged chapter's pages. No body is needed the first time; the answer says how many pages were started.
curl -X POST https://tinypica.com/api/v1/chapters/$CHAPTER/start \
-H "Authorization: Bearer $TINYPICA_KEY"{ "chapterId": "f56d2008-9c47-4554-9deb-7edc73255de9", "pageCount": 18 } On a chapter that has run before, name the pages to run: the ones sent since with hold=1.
curl https://tinypica.com/api/v1/chapters/$CHAPTER/start \
-H "Authorization: Bearer $TINYPICA_KEY" \
-H "Content-Type: application/json" \
-d '{"pageIds": ["9b1d6c3e-…", "d0c5a2f1-…"]}'| Status | When |
|---|---|
400 | Upload at least one page before starting; on a chapter that has run, no pageIds of its own. |
402 | Not enough credits for every page in every language. |
404 | Chapter not found. |
409 | This chapter is still processing, try again when it finishes. |
Re-scan a chapter
POST/api/v1/chapters/:id/rescan
Runs the chapter again from its art: its pages are read again, and translated again into every language. This is how a failed run is retried, and it clears failed. It answers once the run is queued, with how many lines it cleared.
{ "queued": true, "clearedRegions": 212 }Every translation of the chapter is thrown away, edits included, and so are its prepared files. The run costs what a new one does. Glossary terms are kept.
| Status | When |
|---|---|
400 | A novel's chapter, which has nothing to read again: upload its text as a new chapter. A chapter with no pages. |
402 | Not enough credits for the run. |
404 | Chapter not found. |
409 | This chapter is already processing. |