{"openapi":"3.1.0","info":{"title":"Auto-Reader OCR + Translate API","description":"Multilingual OCR (Arabic-first, manga-aware), translation, and vision escalation.","version":"1.0.0"},"paths":{"/v1/illustrate":{"post":{"summary":"Illustrate Submit","operationId":"illustrate_submit_v1_illustrate_post","parameters":[{"name":"x-key-tier","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Key-Tier"}},{"name":"x-email-verified","in":"header","required":false,"schema":{"type":"string","default":"0","title":"X-Email-Verified"}},{"name":"x-credits-available","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Credits-Available"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IllustrateBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/illustrate/status":{"get":{"summary":"Illustrate Status","operationId":"illustrate_status_v1_illustrate_status_get","parameters":[{"name":"x-key-tier","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Key-Tier"}},{"name":"x-email-verified","in":"header","required":false,"schema":{"type":"string","default":"0","title":"X-Email-Verified"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/jobs/{job_id}/image/{n}":{"get":{"summary":"Illustrate Image","operationId":"illustrate_image_v1_jobs__job_id__image__n__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"n","in":"path","required":true,"schema":{"type":"integer","title":"N"}},{"name":"quality","in":"query","required":false,"schema":{"type":"string","default":"view","title":"Quality"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/illustrate/heartbeat":{"post":{"summary":"Agent Heartbeat","operationId":"agent_heartbeat_internal_illustrate_heartbeat_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentHello"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/illustrate/claim":{"post":{"summary":"Agent Claim","operationId":"agent_claim_internal_illustrate_claim_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentHello"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/illustrate/{job_id}/image/{n}":{"put":{"summary":"Agent Upload","operationId":"agent_upload_internal_illustrate__job_id__image__n__put","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"n","in":"path","required":true,"schema":{"type":"integer","title":"N"}},{"name":"agent","in":"query","required":true,"schema":{"type":"string","title":"Agent"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/illustrate/{job_id}/fail/{n}":{"post":{"summary":"Agent Fail","operationId":"agent_fail_internal_illustrate__job_id__fail__n__post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"n","in":"path","required":true,"schema":{"type":"integer","title":"N"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentFail"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/illustrate/book/analyse":{"post":{"summary":"Book Analyse","description":"Free: read the book (text, chapters, scanned pages) and quote every mode.","operationId":"book_analyse_v1_illustrate_book_analyse_post","parameters":[{"name":"x-credits-available","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Credits-Available"}},{"name":"x-key-tier","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Key-Tier"}},{"name":"x-email-verified","in":"header","required":false,"schema":{"type":"string","default":"0","title":"X-Email-Verified"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_book_analyse_v1_illustrate_book_analyse_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/illustrate/book":{"post":{"summary":"Book Submit","operationId":"book_submit_v1_illustrate_book_post","parameters":[{"name":"x-key-tier","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Key-Tier"}},{"name":"x-email-verified","in":"header","required":false,"schema":{"type":"string","default":"0","title":"X-Email-Verified"}},{"name":"x-credits-available","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Credits-Available"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/illustrate/book/{book_id}/quote":{"get":{"summary":"Book Continue Quote","description":"Free: what continuing a finished book would add and cost (no LLM, no writes).","operationId":"book_continue_quote_v1_illustrate_book__book_id__quote_get","parameters":[{"name":"book_id","in":"path","required":true,"schema":{"type":"string","title":"Book Id"}},{"name":"mode","in":"query","required":false,"schema":{"type":"string","default":"minimal","title":"Mode"}},{"name":"n","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"N"}},{"name":"per_context","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Per Context"}},{"name":"x-key-tier","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Key-Tier"}},{"name":"x-email-verified","in":"header","required":false,"schema":{"type":"string","default":"0","title":"X-Email-Verified"}},{"name":"x-credits-available","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Credits-Available"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/illustrate/book/{book_id}/continue":{"post":{"summary":"Book Continue","description":"Illustrate more of a finished book: billed exactly its quote, up front. The\nbook keeps its style, era, custom words, detail and language; only the new\nmoments are drawn, then every download is rebuilt with all the pictures.\nX-Job-Id is this charge's own id (<book id>.cN) for the Worker's refund record;\npoll the book as before (/v1/jobs/<book id>).","operationId":"book_continue_v1_illustrate_book__book_id__continue_post","parameters":[{"name":"book_id","in":"path","required":true,"schema":{"type":"string","title":"Book Id"}},{"name":"x-key-tier","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Key-Tier"}},{"name":"x-email-verified","in":"header","required":false,"schema":{"type":"string","default":"0","title":"X-Email-Verified"}},{"name":"x-credits-available","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Credits-Available"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContinueBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/illustrate/custom-terms":{"get":{"summary":"Custom Terms","description":"Owner insight (control panel): custom styles/eras readers typed. Anonymous.","operationId":"custom_terms_internal_illustrate_custom_terms_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/quota":{"post":{"summary":"Internal Quota","description":"Per-IP daily counters for the Worker's keyless boxes (replaces Workers KV).\n\n{\"k\": \"<bucket>:<ip>:<day>\"} reads; add \"n\" to increment. The day is part of\nthe key, so rows older than 3 days are just purged.","operationId":"internal_quota_internal_quota_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ocr":{"post":{"summary":"Ocr Multipart","description":"OCR via multipart upload. 1 credit/standard page; format=markdown adds\na RAG-ready `markdown` field (headings/tables reconstructed) at 2/page.\nEvery block carries `type`; detail=words adds approximate `words[]`.\nArabic/Persian/Urdu text is auto-proofread (free minimal-edit LLM pass);\npass proofread=true/false to force it on/off for any language.","operationId":"ocr_multipart_v1_ocr_post","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_ocr_multipart_v1_ocr_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ocr/base64":{"post":{"summary":"Ocr Base64","description":"OCR via JSON base64 (easier for LLM agents to call). 1 credit/standard\npage; format=markdown adds a RAG-ready `markdown` field at 2/page.\nEvery block carries `type`; detail=words adds approximate `words[]`.","operationId":"ocr_base64_v1_ocr_base64_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcrJsonBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/manga":{"post":{"summary":"Manga Multipart","description":"Comic/manga OCR, routed by LANGUAGE (not the \"manga = Japanese\"\nassumption): Japanese -> manga-ocr (vertical, right-to-left speech bubbles,\nbest for hand-lettered manga); Korean manhwa, Chinese manhua and other\nscripts -> their own pack in reading order; low-confidence pages escalate to\nthe vision safety net like /v1/ocr. Blocks come back in reading order with\nboxes, ready to render panel-by-panel. 1 credit/standard page (+2 if a page\nescalates). For best non-Japanese results, pass lang explicitly (ko/zh/...).","operationId":"manga_multipart_v1_manga_post","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_manga_multipart_v1_manga_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/manga/base64":{"post":{"summary":"Manga Base64","description":"Manga OCR via JSON base64 (agent-friendly). Same routing and pricing as\n/v1/manga; `mode`/`format` on the body are ignored (manga is always\ndocument-style, JSON out).","operationId":"manga_base64_v1_manga_base64_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcrJsonBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/detect":{"post":{"summary":"Detect Multipart","description":"Detect the language/script of an image — free (0 credits).","operationId":"detect_multipart_v1_detect_post","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_detect_multipart_v1_detect_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/detect/base64":{"post":{"summary":"Detect Base64","description":"Detect the language/script of an image (JSON base64) — free.","operationId":"detect_base64_v1_detect_base64_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcrJsonBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/extract":{"post":{"summary":"Extract Multipart","description":"Schema-driven structured extraction from a document image (invoice /\nreceipt / id presets, or your own JSON schema). 5 credits/standard page;\npreset=zatca (Saudi e-invoice + QR validation) 7.","operationId":"extract_multipart_v1_extract_post","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_extract_multipart_v1_extract_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/extract/base64":{"post":{"summary":"Extract Base64","description":"Structured extraction, JSON base64 variant (5 credits/page; zatca 7).","operationId":"extract_base64_v1_extract_base64_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractJsonBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ocr-translate":{"post":{"summary":"Ocr Translate Multipart","description":"OCR then translate in one call.","operationId":"ocr_translate_multipart_v1_ocr_translate_post","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_ocr_translate_multipart_v1_ocr_translate_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ocr-translate/base64":{"post":{"summary":"Ocr Translate Base64","description":"OCR then translate in one call (JSON base64).","operationId":"ocr_translate_base64_v1_ocr_translate_base64_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcrTranslateBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/document":{"post":{"summary":"Document","description":"PDF in -> per-page OCR (1 credit/page), optional translation\n(4 credits/page). Billed by actual pages via X-Bill-Units.\n\nformat=markdown|chunks gives the same RAG-ready output as /v1/ocr, per page\nplus a joined top-level field, at 2 credits/standard-page. Every block\ncarries `type`; detail=words adds approximate `words[]` (free).","operationId":"document_v1_document_post","parameters":[{"name":"x-credits-available","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Credits-Available"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_document_v1_document_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/book":{"post":{"summary":"Book Submit","description":"Async book/document studio + size-reducer: PDF or image pages in ->\nsearchable (OCR'd, compressed, selectable) or translated documents out\n(submit -> poll -> download). Billed per page at submit (searchable 1,\ntranslated 4 credits/page). Pass webhook_url (+ webhook_secret) to get a\nsigned POST when the job finishes instead of polling.","operationId":"book_submit_v1_book_post","parameters":[{"name":"x-credits-available","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Credits-Available"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_book_submit_v1_book_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reduce":{"post":{"summary":"Reduce Sync","description":"SYNC size-reducer: a scanned PDF (or images) in -> a much smaller,\nSEARCHABLE PDF out, returned directly. Small docs only (larger -> async\n/v1/book). Billed 1 credit/page.\n\noutput=\"same\" makes the result follow the input: a SINGLE image in gives a\nrecompressed image back (JPEG, or PNG when the source needs alpha) with no\nOCR and no text layer — because \"shrink this photo\" shouldn't hand back a\nPDF. Multiple images, or any PDF, always produce a PDF; output=\"pdf\" (the\ndefault) always does.\n\ngrayscale=True (THE DEFAULT) does NOT convert the document to greyscale.\nIt drops the chroma planes only where a page — or, on a PDF whose own JPEG\nstreams are rewritten, an individual strip — carries no real colour, judged\nby connected coloured AREA rather than an average. A stamp, a signature, a\nlogo or a coloured rule keeps its colour; blank margins and black text lose\nplanes that held nothing. Worth about -6% on a text scan for nothing\nvisible. Send grayscale=false to keep every plane regardless.\n\nvectorize=True additionally erases the original raster text (LaMa inpaint)\nand redraws it as real vector text at the same position — much smaller for\ntext-heavy pages and crisp at any zoom. Because a misread becomes a\npermanent, visible error in that mode (unlike the invisible search layer),\nany line the OCR wasn't confident about gets one more independent\nverification pass (reverify_lines). A line STILL uncertain after that is\nneither erased nor redrawn -- its original pixels stay -- unless the vision\nmodel (when the service has it) confirms the reading on a crop; each such\nvision call is billed +VECTORIZE_VISION_CREDITS (1 credit) on top of the\nvectorize surcharge, capped per request (VECTORIZE_VISION_MAX_CALLS, 8) and by the caller's balance. Response headers\nX-Vision-Calls / X-Raster-Lines report it. Only lines that were redrawn\nyet remain uncertain get a PDF comment.\n\nquality=sharp (PDF output): for artwork / infographic pages with thin\nlight text. The page background is downscaled and compressed hard, and\nevery detected text box is pasted back at full resolution (PNG, pixel-\nidentical, when that is cheap; 4:4:4 JPEG q90 otherwise). Works with\nocr=false (detection only, compress-only billing) and ocr=true; cannot be\ncombined with vectorize. On the lone-image output=same path, high /\nveryhigh / sharp encode without chroma subsampling (and a WebP source may\ncome back as WebP when that is smaller). sharp is never larger than the\nplain presets: on a page where its lossless crops cost more than the same\npage as veryhigh (plain light documents), the veryhigh PDF -- or `high`\nwhen even that is not below the source -- is returned instead and the\nresponse says so in X-Sharp-Fallback (veryhigh | high; absent when sharp\nitself was the smallest).\n\nvectorize fonts: Latin/Cyrillic = Noto Sans, Arabic = Noto Naskh (shaped),\nHindi = Noto Sans Devanagari (shaped), Japanese/Korean/Chinese = the\nmatching Noto Sans CJK face. Arabic lines also carry an /ActualText span\nso copy/search return logical text. Languages with an OCR pack: ar fa ur en\nfr es de it pt tr vi zh ja ko ru hi (the pack for hi is `devanagari`, tr/vi\nuse `latin`).","operationId":"reduce_sync_v1_reduce_post","parameters":[{"name":"x-credits-available","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Credits-Available"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_reduce_sync_v1_reduce_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/book/{job_id}":{"get":{"summary":"Book Status","operationId":"book_status_v1_book__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Book Delete","operationId":"book_delete_v1_book__job_id__delete","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/book/{job_id}/download":{"get":{"summary":"Book Download","operationId":"book_download_v1_book__job_id__download_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/translate/batch":{"post":{"summary":"Translate Batch","description":"Translate many texts as one async job — submit, then poll /v1/jobs/{id}\n(or pass webhook_url for a signed POST on completion). Built for\nwhole-book/whole-document translation from apps with short client timeouts.\n\nBilling is PREPAID at submit, like /v1/book: each item costs 1 credit per\nstarted 500 characters (minimum 1), and the batch total is 80% of that sum\n— a 20% discount for letting the server schedule the work. The quote is\nfinal: items served from the translation cache are already reflected in the\ndiscount and are not re-quoted or refunded.","operationId":"translate_batch_v1_translate_batch_post","parameters":[{"name":"x-credits-available","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Credits-Available"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchTranslateBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/jobs/{job_id}":{"get":{"summary":"Job Status","description":"Poll any async job. While it runs: status + done/total progress. When a\nbatch_translate job is done the full results array comes back inline (the\ntexts are small — no second round trip). Book jobs keep their binary\ndownload URL. Image jobs (img_ ids) answer from their own table.","operationId":"job_status_v1_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Job Delete","description":"Cancel a running job / delete a finished one and its stored results.","operationId":"job_delete_v1_jobs__job_id__delete","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/jobs/{job_id}/download/{fmt}":{"get":{"summary":"Illustrated Book Download","description":"An illustrated book's PDF / EPUB / ZIP / CBZ (built when the book finished).","operationId":"illustrated_book_download_v1_jobs__job_id__download__fmt__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"fmt","in":"path","required":true,"schema":{"type":"string","title":"Fmt"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/feedback":{"post":{"summary":"Feedback","description":"Report wrong OCR or rate a result. Corrections feed the fine-tuning\nloop (Stage C) and threshold tuning (Stage B).","operationId":"feedback_v1_feedback_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/data":{"delete":{"summary":"Delete Data","description":"PDPL: delete every stored training image for a key. The Worker\nrewrites ?key= to the caller's own key hash — users can only delete\ntheir own data.","operationId":"delete_data_v1_data_delete","parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string","title":"Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/translate":{"post":{"summary":"Translate","description":"Translate text (100+ languages, formality/context/glossary controls).\n1-5 credits by processing time; long texts floor at 1 credit per started\n500 chars (cap 20). 1-3 word lookups return dictionary-style options and\nalways bill 1.","operationId":"translate_v1_translate_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranslateBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/correct":{"post":{"summary":"Correct","description":"Fix OCR artifacts or spelling/grammar with minimal edits (1-5 credits\nby processing time — quicker is cheaper; long texts floor at 1 credit per\nstarted 1,000 chars, cap 10).","operationId":"correct_v1_correct_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CorrectBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/rewrite":{"post":{"summary":"Rewrite","description":"Grammarly-gap writing tools (1-5 credits by processing time): tone,\nclarity, paraphrase, summary — or action='custom' with the user's own\ninstruction, which is proof-read first (typo cleanup + editing-only guard\nagainst user error and prompt injection).","operationId":"rewrite_v1_rewrite_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewriteBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/export":{"post":{"summary":"Export Document","description":"Text in, document file out — docx, epub, md, html or txt.\n\nThe counterpart to every endpoint that returns TEXT. OCR a page, run a\npipeline, translate a chapter, and until now the only way out was the\nclipboard: the docx/epub builders existed but were reachable only from a\n/v1/book job, which needs a source file and bills per page.\n\nIt reuses those builders exactly (`app.ocr.docout`), so an exported docx is\nthe same docx a book job produces. Page structure survives the round trip:\ntext is split on the `----`/`---` rules build_txt and build_md themselves\nemit, and `#`/`##`/`###` become real headings rather than paragraphs that\nhappen to start with a hash.\n\nNo GPU, no LLM -- this is CPU only, which is why it is one credit.","operationId":"export_document_v1_export_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/glossary":{"put":{"summary":"Put Glossary","description":"Store this key's default glossary (applied to every translation;\nrequest-inline glossary entries override it).","operationId":"put_glossary_v1_glossary_put","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GlossaryBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"Get Glossary","operationId":"get_glossary_v1_glossary_get","parameters":[],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Glossary","operationId":"delete_glossary_v1_glossary_delete","parameters":[],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ask":{"post":{"summary":"Ask","description":"LLM chat over text — or over a DOCUMENT: pass image_base64 and its OCR\ntext is prepended as context, so \"summarize this contract\" or \"what is\nthe total on this receipt?\" is ONE call. 1-5 credits by processing time\n(+1/1,000-char floor on long inputs; +1 OCR credit when an image is\nattached).","operationId":"ask_v1_ask_post","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/deep":{"get":{"summary":"Health Deep","description":"Liveness is not health. This actually builds a searchable PDF and reads\nit back, because the two outages this service has had both answered\n\"200 ok\" from /health while the PDF pipeline was dead (see app/health.py).\n\n503 on failure so a monitor (and the Worker's /status) can alert on it.\nResult is memoized — polling it every 30-60s is cheap by design.\n\nSecret-gated like the other origin routes: it does real work (a PDF build),\nso it must not be an open endpoint on the tunnel hostname. The Worker's\noriginFetch sends X-Origin-Secret on every call, so /status is unaffected.","operationId":"health_deep_health_deep_get","parameters":[],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AgentFail":{"properties":{"agent":{"type":"string","maxLength":64,"minLength":1,"title":"Agent"},"error":{"type":"string","maxLength":300,"title":"Error","default":"render failed"}},"type":"object","required":["agent"],"title":"AgentFail"},"AgentHello":{"properties":{"agent":{"type":"string","maxLength":64,"minLength":1,"title":"Agent"},"comfy_ok":{"type":"boolean","title":"Comfy Ok","default":false},"vram_mb":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Vram Mb"},"safety":{"type":"string","title":"Safety","default":"off"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id"},"klein":{"type":"boolean","title":"Klein","default":false}},"type":"object","required":["agent"],"title":"AgentHello"},"AskBody":{"properties":{"messages":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Messages"},"max_tokens":{"type":"integer","title":"Max Tokens","default":1024},"temperature":{"type":"number","title":"Temperature","default":0.3},"image_base64":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Base64"},"lang":{"type":"string","title":"Lang","default":"auto"},"mode":{"type":"string","title":"Mode","default":"document"}},"type":"object","required":["messages"],"title":"AskBody"},"BatchTranslateBody":{"properties":{"formality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Formality"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"glossary":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Glossary"},"texts":{"items":{"type":"string"},"type":"array","title":"Texts"},"target_lang":{"type":"string","title":"Target Lang"},"source_lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Lang"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url"},"webhook_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Secret"}},"type":"object","required":["texts","target_lang"],"title":"BatchTranslateBody","description":"POST /v1/translate/batch — async whole-book translation.\n\nSize/emptiness limits are enforced in the endpoint (not here) so failures\ncome back as 400 with a machine-readable `code`, which clients can branch\non, instead of pydantic's 422 prose."},"Body_book_analyse_v1_illustrate_book_analyse_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_book_analyse_v1_illustrate_book_analyse_post"},"Body_book_submit_v1_book_post":{"properties":{"file":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"File"},"output":{"type":"string","title":"Output","default":"searchable"},"outputs":{"type":"string","title":"Outputs","default":"pdf"},"lang":{"type":"string","title":"Lang","default":"auto"},"mode":{"type":"string","title":"Mode","default":"document"},"target_lang":{"type":"string","title":"Target Lang","default":""},"quality":{"type":"string","title":"Quality","default":"high"},"grayscale":{"type":"boolean","title":"Grayscale","default":true},"flatten_bg":{"type":"boolean","title":"Flatten Bg","default":false},"ocr":{"type":"boolean","title":"Ocr","default":true},"allow_partial":{"type":"boolean","title":"Allow Partial","default":false},"enhance":{"type":"boolean","title":"Enhance","default":false},"formality":{"type":"string","title":"Formality","default":""},"context":{"type":"string","title":"Context","default":""},"glossary":{"type":"string","title":"Glossary","default":""},"webhook_url":{"type":"string","title":"Webhook Url","default":""},"webhook_secret":{"type":"string","title":"Webhook Secret","default":""}},"type":"object","required":["file"],"title":"Body_book_submit_v1_book_post"},"Body_detect_multipart_v1_detect_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_detect_multipart_v1_detect_post"},"Body_document_v1_document_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"lang":{"type":"string","title":"Lang","default":"auto"},"mode":{"type":"string","title":"Mode","default":"document"},"target_lang":{"type":"string","title":"Target Lang","default":""},"formality":{"type":"string","title":"Formality","default":""},"context":{"type":"string","title":"Context","default":""},"glossary":{"type":"string","title":"Glossary","default":""},"format":{"type":"string","title":"Format","default":"json"},"detail":{"type":"string","title":"Detail","default":"blocks"}},"type":"object","required":["file"],"title":"Body_document_v1_document_post"},"Body_extract_multipart_v1_extract_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"preset":{"type":"string","title":"Preset","default":""},"schema":{"type":"string","title":"Schema","default":""},"lang":{"type":"string","title":"Lang","default":"auto"}},"type":"object","required":["file"],"title":"Body_extract_multipart_v1_extract_post"},"Body_manga_multipart_v1_manga_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"lang":{"type":"string","title":"Lang","default":"auto"},"allow_training":{"type":"boolean","title":"Allow Training","default":false},"detail":{"type":"string","title":"Detail","default":"blocks"},"quality":{"type":"string","title":"Quality","default":"standard"}},"type":"object","required":["file"],"title":"Body_manga_multipart_v1_manga_post"},"Body_ocr_multipart_v1_ocr_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"lang":{"type":"string","title":"Lang","default":"auto"},"mode":{"type":"string","title":"Mode","default":"document"},"allow_training":{"type":"boolean","title":"Allow Training","default":false},"format":{"type":"string","title":"Format","default":"json"},"detail":{"type":"string","title":"Detail","default":"blocks"},"proofread":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Proofread"},"quality":{"type":"string","title":"Quality","default":"standard"}},"type":"object","required":["file"],"title":"Body_ocr_multipart_v1_ocr_post"},"Body_ocr_translate_multipart_v1_ocr_translate_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"lang":{"type":"string","title":"Lang","default":"auto"},"mode":{"type":"string","title":"Mode","default":"document"},"target_lang":{"type":"string","title":"Target Lang","default":"en"},"allow_training":{"type":"boolean","title":"Allow Training","default":false},"formality":{"type":"string","title":"Formality","default":""},"context":{"type":"string","title":"Context","default":""},"glossary":{"type":"string","title":"Glossary","default":""},"format":{"type":"string","title":"Format","default":"json"},"detail":{"type":"string","title":"Detail","default":"blocks"},"quality":{"type":"string","title":"Quality","default":"standard"}},"type":"object","required":["file"],"title":"Body_ocr_translate_multipart_v1_ocr_translate_post"},"Body_reduce_sync_v1_reduce_post":{"properties":{"file":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"File"},"quality":{"type":"string","title":"Quality","default":"email"},"grayscale":{"type":"boolean","title":"Grayscale","default":true},"flatten_bg":{"type":"boolean","title":"Flatten Bg","default":false},"lang":{"type":"string","title":"Lang","default":"auto"},"vectorize":{"type":"boolean","title":"Vectorize","default":false},"ocr":{"type":"boolean","title":"Ocr","default":true},"allow_partial":{"type":"boolean","title":"Allow Partial","default":false},"output":{"type":"string","title":"Output","default":"pdf"},"mode":{"type":"string","title":"Mode","default":"document"}},"type":"object","required":["file"],"title":"Body_reduce_sync_v1_reduce_post"},"BookBody":{"properties":{"analysis_id":{"type":"string","title":"Analysis Id"},"mode":{"type":"string","title":"Mode","default":"minimal"},"n":{"type":"integer","title":"N","default":1},"per_context":{"type":"integer","title":"Per Context","default":1},"style_id":{"type":"string","title":"Style Id","default":"auto"},"era":{"type":"string","title":"Era","default":"auto"},"detail":{"type":"string","title":"Detail","default":"standard"},"spoiler_safe":{"type":"boolean","title":"Spoiler Safe","default":false},"lang":{"type":"string","title":"Lang","default":"auto"},"style_text":{"anyOf":[{"type":"string","maxLength":400},{"type":"null"}],"title":"Style Text"},"era_text":{"anyOf":[{"type":"string","maxLength":400},{"type":"null"}],"title":"Era Text"},"preview":{"type":"boolean","title":"Preview","default":false}},"type":"object","required":["analysis_id"],"title":"BookBody"},"ContinueBody":{"properties":{"mode":{"type":"string","title":"Mode","default":"minimal"},"n":{"type":"integer","title":"N","default":1},"per_context":{"type":"integer","title":"Per Context","default":1},"spoiler_safe":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Spoiler Safe"}},"type":"object","title":"ContinueBody"},"CorrectBody":{"properties":{"text":{"type":"string","title":"Text"},"lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lang"},"mode":{"type":"string","title":"Mode","default":"ocr"}},"type":"object","required":["text"],"title":"CorrectBody","description":"DeepL-Write-gap: fix text with minimal edits. mode='ocr' targets OCR\nartifacts (broken chars, split words, wrong diacritics); 'grammar' is a\nplain spelling/grammar pass."},"ExportBody":{"properties":{"text":{"type":"string","title":"Text"},"format":{"type":"string","title":"Format","default":"docx"},"title":{"type":"string","title":"Title","default":"Document"},"lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lang"}},"type":"object","required":["text"],"title":"ExportBody","description":"Turn text the caller already has into a document file.\n\nThe counterpart to every endpoint that RETURNS text: OCR a page, run a\npipeline, translate a chapter -- and then have nothing to hand someone but\na clipboard. Uses the same builders /v1/book ships its books with, so an\nexported docx is the same docx a book job would have produced."},"ExtractJsonBody":{"properties":{"image_base64":{"type":"string","title":"Image Base64"},"preset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preset"},"schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Schema"},"lang":{"type":"string","title":"Lang","default":"auto"}},"type":"object","required":["image_base64"],"title":"ExtractJsonBody","description":"/v1/extract (base64 variant): schema-driven structured extraction.\nGive either a `preset` (invoice | receipt | id | zatca) or a custom\n`schema` object whose leaves describe the expected values."},"FeedbackBody":{"properties":{"request_id":{"type":"string","title":"Request Id"},"rating":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rating"},"corrected_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Corrected Text"}},"type":"object","required":["request_id"],"title":"FeedbackBody"},"GlossaryBody":{"properties":{"entries":{"additionalProperties":{"type":"string"},"type":"object","title":"Entries"}},"type":"object","required":["entries"],"title":"GlossaryBody","description":"PUT /v1/glossary — one stored default glossary per key."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IllustrateBody":{"properties":{"text":{"type":"string","maxLength":20000,"title":"Text","default":""},"lang":{"type":"string","title":"Lang","default":"auto"},"style_id":{"type":"string","title":"Style Id"},"era":{"type":"string","title":"Era","default":"none"},"count":{"type":"integer","title":"Count","default":1},"detail":{"type":"string","title":"Detail","default":"standard"},"purpose":{"type":"string","title":"Purpose","default":"page"},"quality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quality"},"scene_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scene Ref"},"book":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Book"},"page":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page"},"style_text":{"anyOf":[{"type":"string","maxLength":400},{"type":"null"}],"title":"Style Text"},"era_text":{"anyOf":[{"type":"string","maxLength":400},{"type":"null"}],"title":"Era Text"}},"type":"object","required":["style_id"],"title":"IllustrateBody"},"OcrJsonBody":{"properties":{"image_base64":{"type":"string","title":"Image Base64"},"lang":{"type":"string","title":"Lang","default":"auto"},"mode":{"type":"string","title":"Mode","default":"document"},"allow_training":{"type":"boolean","title":"Allow Training","default":false},"format":{"type":"string","title":"Format","default":"json"},"detail":{"type":"string","title":"Detail","default":"blocks"},"proofread":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Proofread"},"quality":{"type":"string","title":"Quality","default":"standard"}},"type":"object","required":["image_base64"],"title":"OcrJsonBody"},"OcrTranslateBody":{"properties":{"formality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Formality"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"glossary":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Glossary"},"image_base64":{"type":"string","title":"Image Base64"},"lang":{"type":"string","title":"Lang","default":"auto"},"mode":{"type":"string","title":"Mode","default":"document"},"allow_training":{"type":"boolean","title":"Allow Training","default":false},"format":{"type":"string","title":"Format","default":"json"},"detail":{"type":"string","title":"Detail","default":"blocks"},"proofread":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Proofread"},"quality":{"type":"string","title":"Quality","default":"standard"},"target_lang":{"type":"string","title":"Target Lang","default":"en"}},"type":"object","required":["image_base64"],"title":"OcrTranslateBody"},"RewriteBody":{"properties":{"text":{"type":"string","title":"Text"},"action":{"type":"string","title":"Action","default":"proofread"},"lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lang"},"instruction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instruction"}},"type":"object","required":["text"],"title":"RewriteBody","description":"Grammarly-gap writing tools: tone/clarity rewrites on any text.\naction='custom' applies the user's own `instruction`, which the server\nproof-reads first (typo cleanup + editing-only guard)."},"TranslateBody":{"properties":{"formality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Formality"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"glossary":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Glossary"},"text":{"type":"string","title":"Text"},"target_lang":{"type":"string","title":"Target Lang"},"source_lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Lang"}},"type":"object","required":["text","target_lang"],"title":"TranslateBody"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from POST /signup (nsk_live_...)"}}},"servers":[{"url":"https://auto-reader.com"}],"security":[{"bearerAuth":[]}]}