Engineering notes

Document Translation API Guide: Bulk Word and PDF Translation with Python

Translate Word, PDF, Excel and other files in bulk with the OmniDoc document translation API: upload, create jobs, receive webhooks and download results. Python example, job parameters, idempotent retries and pricing rules.

阅读文本 / Reading text
Document Translation API Guide: Translate Word and PDF Files in Bulk with Python and Webhooks If your system handles contracts, manuals, papers or reports every day, uploading, waiting and downloading by hand quickly becomes the bottleneck. The OmniDoc document translation API hands the whole loop to your code: upload a file, create a job, get notified when it finishes, download the result . Translations keep the original layout, tables, images and formulas, and can be bilingual (source and translation side by side) or translation only. The basics Table 1 API conventions Item Details Base URL https://omnidoc.top/api/v1 Authentication API key in the X-API-Key header, or sent as a Bearer token; create keys in the API console Requests JSON with Content-Type: application/json Tracing Keep the X-Request-Id of every response and quote it when contacting support Rate limits On 429, retry after the Retry-After interval Supported files Word (.docx), Excel (.xlsx), PowerPoint (.pptx), PDF, HTML, EPUB, Markdown and plain text, SRT/ASS subtitles, CSV, PNG/JPG images and UniDoc documents (.udoc). Every format except PPTX supports bilingual output: Word pairs paragraphs, Excel pairs columns, PDF pairs pages and subtitles pair lines. A bilingual request for PPTX returns the translation only. Four steps to a translated file Request an upload : POST /upload/presign with the file name and size to get a direct upload URL, upload headers and a finalize_token. Upload and confirm : PUT the file with the returned headers (do not send your API key there), then POST /upload/finalize to get document.id. Create the job : POST /jobs with document_id and target_lang; an Idempotency-Key header is recommended. Collect the result : poll GET /jobs/{id}, subscribe to SSE progress or use a webhook; when the job completes, list the outputs with GET /artifacts?job_id=... and download them. Job parameters Table 2 POST /jobs request fields Field Default Meaning document_id — Confirmed document ID (required) target_lang — Target language code (required) source_lang auto-detect Source language code engine xr-397b Translation profile: xr-397b, deepseek, qwen, chatgpt, gemini or claude output_mode bilingual bilingual or single (translation only) glossary_id — Glossary that fixes brand names and terminology include_images false Also translate text inside images context_translation false Context-aware translation for consistent terms style_preset — Writing style preset Python: create a job and wait for it This snippet only needs requests. The full upload-to-download example is on the Python page of the developer docs. import time, uuid, requests BASE = "https://omnidoc.top/api/v1" HEADERS = {"X-API-Key": "sk_your_key"} def create_job(document_id, target_lang="en", engine="xr-397b"): r = requests.post(f"{BASE}/jobs", headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())}, json={"document_id": document_id, "target_lang": target_lang, "engine": engine}, timeout=30) r.raise_for_status() return r.json() def wait_for_job(job_id): while True: job = requests.get(f"{BASE}/jobs/{job_id}", headers=HEADERS, timeout=20).json() if job["status"] in ("completed", "failed"): return job time.sleep(5) Batches and retries: concurrency, queueing and idempotency Automatic queueing : each account processes up to 5 files at a time; further jobs are still created and wait in the queue, and stage_message tells you how many are ahead. Idempotency keys : the same Idempotency-Key with the same body returns the original job, so nothing is created or charged twice. After a network timeout, query the job first instead of retrying with a new key. Error codes : 403 means the key may not use the chosen profile, 404 that the document or glossary does not exist, 415 an unsupported format, 422 an empty file or invalid parameters. Webhooks: let the job call you Each user can register up to 3 webhooks (POST /webhooks to create, PATCH to update or disable). When a file translation job ends, successfully or not, OmniDoc sends a job.completed event; data.status is completed or failed and data.char_count is the number of translated characters. If you set a secret, every callback carries X-Webhook-Signature: verify it with HMAC-SHA256 over the raw request body. The URL must be publicly reachable, and HTTPS is recommended. What it costs Balance check before start : a PDF needs a balance above page count × 2 credits; other formats are estimated from the source text, at least 2 credits. If the balance is short, the job ends with quota_exceeded and nothing is charged. Charged on delivery : the actual usage is charged when the job completes; failed or cancelled jobs cost nothing. Queries are free : balance, job status, usage, receipts and download links never use credits. Credit packs start at 3,000 credits for ¥9.9, and purchased credits do not expire; GET /billing/credits/plans lists the packs on sale. Next steps Developer quickstart with complete cURL, Python and Node.js examples: https://docs.omnidoc.top/guide/quickstart/ . Prefer not to write code? An AI assistant connected to OmniDoc can translate local files directly; see https://omnidoc.top/blog/en/ai-word-excel-ppt-omnidoc/ . - 1 -
Updated 2026-10-18