TranslaQEDevelopers

Translate documents

Upload a file, follow its job, review its sentences and download it translated, with its layout intact.

A document is translated in the background. You upload it, the API answers at once with a job, and you come back for the translated file, in the same format and with the same layout.

Formats

  • Office: DOCX, XLSX, PPTX and their macro-enabled and template variants.
  • OpenDocument: ODT, ODS, ODP, ODG and their templates.
  • Web and text: HTML, XHTML, TXT, Markdown.
  • Software: JSON, YAML, PO, Java properties.

A file can be up to 50 MB.

1. Upload

POST /v1/jobs takes a form (multipart/form-data) with the file and the two languages. The answer is 202 with the job, queued.

curl https://api.translaqe.com/v1/jobs \
  -H "Authorization: Bearer $TRANSLAQE_API_KEY" \
  -H "Idempotency-Key: contract-2026-10-12" \
  -F "[email protected]" \
  -F "source_lang=es" \
  -F "target_lang=en" \
  -F "glossary_ids=gl_3f9a1c2b7d5e4f60a1b2c3d4e5f60718" \
  -F "webhook_url=https://example.com/hooks/translaqe"
Field What it is for
file The document.
source_lang, target_lang The language it is in and the one you want.
memory_ids, glossary_ids Memories and glossaries to translate with, separated by commas.
project_id A project: its memories and glossaries are used, and the job is listed under it.
webhook_url An HTTPS address to call when the job ends.
notify_email An address to email when the job ends.
allow_partial Deliver the file even if some sentence cannot be translated.

Send an Idempotency-Key header with a value of your own. If the connection drops and you send the upload again with the same value, you get the same job back (200) instead of translating, and paying for, the file twice.

2. Wait for it

Ask for the job every few seconds until its status is final:

Status Meaning
queued Waiting for its turn.
running In progress: stage says where (extracting, translating, scoring, rebuilding) and progress how far.
retrying It failed and will be tried again.
succeeded Done: result has the numbers and the file is ready.
failed It could not be done: error_code says why.
cancelled You cancelled it.
JOB=job_8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f

# Ask until it is over: succeeded, failed or cancelled.
while true; do
  STATUS=$(curl -s "https://api.translaqe.com/v1/jobs/$JOB" \
    -H "Authorization: Bearer $TRANSLAQE_API_KEY" | jq -r .status)
  case "$STATUS" in succeeded|failed|cancelled) break ;; esac
  sleep 5
done

# -OJ saves the file under the name the API gives it.
[ "$STATUS" = succeeded ] && curl -sOJ "https://api.translaqe.com/v1/jobs/$JOB/file" \
  -H "Authorization: Bearer $TRANSLAQE_API_KEY"

Or let us call you

With webhook_url, a POST is sent to your address when the job ends, well or badly:

POST /hooks/translaqe HTTP/1.1
Content-Type: application/json
User-Agent: TranslaQE-Webhook/1
X-TranslaQE-Event: job.succeeded
X-TranslaQE-Delivery: 5b0e…

{
  "job_id": "job_8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f",
  "status": "succeeded",
  "error_code": null,
  "sent_at": "2026-10-12T09:31:47+00:00"
}

The events are job.succeeded and job.failed, and for memories and glossaries resource.ready and resource.failed, which also carry resource_id and kind. A cancelled job sends nothing.

The notice carries no content and is not signed. Treat it as a hint: when it arrives, ask for the job with your key and act on what the API tells you.

3. Download

GET /v1/jobs/{job_id}/file returns the translated file. Its name comes in the Content-Disposition header. Before the job has succeeded the answer is 409 with the type job-not-ready.

result tells you how it went: the average score, how many sentences scored under 60 (low_score_segments) and how many needed a formatting mark fixed (mark_warnings).

When a sentence cannot be translated

If no model can translate some sentence, the job ends failed with error_code: "partial" and no file: a document with holes is not delivered behind your back. You have two ways out:

  • Upload it with allow_partial: true. The file is delivered with those sentences in the source language, and result.failed_segments says how many.
  • Write the missing translations yourself (below) and build the file again.

Review and correct

Every sentence of the document is available at GET /v1/jobs/{job_id}/segments, with its source, its translation, its score and its state. Filter by band to go straight to the ones that need a look, correct them with PATCH, and ask for the file to be built again.

JOB=job_8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f
AUTH="Authorization: Bearer $TRANSLAQE_API_KEY"

# 1. The sentences that need another translation.
curl -s "https://api.translaqe.com/v1/jobs/$JOB/segments?band=rehacer" -H "$AUTH"

# 2. Correct one of them.
curl -s -X PATCH "https://api.translaqe.com/v1/jobs/$JOB/segments/12" \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"target": "The rate in force at the time of the order will apply.", "state": "approved_translation"}'

# 3. Build the file again with the corrections.
curl -s -X POST "https://api.translaqe.com/v1/jobs/$JOB/rebuild" -H "$AUTH"

# 4. Keep what was approved in a memory, for next time.
curl -s -X POST "https://api.translaqe.com/v1/jobs/$JOB/review" \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"memory_id": "tm_5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d"}'
  • A corrected sentence becomes a person's translation (origin: "interactive") and loses its score.
  • The translation must keep the formatting marks of the source (<g1>…</g1>, <x1/>): they are what puts bold, links and line breaks back in place.
  • POST /v1/jobs/{job_id}/rebuild uses no characters: nothing is translated again.
  • POST /v1/jobs/{job_id}/review sends to a memory what a person wrote or approved. The next document that repeats those sentences gets them from the memory.

Clean up

DELETE /v1/jobs/{job_id} deletes the job with its sentences and its files, the original and the translated one. A job that is queued or running has to be cancelled first, with POST /v1/jobs/{job_id}/cancel.