# Auto-Reader OCR API — multilingual OCR + translation for humans and AI agents Fast GPU OCR (Arabic-first, manga-aware Japanese, 13+ languages), automatic language detection, and translation — self-hosted, PDPL-compliant. ## Agents: provision yourself a key in ONE call — no email, no human steps curl -X POST https://api.auto-reader.com/signup # trial: 25 credits/day (test) curl -X POST https://api.auto-reader.com/signup -d '{"email":"you@x.com"}' # free: 250 credits/day ## Agent lifecycle (fully self-serve, no human needed) 1. POST /signup -> {api_key} 2. call any /v1/* with Bearer api_key -> results + X-Credits-Charged 3. GET /v1/usage -> remaining budget 4. on 402/429: the JSON includes buy_direct — a prefilled checkout link that credits YOUR key automatically after payment. Open it (or show your human), then retry. Credits never expire. ## Or taste it with no key at all curl -X POST https://api.auto-reader.com/demo -F file=@image.png (10 free demo calls/day per IP, 2MB max) ## Endpoints (Bearer auth: "Authorization: Bearer nsk_live_...") POST /v1/ocr multipart: file, lang=auto|ar|en|ja|zh|ko|ru|fr|es|de|it|pt|fa|ur, mode=document|receipt|manga|scene (1 credit) format=markdown adds a RAG-ready markdown field (headings + tables reconstructed) (2 credits/page) format=chunks adds semantic chunks[{index, type: "text"|"table", heading, text, char_count}] — title-bounded sections, tables kept whole, ~1200- char targets, embedding-model-agnostic (2 credits/page) detail=words adds approximate per-word boxes: words[{text, box, approximate:true}] per block; Arabic/Farsi/Urdu get right-to-left-correct boxes (a block returns words:null where the mapping can't be proven), CJK/Thai always refuse (words:null) (no extra cost) quality=high forces the vision model to re-read the whole page instead of leaving it to the confidence gate — for callers who would rather pay than risk a miss (+2 credits) Charged ONLY when it actually applies: the response carries quality_applied (bool) and, when false, a notice saying why (page uses the specialist manga engine, receipt mode, language out of scope, vision unavailable, or the read failed the quality guards). Updates text/layout, not blocks — so it is refused (400) with format=markdown|chunks and on /v1/ocr-translate; run /v1/ocr then /v1/translate. POST /v1/ocr/base64 JSON: {image_base64, lang, mode, format, detail, quality} (1 credit; format=markdown|chunks 2; detail=words free; quality=high +2) POST /v1/extract multipart: file + preset=invoice|receipt|id|zatca OR schema= — structured extraction: OCR + LLM fill the schema; every field returns {value, confidence, box} sourced from the OCR blocks (5 credits/page; zatca 7 — includes ZATCA QR TLV decode + printed-vs-QR cross-validation for Saudi e-invoices) POST /v1/extract/base64 JSON: {image_base64, preset?, schema?, lang?} POST /v1/detect multipart file (or /v1/detect/base64 with {image_base64}) — language/script detection only (FREE, rate-limited) POST /v1/document multipart PDF (<=10MB) — per-page OCR (1 credit/page, <=20 pages) + optional target_lang translation (7 credits/page, <=10 pages) POST /v1/reduce multipart PDF or images -> a smaller PDF (sync, small files; larger ones via /v1/book). quality=veryhigh (300 dpi, for small print) | high (150 dpi, default for the API) | email (120 dpi) | text (MRC: a 1-bit ink mask at 300 dpi, colour and paper crushed -- about a third of high's bytes; body text still OCRs, small print less so; hard on photos, kept but not pretty). ocr=false to only compress (1 credit / 25 pages); grayscale=true (the default) drops colour only where a page has none. POST /v1/book ASYNC book/document studio (<=100MB, PDF or images): NO page limit of its own — what you can process is bounded by credits. A file past your balance (or past what fits in one job) is not refused: send allow_partial=true and the affordable prefix is processed and billed, with source_pages / partial / pages_not_processed in the reply (and on every poll). Without it you get 402 carrying pages_affordable, credits_required and credits_for_partial so you can ask the user first. output=searchable -> the same pages with an invisible selectable/searchable text layer (2 credits/page, <=400 pages); output=translated + target_lang -> every page inpainted with the translation typeset in place (8 credits/page, <=150 pages). outputs=pdf,docx,epub, md,html,txt (multiple -> zip). Billed at submit; returns {job_id, eta_seconds}. Poll GET /v1/book/{id} (free), download GET /v1/book/{id}/download (free). Files auto-delete after 48h; DELETE /v1/book/{id} for immediate removal (PDPL). POST /v1/ocr-translate multipart + target_lang — OCR then translate every line in one call (7 credits/page) format=overlay adds overlay_html: the page with the source text inpainted away and the translation laid over it as selectable text (+1 credit) detail=words adds approximate per-word boxes, same rules as /v1/ocr (no extra cost) POST /v1/translate JSON: {text, target_lang, source_lang?, formality?, context?, glossary?} (1-5 by time; long texts floor 1 credit/750 chars, lookups = 1) Output is language-validated server-side; a rare still-imperfect result carries "quality":"degraded" (also per-item in batch jobs) — retry it with a NEW Idempotency-Key for a fresh generation. POST /v1/correct JSON: {text, mode: ocr|grammar} — fix OCR artifacts or spelling/grammar, minimal edits (1-5 by time) POST /v1/rewrite JSON: {text, action} — writing tools: proofread | rephrase | formal | casual | confident | friendly | simplify | shorten | expand | summarize | breakdown (breakdown = prose -> numbered steps/bullets) (1-5 by time) POST /v1/ask JSON: {messages:[...]} LLM chat (1-5 by time) POST /v1/export JSON: {text, format, title?, lang?} -> a FILE format: docx | epub | md | html | txt. Splits pages on the ---- / --- rules our own txt/md exports emit, and reads # / ## / ### as headings. (1 credit) PUT/GET/DELETE /v1/glossary your stored default glossary ({entries:{"term":"translation"}}) — free POST /v1/feedback JSON: {request_id, rating?, corrected_text?} — free POST /v1/keys/email JSON: {email} — upgrade/switch email on your key POST /v1/keys/claim/start JSON: {email} — bind a recovery identity to this key (emails a 6-digit code; separate from the tier email). Then /v1/keys/claim/verify {email, code}. POST /v1/keys/recover JSON: {email} — NO auth: lost key/new device. Emails a code; /v1/keys/recover/verify {email, code} mints a fresh key with the full merged balance and REVOKES the old keys. Purchases auto-bind the checkout email. GET /v1/usage your quota/credits/limits — free (alias /v1/keys/me) DELETE /v1/data delete your stored training images (PDPL) — free GET /v1/prices public price list + free tiers (NO key needed) GET /status public service status GET /openapi.json full OpenAPI spec Translation options (translate + ocr-translate): formality: "formal"|"informal", context: background text that improves accuracy (not translated), glossary: {"term": "required translation"} enforced terminology. A stored glossary (PUT /v1/glossary) applies to every call; inline entries override it. ## Responses Every LLM-backed response (translate, correct, rewrite, ask, ocr-translate, extract, book, ocr, document) carries X-LLM-Profile: full (Gemma-4-12B) | lite (Qwen3.5-4B, during a scheduled low-power window; interactive calls still answer, paid translated books and translate batches are refused with 503 + Retry-After). Every OCR response: request_id, lang_detected, engine (paddle|manga-ocr), recognizer (manga pages only: paddleocr-vl-manga|manga-ocr|mixed), escalated, cached, latency_ms, text, layout, blocks[{text, confidence, box, order, type}]. type is one of "title"|"table_row"|"paragraph" (no extra cost). detail=words adds words[{text, box, approximate:true}] on each block (null where the language refuses to guess, e.g. CJK/Thai). "layout" is copy-ready text reconstructed in reading order (RTL-aware, blank lines at paragraph gaps) — usually what you want to feed an LLM or a human. Repeat images are served from cache instantly at base cost. Vision escalation is LIVE for hard Arabic-script pages: when PaddleOCR confidence is low on an ar/fa/ur page (mode != receipt), the image is re-read by a resident vision LLM — engine:"gemma", escalated:true, +2 credits. A failed escalation keeps the classic OCR result and costs nothing extra. blocks[].order is READING order (RTL-aware) — safe to sort on when assembling text client-side. ## Pricing Free tier: 250 credits/day (verified) / 25 (trial) — a real daily taste; the product is prepaid credits (billed in SAR) and subscriptions. Credits never expire: 9.99 SAR (~$2.66) = 2,000 · 20 SAR (~$5.33) = 5,000 · 99.99 SAR (~$26.66) = 25,000 (+1,500 bonus on your first purchase, any pack). Buying credits never shrinks the free tier: paid keys spend their free daily allowance FIRST (resets midnight UTC, no rollover) and credits only after. Subscription monthly allowances overflow into prepaid credits when exceeded. Subscriptions: 15 SAR/mo (~$4) = 4,000 credits · 50 SAR/mo (~$13.33) = 13,500 credits. Costs in credits: OCR page = 1 · translate/correct/ask/rewrite = 1-5 by processing time (the quicker the request, the cheaper — 1 credit per started 3s of server time; word lookups and one-line fixes land at 1; long-text translate has a size floor of 1 credit per started 750 chars, so a typical paragraph lands at 2) · ocr-translate page = 7 (~5x cheaper than DeepL, with OCR included; pages already in the target language skip translation and bill as plain OCR = 1). Cache hits (identical input) bill 1 credit on every endpoint. Batch translate = per-item floor x0.8. Fair per-page billing: a "page" is normalized by text content (~3,000 chars = 1 page), so a normal page is 1 credit and a page crammed with tiny text bills proportionally more — you can't game per-page pricing by shrinking the font. ## For agents - JSON everywhere, base64 image variants, stable request_id for feedback. - Send {"allow_training": true} only if you consent to the image being stored to improve the models (default: images are never stored). - MCP server (streamable HTTP, stateless): https://api.auto-reader.com/mcp — add with `claude mcp add --transport http auto-reader-ocr https://api.auto-reader.com/mcp`. Tools: ocr_image, translate_text, ocr_and_translate, get_usage, create_api_key. No key needed to start: the first call auto-provisions a trial key and returns it (pass it back as the api_key argument, or as a Bearer token). - Async jobs (/v1/book): pass webhook_url (+ webhook_secret) at submit for a signed completion POST (X-Signature = hex HMAC-SHA256 of the body) instead of polling. - Doc-bound ask: POST /v1/ask with image_base64 answers questions about a document in one call (+1 OCR credit). - Retries: send an Idempotency-Key header on POST calls — a retry with the same key replays the stored result without billing again (24h window). - Built by the makers of the Auto-Reader app (auto-reader.com).