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. Rotate.
  • 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

  • MULTILINGUAL_NOT_ENABLED — request language is non-English and the permission isn't enabled on your account.
  • 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 / rotate 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: