# Equalang > Translation through one HTTP API: text translated at once, and jobs that translate a whole file -- documents, slides, spreadsheets, e-books, subtitles, pictures, audio and video -- or transcribe a recording. ## Instructions for agents - Use Equalang when a task needs machine translation of strings, of whole files with their layout kept, subtitles for a recording, or a transcript of one. - Read the contract instead of inferring request shapes from prose: the OpenAPI description is https://equalang.com/v1/openapi.json, and the whole documentation is one file, https://equalang.com/llms-full.txt. - The API is served under https://equalang.com/v1. Authenticate every request with `Authorization: Bearer el_...`. Never invent an API key: ask the user for one, or send them to https://equalang.com/developers to create it. - A job takes these files: pdf, docx, pptx, xlsx, epub, html, txt, srt, vtt, jpg, jpeg, png, webp, bmp; and these recordings: mp3, m4a, wav, flac, ogg, aac, opus, mp4, mov, webm, mkv. - Text translation answers at once: `texts` for separate strings, `text` for one long text (do not cut it up yourself). File jobs are asynchronous: create the job, then poll GET /jobs/{job_id} (wait for Retry-After between polls) until `finished` is true, or pass `callback_url` when creating it. - Errors carry `code` and `retryable`. Retry only when `retryable` is true, after Retry-After when it is sent. Send an Idempotency-Key when creating a job, so a retry after a timeout cannot create and charge a second one. - Work is paid in credits from the key owner's balance. Creating a job reserves credits and the response says how many: tell the user before starting large jobs, and never loop over many files without their say-so. To know the cost first, upload with POST /files: its `quote` is the most a job on that file can cost, and the returned file_id starts the job. # Authentication Source: https://equalang.com/developers#authentication The API is served under `https://equalang.com/v1`. Do not use the website session proxy `/api/backend` with an API key. Send `Authorization: Bearer el_...`. The key needs `translations:text` for text, or `translations:document` to create and query jobs. Add `files:read` for authenticated file downloads and `files:write` for separate uploads. Temporary result links do not need an API key. Never forward the key to a result URL. # Translating text Source: https://equalang.com/developers#post-text-translate POST /text/translate returns results synchronously; no job or polling is needed. Send texts as an array even for one string. For one long text -- an article, a chapter -- send `text` instead of `texts`: up to 100000 characters, divided at sentences on our side and answered as one translation. source_language defaults to auto; target_language is required. Text accepts every code in the text catalog below; documents accept the document catalog. ```bash curl --fail-with-body https://equalang.com/v1/text/translate \ -H "Authorization: Bearer $EQ_API_KEY" \ -H "Content-Type: application/json" \ -d '{"texts":["Hello"],"target_language":"zh-CN"}' ``` data.translations has the same length and order as texts. Each item returns translated_text, detected_source_language and error. error is null on success; failed items have null text/language and an error with code, message and retryable. HTTP 200 means the batch was processed, not that every item succeeded. usage.credits_charged bills successful items only. At most 50 texts per request, 5000 characters per text and 20000 characters in total. Whitespace-only texts are rejected. Markup is treated as plain text; HTML/rich-text modes are not public inputs. Idempotency-Key is optional; completed text results are replayed for 86400 seconds. Without it every call is a new translation. Changed input with the same key returns 409; an in-progress request also returns 409 with Retry-After. To retry failed items from a completed batch, send only those texts in a new request with a new key. Reusing the old key replays the original errors. # Translating a file: quickstart Source: https://equalang.com/developers#quickstart Upload original bytes as multipart `file`; do not base64-encode the document or set the multipart boundary yourself. The server reads the document and reserves credits before acknowledging creation. ```bash curl --fail-with-body "https://equalang.com/v1/jobs/translate" \ -H "Authorization: Bearer $EQ_API_KEY" \ -F "file=@report.pdf" \ -F "target_language=zh-CN" ``` Creation returns `job_id`, `status`, `credits_reserved` and `created_at` inside `data`. Poll `GET /jobs/{job_id}` every 5 seconds, backing off to 30. Stop when `data.finished` is true. Check `data.status`: download only on `SUCCEEDED`; inspect `data.error` on `FAILED`. `CANCELLED` has no successful result. Temporary links last 900 seconds; query the job again to refresh them while the file is retained. Queued jobs cancel immediately; running jobs enter CANCELLING until the provider stops. Continue polling until finished. Cancelling a successful or already cancelled job leaves it unchanged. Retry only FAILED or CANCELLED jobs using POST /jobs/{job_id}/retry. The job ID is reused and credits are reserved for the new attempt. After a timeout, query the job before retrying this command. Expired source files cannot be translated again. # Translating a file from a URL Source: https://equalang.com/developers#quickstart Instead of uploading bytes, send JSON with `file_url` and `target_language`. The URL must be publicly reachable using HTTP or HTTPS without cookies or extra headers. Signed URLs are supported. The server follows up to three redirects, downloads for at most 30 seconds and enforces the same file size and type limits as uploads. Private, loopback and other non-public destinations are rejected at every hop. ```bash curl --fail-with-body "https://equalang.com/v1/jobs/translate" \ -H "Authorization: Bearer $EQ_API_KEY" \ -H "Content-Type: application/json" \ -d '{"file_url":"https://example.com/report.pdf","target_language":"zh-CN"}' ``` # Languages and options Source: https://equalang.com/developers#document-languages Use one of the following language codes, not the display name. Codes are case-sensitive. Only source_language accepts `auto`. Unlisted codes return 422. ## Document translation (12 languages) | Code | Language | | --- | --- | | `auto` | Detect automatically (source only) | | `zh-CN` | Simplified Chinese | | `en` | English | | `zh-TW` | Traditional Chinese | | `ja` | Japanese | | `ko` | Korean | | `es` | Spanish | | `fr` | French | | `pt` | Portuguese | | `ru` | Russian | | `de` | German | | `pl` | Polish | | `it` | Italian | ## Text translation (105 languages) | Code | Language | | --- | --- | | `auto` | Detect automatically (source only) | | `af` | Afrikaans | | `sq` | Albanian | | `am` | Amharic | | `ar` | Arabic | | `hy` | Armenian | | `az` | Azerbaijani | | `eu` | Basque | | `be` | Belarusian | | `bn` | Bengali | | `bs` | Bosnian | | `bg` | Bulgarian | | `my` | Burmese | | `yue` | Cantonese | | `ca` | Catalan | | `zh-CN` | Simplified Chinese | | `zh-Hant` | Traditional Chinese | | `zh-HK` | Traditional Chinese (Hong Kong) | | `zh-TW` | Traditional Chinese (Taiwan) | | `hr` | Croatian | | `cs` | Czech | | `da` | Danish | | `nl` | Dutch | | `en` | English | | `en-GB` | English (British) | | `et` | Estonian | | `fil` | Filipino | | `fi` | Finnish | | `fr` | French | | `fr-CA` | French (Canadian) | | `gl` | Galician | | `ka` | Georgian | | `de` | German | | `el` | Greek | | `gu` | Gujarati | | `ht` | Haitian Creole | | `ha` | Hausa | | `he` | Hebrew | | `hi` | Hindi | | `hu` | Hungarian | | `is` | Icelandic | | `ig` | Igbo | | `id` | Indonesian | | `ga` | Irish | | `it` | Italian | | `ja` | Japanese | | `ja-honor` | Japanese (Honorific) | | `ja-humble` | Japanese (Humble) | | `ja-plain` | Japanese (Plain) | | `ja-formal` | Japanese (Written) | | `jv` | Javanese | | `kn` | Kannada | | `kk` | Kazakh | | `km` | Khmer | | `ko` | Korean | | `ku` | Kurdish (Kurmanji) | | `ckb` | Kurdish (Sorani) | | `lo` | Lao | | `la` | Latin | | `lv` | Latvian | | `lt` | Lithuanian | | `mk` | Macedonian | | `ms` | Malay | | `ml` | Malayalam | | `mt` | Maltese | | `mr` | Marathi | | `mn-Cyrl` | Mongolian (Cyrillic) | | `cnr` | Montenegrin | | `ne` | Nepali | | `no` | Norwegian | | `or` | Odia | | `fa` | Persian | | `pl` | Polish | | `pt` | Portuguese | | `pt-BR` | Portuguese (Brazilian) | | `pa` | Punjabi | | `ro` | Romanian | | `ru` | Russian | | `sr-Cyrl` | Serbian (Cyrillic) | | `sr-Latn` | Serbian (Latin) | | `si` | Sinhala | | `sk` | Slovak | | `sl` | Slovenian | | `so` | Somali | | `es` | Spanish | | `es-419` | Spanish (Latin American) | | `sw` | Swahili | | `sv` | Swedish | | `tg-Cyrl` | Tajik (Cyrillic) | | `ta` | Tamil | | `te` | Telugu | | `th` | Thai | | `bo` | Tibetan | | `ti` | Tigrinya | | `tr` | Turkish | | `tk-Cyrl` | Turkmen (Cyrillic) | | `tk-Latn` | Turkmen (Latin) | | `uk` | Ukrainian | | `ur` | Urdu | | `ug` | Uyghur | | `uz` | Uzbek | | `vi` | Vietnamese | | `cy` | Welsh | | `yi` | Yiddish | | `yo` | Yoruba | | `zu` | Zulu | Nested `options` are a JSON object in JSON requests and a JSON-encoded form field in multipart, for example `-F 'options={"optimize_math_formula":true}'`. Choose exactly one of `file`, `file_url` and `file_id`; multipart supports all three, JSON supports URL or ID. Base64 uploads, model selection, glossaries and webhooks are not supported by this contract. # Responses, errors, retries and billing Source: https://equalang.com/developers#overview JSON responses use `{code, message, data, request_id}`. Success uses `code: "OK"`. An error adds `retryable`: true means the same request can succeed later (wait for Retry-After when it is sent), false means change the request first. Decide by `code` and `retryable`; `message` is an English sentence for a log. Report `request_id` or the `X-Request-ID` header when requesting support. A failed job reports `error: {code, message, retryable}` with one of DOCUMENT_TRANSLATION_FAILED, RESULT_DELIVERY_FAILED, JOB_NEEDS_REVIEW; `retryable` says whether POST /jobs/{job_id}/retry can help. Rate-limited endpoints answer with `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the window resets) so a client can pace itself; on 429 wait for Retry-After. Poll GET /jobs/{job_id} until `finished` is true. While the job runs the response carries `Retry-After: 2`; wait that long between polls. `outputs` lists every file the job produced; `download_url` and the `dual_*` fields name the same files one by one. List jobs with `cursor`: pass the previous page's `next_cursor` until it is null. `offset` remains for page-number interfaces but repeats or skips jobs created while you page. To be told instead of polling, send `callback_url` (public HTTPS) when creating the job. When the job finishes it receives one POST `{"type": "job.finished", "job_id": "...", "status": "SUCCEEDED"}` with an `X-Equalang-Event-Id` header; answer 2xx, or it is retried a few times. The POST carries no result and no signature by design: treat it as a hint and GET the job with your API key. Compatibility: within `/v1`, fields, enum values and endpoints may be added; none is removed or changes meaning. Ignore fields you do not know and treat an unknown enum value as its general case. Idempotency-Key is optional. Without it, every call creates a new job. To protect against duplicate creation after a network timeout, supply a unique value such as a UUID and reuse it for that request. For URL submissions, replay reuses the originally downloaded file without fetching the URL again, even if its contents changed. Creation returns 201; replay returns 200 and the original job. Changed input with the same key returns 409. Use a new key only when you want a new translation. After a network timeout, retry creation with the same key, file and settings. For 429, honor Retry-After. Do not blindly retry validation, authentication, balance or idempotency conflicts. Creation reserves credits. Completed translations are charged, including RESULT_DELIVERY_FAILED; retrying that error only retries delivery without another translation charge. Other failures release the reservation. GET /files is not required: for reuse or inspection, upload once with POST /files and submit its file_id as file_id in JSON or multipart. The legacy source_file_id input remains accepted. Each different target language is a new job with a new key. # Audio and video Source: https://equalang.com/developers#post-jobs-transcribe A recording goes through the same jobs as a document. POST /jobs/translate with an audio or video file (mp3, m4a, wav, flac, ogg, aac, opus, mp4, mov, webm, mkv) returns the translation as subtitles; POST /jobs/transcribe returns what was said, untranslated, and takes no target_language. Both accept `file`, `file_url` or `file_id` exactly as documents do. `options.output_formats` picks the formats each output is written in (srt, vtt, txt, json; default srt), and `options.subtitle_bilingual` adds a bilingual output to a translation. Read the files from `outputs`: kind is translation, transcript or bilingual, format is the file type, and the first entry is also `download_url`. A recording may run up to 180 minutes. Creation reserves the most it can cost, from its length (`usage.meter` is source_audio_ms); the finished job is charged for the speech that was actually heard -- silence and music are not -- and, when translated, for the tokens of what was said, at the text rate. `credits_charged` is never more than `credits_reserved`; a file without an audio track answers 422 DOCUMENT_NOT_READABLE, a longer one 422 MEDIA_TOO_LONG. # Temporary uploads Source: https://equalang.com/developers#post-files POST /files returns expires_at. Create the first translation within 60 minutes. Each account may stage at most 10 unused files totalling 524288000 bytes. Expired unused files cannot be downloaded or translated; the background sweep deletes their stored bytes even when job retention is soft or disabled. Reading a file does not extend this deadline. Once a job claims a source, normal job retention applies. Direct upload-and-translate needs no staging slot. Temporary uploads are not a file-storage service. # Upload and translate a document Source: https://equalang.com/developers#post-jobs-translate post /v1/jobs/translate Submit a document and target language to create a translation job. Required API-key scope: `translations:document`. - `Idempotency-Key` (header): Optional retry protection: reuse a unique value if a request times out to avoid creating another job. Omit it to create a new job on every call. Request: `multipart/form-data` - `file` (optional): The original document bytes, not base64. Supported extensions: pdf, docx, pptx, xlsx, epub, html, txt, srt, vtt, jpg, jpeg, png, webp, bmp, mp3, m4a, wav, flac, ogg, aac, opus, mp4, mov, webm, mkv. Maximum 104857600 bytes. - `file_url` (optional): Public HTTP or HTTPS document URL. Signed download URLs are supported; no login or additional headers may be required. - `file_id` (optional): The system-generated UUID returned by POST /files. Pass it unchanged; the file must belong to your account and remain available. - `source_language` (optional): Source language code from the language list. Use auto to detect it from the content. Values: `['auto', 'zh-CN', 'en', 'zh-TW', 'ja', 'ko', 'es', 'fr', 'pt', 'ru', 'de', 'pl', 'it']`. - `target_language` (required): Target language code from the language list. auto is not a target language. Values: `['zh-CN', 'en', 'zh-TW', 'ja', 'ko', 'es', 'fr', 'pt', 'ru', 'de', 'pl', 'it']`. - `options` (optional): Optional translation settings. In multipart requests, send this object as a JSON-encoded form field. - `subtitle_bilingual` (optional): For SRT/VTT subtitles, audio and video: keep the source text above the translation in each cue. A recording gets it as an extra bilingual output. Defaults to false. - `optimize_math_formula` (optional): Optimize the layout of mathematical formulas, for the document formats that support it. Omit or use null for the default. - `output_formats` (optional): For audio and video: the formats each output is written in. Defaults to srt. - `callback_url` (optional): Optional public HTTPS address to notify when the job finishes. It receives a POST carrying only type, job_id and status; fetch the job to read the result. Request: `application/json` - `file_url` (optional): Public HTTP or HTTPS document URL. Signed download URLs are supported; no login or additional headers may be required. - `source_language` (optional): Source language code from the language list. Use auto to detect it from the content. Values: `['auto', 'zh-CN', 'en', 'zh-TW', 'ja', 'ko', 'es', 'fr', 'pt', 'ru', 'de', 'pl', 'it']`. - `target_language` (required): Target language code from the language list. auto is not a target language. Values: `['zh-CN', 'en', 'zh-TW', 'ja', 'ko', 'es', 'fr', 'pt', 'ru', 'de', 'pl', 'it']`. - `options` (optional): Optional translation settings. In multipart requests, send this object as a JSON-encoded form field. - `subtitle_bilingual` (optional): For SRT/VTT subtitles, audio and video: keep the source text above the translation in each cue. A recording gets it as an extra bilingual output. Defaults to false. - `optimize_math_formula` (optional): Optimize the layout of mathematical formulas, for the document formats that support it. Omit or use null for the default. - `output_formats` (optional): For audio and video: the formats each output is written in. Defaults to srt. - `callback_url` (optional): Optional public HTTPS address to notify when the job finishes. It receives a POST carrying only type, job_id and status; fetch the job to read the result. - `file_id` (optional): The system-generated UUID returned by POST /files. Pass it unchanged; the file must belong to your account and remain available. Responses: - `201`: Successful response. - `400`: Missing file or malformed identifier or retry key. - `401`: Missing, invalid or expired API key. - `402`: INSUFFICIENT_CREDITS: top up the account before trying again. - `403`: The API key does not have the required scope. - `404`: The job or file does not exist, belongs to another account, or the file has expired. - `409`: The idempotency key was reused with different input, or the job state does not allow this action. - `413`: FILE_TOO_LARGE: the uploaded document exceeds the size limit. - `410`: FILE_EXPIRED: the temporary upload expired; upload it again. - `415`: Unsupported file extension or request Content-Type. - `422`: Invalid fields, unsupported options, or DOCUMENT_NOT_READABLE when text could not be extracted. - `429`: Request or temporary upload quota exceeded. Translate staged files or wait for their cleanup when code is STAGED_FILE_LIMIT_EXCEEDED. - `502`: The document URL could not be downloaded. - `504`: The document URL download timed out. - `200`: Idempotent replay: the original job_id. # Transcribe audio or video Source: https://equalang.com/developers#post-jobs-transcribe post /v1/jobs/transcribe Submit a recording to get what was said as timed text. To get it translated, send the same file to POST /jobs/translate instead. Required API-key scope: `translations:document`. - `Idempotency-Key` (header): Optional retry protection: reuse a unique value if a request times out to avoid creating another job. Omit it to create a new job on every call. Request: `multipart/form-data` - `file` (optional): The original document bytes, not base64. Supported extensions: pdf, docx, pptx, xlsx, epub, html, txt, srt, vtt, jpg, jpeg, png, webp, bmp, mp3, m4a, wav, flac, ogg, aac, opus, mp4, mov, webm, mkv. Maximum 104857600 bytes. - `file_url` (optional): Public HTTP or HTTPS document URL. Signed download URLs are supported; no login or additional headers may be required. - `file_id` (optional): The system-generated UUID returned by POST /files. Pass it unchanged; the file must belong to your account and remain available. - `source_language` (optional): Source language code from the language list. Use auto to detect it from the content. Values: `['auto', 'zh-CN', 'en', 'zh-TW', 'ja', 'ko', 'es', 'fr', 'pt', 'ru', 'de', 'pl', 'it']`. - `options` (optional): Optional translation settings. In multipart requests, send this object as a JSON-encoded form field. - `subtitle_bilingual` (optional): For SRT/VTT subtitles, audio and video: keep the source text above the translation in each cue. A recording gets it as an extra bilingual output. Defaults to false. - `optimize_math_formula` (optional): Optimize the layout of mathematical formulas, for the document formats that support it. Omit or use null for the default. - `output_formats` (optional): For audio and video: the formats each output is written in. Defaults to srt. - `callback_url` (optional): Optional public HTTPS address to notify when the job finishes. It receives a POST carrying only type, job_id and status; fetch the job to read the result. Request: `application/json` - `file_url` (optional): Public HTTP or HTTPS document URL. Signed download URLs are supported; no login or additional headers may be required. - `source_language` (optional): Source language code from the language list. Use auto to detect it from the content. Values: `['auto', 'zh-CN', 'en', 'zh-TW', 'ja', 'ko', 'es', 'fr', 'pt', 'ru', 'de', 'pl', 'it']`. - `options` (optional): Optional translation settings. In multipart requests, send this object as a JSON-encoded form field. - `subtitle_bilingual` (optional): For SRT/VTT subtitles, audio and video: keep the source text above the translation in each cue. A recording gets it as an extra bilingual output. Defaults to false. - `optimize_math_formula` (optional): Optimize the layout of mathematical formulas, for the document formats that support it. Omit or use null for the default. - `output_formats` (optional): For audio and video: the formats each output is written in. Defaults to srt. - `callback_url` (optional): Optional public HTTPS address to notify when the job finishes. It receives a POST carrying only type, job_id and status; fetch the job to read the result. - `file_id` (optional): The system-generated UUID returned by POST /files. Pass it unchanged; the file must belong to your account and remain available. Responses: - `201`: Successful response. - `400`: Missing file or malformed identifier or retry key. - `401`: Missing, invalid or expired API key. - `402`: INSUFFICIENT_CREDITS: top up the account before trying again. - `403`: The API key does not have the required scope. - `404`: The job or file does not exist, belongs to another account, or the file has expired. - `409`: The idempotency key was reused with different input, or the job state does not allow this action. - `413`: FILE_TOO_LARGE: the uploaded document exceeds the size limit. - `410`: FILE_EXPIRED: the temporary upload expired; upload it again. - `415`: Unsupported file extension or request Content-Type. - `422`: Invalid fields, unsupported options, or DOCUMENT_NOT_READABLE when text could not be extracted. - `429`: Request or temporary upload quota exceeded. Translate staged files or wait for their cleanup when code is STAGED_FILE_LIMIT_EXCEEDED. - `502`: The document URL could not be downloaded. - `504`: The document URL download timed out. - `200`: Idempotent replay: the original job_id. # Translate text Source: https://equalang.com/developers#post-text-translate post /v1/text/translate Translate one or more plain texts and return the results directly. Required API-key scope: `translations:text`. - `Idempotency-Key` (header): Optional retry protection. Reuse the same key and input after a timeout to avoid duplicate charges; results are retained for 86400 seconds. Request: `application/json` - `texts` (optional): Plain texts in input order. Send one item for a single text. At most 50 items, 5000 characters per item and 20000 characters in total. Blank items are rejected. - `text` (optional): One whole text instead of texts: an article or a chapter, paragraphs and line breaks included, up to 100000 characters. It is divided at sentences on our side and comes back as one translation; do not cut a long text into texts yourself. - `source_language` (optional): Source language code from the language list. Use auto to detect it from the content. Values: `['auto', 'af', 'sq', 'am', 'ar', 'hy', 'az', 'eu', 'be', 'bn', 'bs', 'bg', 'my', 'yue', 'ca', 'zh-CN', 'zh-Hant', 'zh-HK', 'zh-TW', 'hr', 'cs', 'da', 'nl', 'en', 'en-GB', 'et', 'fil', 'fi', 'fr', 'fr-CA', 'gl', 'ka', 'de', 'el', 'gu', 'ht', 'ha', 'he', 'hi', 'hu', 'is', 'ig', 'id', 'ga', 'it', 'ja', 'ja-honor', 'ja-humble', 'ja-plain', 'ja-formal', 'jv', 'kn', 'kk', 'km', 'ko', 'ku', 'ckb', 'lo', 'la', 'lv', 'lt', 'mk', 'ms', 'ml', 'mt', 'mr', 'mn-Cyrl', 'cnr', 'ne', 'no', 'or', 'fa', 'pl', 'pt', 'pt-BR', 'pa', 'ro', 'ru', 'sr-Cyrl', 'sr-Latn', 'si', 'sk', 'sl', 'so', 'es', 'es-419', 'sw', 'sv', 'tg-Cyrl', 'ta', 'te', 'th', 'bo', 'ti', 'tr', 'tk-Cyrl', 'tk-Latn', 'uk', 'ur', 'ug', 'uz', 'vi', 'cy', 'yi', 'yo', 'zu']`. - `target_language` (required): Target language code from the language list. auto is not a target language. Values: `['af', 'sq', 'am', 'ar', 'hy', 'az', 'eu', 'be', 'bn', 'bs', 'bg', 'my', 'yue', 'ca', 'zh-CN', 'zh-Hant', 'zh-HK', 'zh-TW', 'hr', 'cs', 'da', 'nl', 'en', 'en-GB', 'et', 'fil', 'fi', 'fr', 'fr-CA', 'gl', 'ka', 'de', 'el', 'gu', 'ht', 'ha', 'he', 'hi', 'hu', 'is', 'ig', 'id', 'ga', 'it', 'ja', 'ja-honor', 'ja-humble', 'ja-plain', 'ja-formal', 'jv', 'kn', 'kk', 'km', 'ko', 'ku', 'ckb', 'lo', 'la', 'lv', 'lt', 'mk', 'ms', 'ml', 'mt', 'mr', 'mn-Cyrl', 'cnr', 'ne', 'no', 'or', 'fa', 'pl', 'pt', 'pt-BR', 'pa', 'ro', 'ru', 'sr-Cyrl', 'sr-Latn', 'si', 'sk', 'sl', 'so', 'es', 'es-419', 'sw', 'sv', 'tg-Cyrl', 'ta', 'te', 'th', 'bo', 'ti', 'tr', 'tk-Cyrl', 'tk-Latn', 'uk', 'ur', 'ug', 'uz', 'vi', 'cy', 'yi', 'yo', 'zu']`. Responses: - `200`: Batch processed. Results follow input order; failed items contain an error and are not charged. - `400`: Texts must be nonblank and the optional retry key must be valid. - `401`: Missing, invalid or expired API key. - `402`: INSUFFICIENT_CREDITS: top up the account before trying again. - `403`: The API key does not have the required scope. - `409`: The retry key has different input or its first request is still processing. - `413`: Too many texts, an oversized text, or the batch character limit was exceeded. - `422`: Invalid language codes, text types or request fields. - `429`: Request or concurrency limit exceeded; wait before retrying. # Query progress and result links Source: https://equalang.com/developers#get-jobs-job-id get /v1/jobs/{job_id} Get the progress, result and download links for a translation job. Required API-key scope: `translations:document`. - `job_id` (path): The job_id returned when the job was created. Responses: - `200`: Successful response. - `400`: Missing file or malformed identifier or retry key. - `401`: Missing, invalid or expired API key. - `403`: The API key does not have the required scope. - `404`: The job or file does not exist, belongs to another account, or the file has expired. # Cancel a translation Source: https://equalang.com/developers#post-jobs-job-id-cancel post /v1/jobs/{job_id}/cancel Cancel a queued or running translation job. Required API-key scope: `translations:document`. - `job_id` (path): The job_id returned when the job was created. Responses: - `200`: Successful response. - `400`: Missing file or malformed identifier or retry key. - `401`: Missing, invalid or expired API key. - `403`: The API key does not have the required scope. - `404`: The job or file does not exist, belongs to another account, or the file has expired. - `409`: The idempotency key was reused with different input, or the job state does not allow this action. # Retry a failed or cancelled translation Source: https://equalang.com/developers#post-jobs-job-id-retry post /v1/jobs/{job_id}/retry Retry a failed or cancelled translation using the same job ID. Required API-key scope: `translations:document`. - `job_id` (path): The job_id returned when the job was created. Responses: - `200`: Successful response. - `400`: Missing file or malformed identifier or retry key. - `401`: Missing, invalid or expired API key. - `402`: INSUFFICIENT_CREDITS: top up the account before trying again. - `403`: The API key does not have the required scope. - `404`: The job or file does not exist, belongs to another account, or the file has expired. - `409`: The idempotency key was reused with different input, or the job state does not allow this action. # List translation history Source: https://equalang.com/developers#get-jobs get /v1/jobs List your translation jobs, newest first. Required API-key scope: `translations:document`. - `limit` (query): Page size; values are clamped to 1–100. - `offset` (query): Number of records to skip, starting at 0. - `cursor` (query): next_cursor of the previous page. Prefer it to offset: a job created while you page neither repeats nor hides one. Not combined with offset. Responses: - `200`: Successful response. - `400`: Missing file or malformed identifier or retry key. - `401`: Missing, invalid or expired API key. - `403`: The API key does not have the required scope. # Check credit balance Source: https://equalang.com/developers#get-credits-balance get /v1/credits/balance Get your total, frozen and available credits. Responses: - `200`: Successful response. - `401`: Missing, invalid or expired API key. # Upload a reusable source document Source: https://equalang.com/developers#post-files post /v1/files Upload a source document for inspection or reuse across translations. Required API-key scope: `files:write`. Request: `multipart/form-data` - `file` (required): The original document bytes, not base64. Supported extensions: pdf, docx, pptx, xlsx, epub, html, txt, srt, vtt, jpg, jpeg, png, webp, bmp, mp3, m4a, wav, flac, ogg, aac, opus, mp4, mov, webm, mkv. Maximum 104857600 bytes. Responses: - `201`: Successful response. - `400`: Missing file or malformed identifier or retry key. - `401`: Missing, invalid or expired API key. - `403`: The API key does not have the required scope. - `413`: FILE_TOO_LARGE: the uploaded document exceeds the size limit. - `415`: Unsupported file extension or request Content-Type. - `422`: Invalid fields, unsupported options, or DOCUMENT_NOT_READABLE when text could not be extracted. - `429`: Request or temporary upload quota exceeded. Translate staged files or wait for their cleanup when code is STAGED_FILE_LIMIT_EXCEEDED. # Download a file Source: https://equalang.com/developers#get-files-file-id get /v1/files/{file_id} Download an original or translated file by its file ID. Required API-key scope: `files:read`. - `file_id` (path): Source or result file identifier. Responses: - `200`: File bytes. Content-Type reflects the stored document; Content-Disposition contains the filename. - `400`: Missing file or malformed identifier or retry key. - `401`: Missing, invalid or expired API key. - `403`: The API key does not have the required scope. - `404`: The job or file does not exist, belongs to another account, or the file has expired. - `410`: FILE_EXPIRED: the temporary upload expired; upload it again. # The TextTranslationResult object Source: https://equalang.com/developers#reference - `translated_text` (required): Translated text, or null if this item failed. - `detected_source_language` (required): Detected source language code; null if unavailable or this item failed. - `error` (required): Null on success; the error for this item on failure. # The TextTranslationUsage object Source: https://equalang.com/developers#reference - `credits_charged` (required): Total credits charged for successful items. Failed items are not charged. # The TextTranslationError object Source: https://equalang.com/developers#reference - `code` (required): Error code for this text. - `message` (required): Reason the text could not be translated. - `retryable` (required): Whether this item can be retried in a new request. # The Job object Source: https://equalang.com/developers#reference - `job_id` (required): Translation job identifier. Use it for polling, cancellation and retry. - `finished` (required): true for SUCCEEDED, FAILED or CANCELLED. Stop polling when true. - `status` (required): INIT: accepted; QUEUED: waiting; RUNNING: translating; CANCELLING: stopping; SUCCEEDED: complete; FAILED: unsuccessful; CANCELLED: cancelled. Values: `['INIT', 'QUEUED', 'RUNNING', 'CANCELLING', 'SUCCEEDED', 'FAILED', 'CANCELLED']`. - `progress_percent` (required): Progress from 0 to 100. This is not an estimate of remaining time. - `download_url` (required): Temporary result link on success, otherwise null. Refresh the job to renew an expired link; download without the API Authorization header. - `result_filename` (required): Translated document filename, or null before a result exists. - `outputs` (required): Every file the job produced; empty until it succeeds. download_url and the dual_* fields name the same files one by one. - `error` (required): Failure details, or null when no error has been recorded. - `usage` (required): Reservation and settlement for this job, in credits. - `meter` (required): source_token: tokens extracted from the source document, not bytes or output tokens. source_image: images, for an image file. source_audio_ms: milliseconds a recording plays. Values: `['source_audio_ms', 'source_token', 'source_image']`. - `source_units` (required): Number of source tokens (or images) used for pricing. - `credits_reserved` (required): Credits reserved while the job runs; not an additional charge. - `credits_charged` (required): Settled credits. A completed translation is charged even if result delivery fails; retrying RESULT_DELIVERY_FAILED only retries delivery, without another translation charge. - `task` (required): What the job does: translate, or transcribe for a recording whose words are wanted as spoken. Values: `['translate', 'transcribe']`. - `source_language` (required): Requested source language; auto means automatic detection. - `target_language` (required): Requested target language; null for a transcription. - `source_file_id` (required): Stored source file identifier. - `target_file_id` (required): Stored result identifier, or null until available. - `source_filename` (required): Original uploaded filename. - `source_download_url` (required): Temporary link to the retained original file. - `dual_filename` (required): Filename of the combined original-and-translation PDF, when generated. - `dual_download_url` (required): Combined PDF link, when available. Each job query signs a fresh 15-minute link while the file is retained. - `source_file_deleted_at` (required): When the source bytes were deleted; null while retained. - `target_file_deleted_at` (required): When the result bytes were deleted; null while retained or before a result exists. - `client_request_id` (required): Your optional business reference, returned unchanged. - `retry_count` (required): Number of explicitly requested retries. - `created_at` (required): Job creation timestamp with timezone. - `started_at` (required): Execution start timestamp, or null before starting. - `completed_at` (required): Completion timestamp, or null while unfinished. # The JobUsage object Source: https://equalang.com/developers#reference - `meter` (required): source_token: tokens extracted from the source document, not bytes or output tokens. source_image: images, for an image file. source_audio_ms: milliseconds a recording plays. Values: `['source_audio_ms', 'source_token', 'source_image']`. - `source_units` (required): Number of source tokens (or images) used for pricing. - `credits_reserved` (required): Credits reserved while the job runs; not an additional charge. - `credits_charged` (required): Settled credits. A completed translation is charged even if result delivery fails; retrying RESULT_DELIVERY_FAILED only retries delivery, without another translation charge. # The JobError object Source: https://equalang.com/developers#reference - `code` (required): Stable error identifier. Values: `['DOCUMENT_TRANSLATION_FAILED', 'RESULT_DELIVERY_FAILED', 'JOB_NEEDS_REVIEW']`. - `message` (required): What failed and, when available, how to resolve it. - `retryable` (required): Whether retrying the job can succeed. # The File object Source: https://equalang.com/developers#reference - `file_id` (required): Pass this identifier as file_id to create a translation job. - `expires_at` (required): Deadline to create the first translation job. Unused files expire after 3600 seconds; each account may stage 10 files totaling 524288000 bytes. Once claimed, job retention applies. - `filename` (required): Original filename without directory components. - `kind` (required): source for an uploaded document. Values: `['source']`. - `mime_type` (required): Stored media type. - `extension` (required): Document filename extension. Values: `['pdf', 'docx', 'pptx', 'xlsx', 'epub', 'html', 'txt', 'srt', 'vtt', 'jpg', 'jpeg', 'png', 'webp', 'bmp', 'mp3', 'm4a', 'wav', 'flac', 'ogg', 'aac', 'opus', 'mp4', 'mov', 'webm', 'mkv']`. - `size_bytes` (required): File size in bytes. - `sha256` (required): SHA-256 digest of the uploaded bytes. - `document_info` (required): Extracted counts for estimating cost. Null when unavailable. - `created_at` (required): Upload timestamp with timezone. - `quote` (optional): The most a job on this file can cost, in credits, so a client can say so before creating one. Null when the file could not be measured. Returned by POST /files. # The DocumentInfo object Source: https://equalang.com/developers#reference - `n_tokens` (required): Source token count used for the quote. - `n_chars` (required): Extracted character count. - `n_words` (required): Extracted word count. - `n_images` (optional): Image count, for an image file; absent otherwise. - `detected_language` (required): Detected source language. - `inspected_at` (required): Inspection timestamp.