Skip to main content

Error handling

Most production errors fall into a small number of patterns. This page covers the right response to each.

Standard error shape​

Every 4xx and 5xx response from the public API uses the platform's shared standard error envelope:

{
"error": {
"code": "INVALID_LANGUAGE_CODE",
"message": "Invalid language code. Must be a 2-letter ISO 639-1 code.",
"timestamp": "2026-04-21T12:34:56.789Z",
"requestId": "req_1705412345678_abc123",
"details": { /* optional, code-specific extras */ }
}
}

code, message, and timestamp are always present. requestId and details are included when they apply — requestId is emitted once the route handler has generated one (middleware-level rejections happen before that and omit it). It's the same envelope on every module; see Identifiers for how requestId differs from the run id and your externalId.

Rate-limit and service-warming responses also include error.retryAfterSeconds and the standard HTTP Retry-After header. Respect the header.

Common cases​

400 Bad Request​

Malformed input. Fix the request and retry. Typical codes:

  • MISSING_AUDIO_FILE
  • UNSUPPORTED_FORMAT
  • FILE_TOO_LARGE — audio exceeds the per-request file-size limit.
  • INVALID_LANGUAGE_CODE
  • INVALID_EXTERNAL_ID
  • INVALID_METADATA
  • AUDIO_TOO_SHORT / AUDIO_TOO_LONG

Do not retry a 400. It will fail the same way.

401 Unauthorized​

Check your API key. Possible codes:

  • MISSING_API_KEY — no X-API-Key or Authorization header.
  • INVALID_API_KEY — key not recognized or marked inactive.
  • API_KEY_EXPIRED — key had an expiration date that's now past. Extend the key's expiry in the console (API Keys → Extend expiry); the key value does not change.
  • CLIENT_INACTIVE — the account behind the key has been disabled. Contact support.

402 Payment Required​

INSUFFICIENT_CREDITS — balance below minimum. Top up before retrying.

403 Forbidden​

  • MISSING_PERMISSION — the account behind the key isn't entitled to the module you called.
  • IP_NOT_ALLOWED — the API key has an IP whitelist and your request didn't originate from an allowed address.

429 Too Many Requests​

Two flavors — treat them differently:

  • RATE_LIMIT_EXCEEDED on submit: you're submitting too fast. Back off with exponential delay.
  • POLL_RATE_LIMITED on poll: you're polling a single requestId too fast. Respect Retry-After and continue polling the same requestId.

503 Service Unavailable​

  • SERVICE_WARMING_UP — the scoring service is warming up after a fresh deployment (typically 15–20 minutes after a deploy). Retry with the suggested retryAfterSeconds, then back off further if still warming.

status: "failed" on a poll response​

The run reached a terminal failure. No credits were charged. Common codes:

  • TRANSCRIPTION_FAILED — audio quality issue or provider error.
  • TRANSCRIPTION_LOW_CONFIDENCE — audio content doesn't match the requested language.
  • SCORING_FAILED — scoring service error after retry.
  • SERVICE_CONFIGURATION_ERROR — external provider misconfigured (rare; contact support).
  • STUCK_TIMEOUT — run exceeded its watchdog timeout.
  • INTERNAL_ERROR — unexpected error (contact support).

Retry policy: resubmit the audio with a fresh request. Do not reuse the same requestId — it's terminal.

Retry strategy at a glance​

ResponseRetry?How
400NoFix input.
401NoCheck key / extend its expiry if expired / contact support if account inactive.
402NoTop up balance.
403NoContact support (language permission, IP whitelist).
429 RATE_LIMIT_EXCEEDEDYesRespect Retry-After, then exponential backoff.
429 POLL_RATE_LIMITEDYesRespect Retry-After, continue polling same requestId.
503 SERVICE_WARMING_UPYesRetry after 30–60s, back off further if repeated.
status: "failed"Case-by-caseFresh submission with new audio if applicable.

Full error code catalog​

See Resources → Error codes for every code the API can return, with recommended actions.

See in the API reference​

Every endpoint page lists the full response schema for each status code: