FAQs
Common questions about the Document Translation API. If yours isn’t here, reach out on Discord.
Getting started
Is there a single call that takes a file and returns a translated file?
No. Document translation is asynchronous, split across five calls: create the job, PUT the file to the signed upload_url, POST /start, poll live-status, then trigger POST /export and poll GET /export/status once per target language. See the Overview for the flow.
Which file formats are supported?
PDF (.pdf), Word (.doc, .docx, .odt), spreadsheets (.xls, .xlsx, .ods), presentations (.ppt, .pptx, .odp), and web pages (.html, .xhtml, .mhtml).
What keeps a job in Accepted?
Accepted is returned by both job creation and a successful start call. If the job never moves past it, either the document was never uploaded to upload_url, or POST /translate/document/jobs/{job_id}/start was never called.
Languages
Which languages are supported?
23: English plus 22 Indic languages, including Assamese, Bengali, Bodo, Dogri, Gujarati, Hindi, Kannada, Kashmiri, Konkani, Maithili, Malayalam, Manipuri, Marathi, Nepali, Odia, Punjabi, Sanskrit, Santali, Sindhi, Tamil, Telugu, and Urdu. See the Overview for the full code table.
Can I translate into more than one language in a single job?
Yes, but capped: target_language_codes is an array of 1 to 12 entries per job (out of 23 total supported languages), from one upload. Split into multiple jobs if you need more than 12 target languages from the same document.
Translation quality
How do I control terminology and tone?
Use style_guidelines for instructions that apply to the whole job, and language_specific_guidelines for per-language overrides. See Set Style Guidelines.
What's the difference between lite and plus model_type?
lite is faster and suited to short-form content; plus is higher quality and suited to long-form content.
Uploads and results
How long is the upload URL valid for?
Check expires_in_hours on the create-job response (24 hours). Upload promptly after creating the job.
Does the translated file keep the original layout?
Yes: export returns the translated document in the same file format as the source; format on the export response always matches the original upload.
Do I export the whole job in one call?
No: export is per language. Call POST /translate/document/jobs/{job_id}/export?lang={code}&format={fmt} once for each of your target_language_codes, once that language’s own state in live-status reads Completed. Then poll GET /translate/document/jobs/{job_id}/export/status until export_state is Completed.
What causes a 409 on export?
The requested language’s translation isn’t Completed yet, or an export is already in progress for that language and format. Check the per-language state inside live-status’s translations array; a job_state of Running or PartiallyCompleted can still have individual languages ready to export.
How often should I poll live-status?
Every 10-15 seconds is the documented guidance. Poll from a background worker rather than an HTTP request handler, and cap total wait time.
What is PartiallyCompleted?
Some target languages finished translating and others failed. Treat it as a terminal state alongside Completed; check each language’s own state in translations to see which succeeded, and export those.
Why don't I see page_metrics in the response?
live-status returns one of two shapes depending on which pipeline processed your file. PDF uploads get the page-granular shape (page_metrics, per-language pages_completed/pages_failed). Word, spreadsheet, and presentation uploads get the document-granular shape instead (translation_metrics, per-language segments_completed/segments_total), with no page_metrics field in that shape at all, rather than a null value. See the Overview for both response examples.