Error codes

Three response shapes

All three are application/json.

1. Standard error — a string detail. The common case for every explicit rejection.

{"detail": "job not found"}

2. Validation error — an array detail. Emitted by the framework for malformed path, query, header, or body parameters. Always 422. Each entry carries loc (the path to the offending value), msg, type, and optionally input and ctx.

{
  "detail": [
    {
      "loc": ["query", "limit"],
      "msg": "Input should be less than or equal to 500",
      "type": "less_than_equal",
      "input": "900",
      "ctx": {"le": 500}
    }
  ]
}

3. Pipeline error — detail plus error_code and request_id. Emitted when a typed pipeline exception reaches the boundary — the status comes from the exception class — and by an unexpected internal failure, which answers 500 with {"detail": "internal error", "error_code": "internal_error", "request_id": "…"}. request_id is never null: it is the same id as the response’s X-Request-ID header — yours when you sent one, otherwise one the server generated — so every failure is traceable.

{
  "detail": "document layout is unavailable",
  "error_code": "validation_error",
  "request_id": "b0a1f2c3d4e5f60718293a4b5c6d7e8f"
}
Note: Not every 422 uses the array shape. Language rejections, batch expansion failures, the storage-binding validations, the terminology and translation-memory capacity rejections, a content-policy refusal, and every billing request-body rejection return 422 with a string detail. Type-check detail before you index into it.

Stable tokens

Four rejections put a stable token at the front of a string detail so you can branch without parsing prose. Everything after the token is human-readable detail — counts, allowance, remediation — whose wording may change, so match on the prefix only.

TokenStatusEndpointMeaning
workspace_id_required: 401 POST /api/oauth2/token (password grant) A password sign-in sent without a workspace ID matched none of the accounts it checked, and the email address belongs to more workspaces than that sign-in searches. Sign in again with your workspace ID in tenant_id — the sign-in page’s optional Workspace ID field.
terminology_max_terms_exceeded: 422 POST /api/terminology The upload would take the tenant past its terminology allowance for the language pair. Nothing was stored.
tm_max_segments_exceeded: 422 POST /api/tm The import would take the tenant past its translation-memory allowance for the language pair. Nothing was imported.
tm_import_in_progress: 409 POST /api/tm, DELETE /api/tm/{set_id} An import into the same set name is still running, whether it runs inline or in the background. An import replaces its set wholesale, so a second import cannot overlap it, and a delete would be undone when it lands. Nothing was imported or deleted — wait for the running import to finish (for a background import the message names the job to poll), then retry.

error_code values

These are all the values that exist. Each maps to exactly one HTTP status, but a status can carry more than one value — and most statuses are also returned without one — so switch on error_code, the stable half.

error_codeStatusMeaning
validation_error400 The request, or the referenced resource’s state, was invalid — an unsupported document format, a file that cannot be read or is past a document limit, a document with no layout, an approve on a job that is not translated yet.
not_found404 A referenced job or resource does not exist — including a job deleted while it was still processing.
conflict409 The request conflicts with current state.
storage_binding_not_verified409 Bring Your Own Storage is configured for the workspace but cannot take the work: the binding is not verified, or its stored secret is missing or unreadable. A translation submission or document upload is refused before anything is created or translated — verify the binding (re-entering the secret if it is gone), then resubmit. A document download, review or approval that has to reach that storage is refused the same way. When a text job’s golden record hits an unverified binding instead (a review approval, say), that job is parked as persistence_failed and publishes once the binding is verified, the workspace returns to platform storage, or the binding is deleted.
content_filtered422 The model provider’s content policy refused the text. The same text is refused again on every retry — change the text.
rate_limit429 Translation capacity is temporarily saturated, even after the service’s own retries. Retry with backoff.
quota_exceeded429 A document found no allowance left this month once extraction had counted its characters. Nothing was translated or billed. A wait=true submission returns it; an asynchronous job records it as its failure code. Retrying cannot help until a top-up or the next month adds headroom.
internal_error500 Unexpected internal failure. The body’s request_id is what support needs to find it.
persistence_failed502 Writing the golden record failed after the translation finished. The translation is kept — readable through GET, and billed — and the job is parked as persistence_failed; verifying storage (POST /api/storage/binding/verify) publishes it.
transient_error503 A retryable upstream failure — the model provider or a storage dependency (the service’s own secret storage included) was unavailable, even after the service’s own retries. Safe to retry with backoff.
service_unavailable503 A required dependency is unavailable or misconfigured.
stage_timeout504 A wait=true document request whose processing stage used up its time budget; the job is failed with that same code. The stage’s work is fixed by the document, so resubmitting it unchanged is likely to run out of time again — split it.

transient_error and rate_limit are the retryable set. Everything else, stage_timeout included, indicates the request will fail the same way if you replay it unchanged — fix the request or the resource state first.

HTTP status reference

What each status means in TrueIdiom, and the one thing to do about it. The exact detail string you get back depends on the endpoint — Conventions & errors lists every detail string per status.

StatusWhat it meansWhat to do
200 Success — including synchronous submissions, reviews, approvals, and deletions, which return a body of cascade counts rather than a 204. Nothing. Read the body.
202 Accepted and genuinely in flight: a document translation sent to POST /api/documents/translate without wait=true, or a large TMX import. (A document uploaded to POST /api/translations comes back 200 with the queued job.) Poll the job at the URL in the body. Async jobs are poll-only.
204 Deleted, no body — a terminology or translation-memory set, or a withdrawn invite. Nothing. Do not parse a body.
400 Malformed or missing input the endpoint itself checks — a bad api-version, an empty or missing upload, blank source text, a missing target_lang, a file that cannot be read (corrupt, password-protected, or text that is neither UTF-8 nor UTF-16 with a byte-order mark), or a Word or Excel file past a document limit. Also every validation_error pipeline error. Fix the request. Retrying it unchanged fails identically.
401 No usable credential: a missing or invalid API key, tenant credentials, or bearer token — or a sign-in step that failed: a wrong password, a wrong MFA code, or an MFA challenge that has expired or been used up. Send a valid credential, or refresh an expired token; a used-up MFA challenge means starting again from the password step. For workspace_id_required:, sign in with your workspace ID. See Authentication.
402 Billing is on and the workspace cannot start this billable work — no active subscription; the free trial is used up, has ended, or has fewer characters left than the request needs; or the request is one the trial does not cover (a PDF, Word or Excel document, or a call made with an API key). A top-up also needs an active subscription. Add a payment method at /billing.
403 Authenticated but not permitted: the admin role is required, the action is reserved for the service operator, your organization requires an invitation to join through single sign-on, or the sign-in method you tried is switched off for this deployment. Use an administrator credential, an invite link from your workspace admin, or the sign-in method the deployment allows. Never retry as-is.
404 The job, document, artifact, set, tenant or user does not exist — or is not yours to see, or was deleted while it was still processing. Check the id. Do not treat it as transient.
409 A conflict with current state: the golden translation is not available at this job status; a document download before the job is translated (still in progress, or failed); an import into the same translation-memory set is running; the workspace’s own storage binding is not verified or has lost its stored secret; a billing change the account’s state rules out; or a required capability is not enabled. Wait for the state to change and re-read, or enable the capability. A failed document has no translation to download — resubmit it. For tm_import_in_progress:, let the running import finish first; for storage_binding_not_verified, verify the binding, then resubmit.
413 The upload, request body, source text or batch is past a size ceiling. Split the work or shrink the file. See Limits & quotas.
415 The file type is not one this endpoint accepts — a source document, a terminology file, or a TMX. Convert the file. See Supported file formats.
422 The request parsed but the values do not hold up: framework parameter validation (array detail), an unsupported language code, a batch that would not expand, a storage-binding validation, a terminology or TM capacity rejection, or text the model provider’s content policy refused (content_filtered). Fix the request. Type-check detail, and match the stable token prefix for the capacity rejections. Refused text is refused again unchanged.
429 Rate limited — too many attempts, too many failed MFA codes, or translation capacity saturated (rate_limit) — or the monthly character allowance has no room for the request, including a document refused once its characters were counted (quota_exceeded). Honour Retry-After where present and back off; do not retry inside the window. For an exhausted allowance, take the remedy the detail names at /billing — a top-up for this month, or an upgrade, which raises the allowance immediately and is charged the prorated difference at once (a downgrade waits for renewal) — or, once the month’s ceiling is reached, contact us.
500 An unexpected internal failure (internal_error), or a stored document artifact that failed its integrity check. Do not use a download that failed its check. Retry once; if it persists, give support the request_id — the same id as the X-Request-ID response header.
502 A backend needed for a terminology or TM import was unavailable, writing the golden record failed, or the workspace’s platform storage could not be set up. Retry the import or the storage change. A golden-record failure parks the job with its translation intact and billed, so do not resubmit it — POST /api/storage/binding/verify publishes it. A TM import that ran asynchronously records the same message on the import job’s error instead of returning 502.
503 Retryable upstream failure (the service’s own secret storage included), a misconfigured dependency, or a capability switched off or not set up on this deployment (translation, billing or top-ups). Retry with backoff. If the message says a capability is disabled or not configured, retrying will not help — that is a deployment setting.
504 A wait=true document request whose processing stage used up its time budget (stage_timeout); the job is marked failed. Split the document; resubmitting it unchanged is likely to run out of time again.
507 This workspace’s stored document artifacts, plus the upload being submitted, would pass the cap this deployment sets for platform-hosted bytes. Delete document jobs you no longer need, or bring your own storage so the bytes land in your account instead. Bound tenants skip the check entirely.
Note: An id that belongs to another workspace returns 404, never 403. Existence is never confirmed to a caller who may not see it, so a 404 means “not yours or not there” — the two are deliberately indistinguishable.

What's next

  • Conventions & errors — the canonical catalog, including every detail string each status can carry.
  • Limits & quotas — the ceilings behind the 413, 422 and 429 rejections.
  • Text translation — the endpoint most of these statuses come from, with the errors it can raise.