API reference
Every error the API can return
The status, the error code, why it happened and what to do about it — for the shared statuses and for the two endpoints that have failure modes of their own.
These rows are the same ones the API is tested against.
Errors carry a JSON envelope with a type and usually a code. Read error.message first: it names the field or the endpoint to use instead. A 402 means an empty wallet, a 429 or 503 is transient and safe to retry after Retry-After, and a 401 means the key itself.
Which errors can any endpoint return?
These statuses are shared. Anything you call can answer with one of them.
| Row label | Why it happened | What to do |
|---|---|---|
| 400 | a field failed validation, or the model's task_type does not match this endpoint Field-validation errors carry no code, except on the audio upload endpoints. A task_type mismatch carries invalid_task_type. | Read error.message — it names the field, or the endpoint to use instead. Two 400s skip this envelope: unparseable JSON answers in plain text, and an error relayed from the model is passed through in the model's own shape. Parse defensively. |
| 401 | the API key was missing, malformed, expired, revoked or blocked code is invalid_api_key or api_key_blocked. | Use a live key. |
| 402 | your wallet has no spendable balance code is insufficient_balance. The check is balance above zero, never the price of the request. | Top up. Some models bill from wallet balance only, not promotional credit. |
| 404 | no model with that id is active for API use, or no backend is configured to serve it code is model_not_found. The two causes are indistinguishable. | Use an id from /v1/models whose status is live. |
| 413 | the request body was larger than 32 MiB Audio uploads have their own, lower limits — see Transcriptions. | Send a smaller body. |
| 415 | a JSON endpoint was called without Content-Type: application/json Audio format failures are listed under Transcriptions. | Set the header. |
| 422 | the body is valid JSON but the wrong shape Rejected before any handler runs, so the body is plain text. | Check the field types above. |
| 429 | you were rate limited, or every backend for the model was busy rate_limit_exceeded is a per-key limit; backend_saturated is capacity. Tell them apart by error.code. | Wait for Retry-After, then retry; both are transient. |
| 500 | the request could not be completed type is server_error; there is no code. | Retry. If it repeats, contact support and quote x-request-id. |
| 502 | every backend for the model failed, or the model returned nothing type is server_error. On a streamed request the 200 is already sent, so an empty result arrives as an empty stream rather than a 502. | Retry once. If it persists, try another id or contact support. |
| 503 | usually the model is starting type server_starting, code model_warming. Any other 503 is server_error, and its code names the reason. | For model_warming, wait for Retry-After and retry. For a server_error 503, back off and quote x-request-id. |
| 504 | the model did not answer in time code is backend_timeout. Audio, forecast and classify only; chat and embeddings surface a timeout as 502. | Retry — a 504 is not charged. Each attempt uses the serving backend's own deadline: 120 seconds by default, 300 where it has no runtime config, or whatever that backend is configured with. |
Which errors are specific to audio uploads?
Additional failures on /v1/audio/transcriptions and /v1/audio/translations, on top of the shared statuses above.
| Row label | Why it happened | What to do |
|---|---|---|
| 413 | the audio file is larger than 25 MiB (26,214,400 bytes) code is audio_too_large. | Trim or re-encode to a shorter clip. |
| 415 | the upload was not recognized as audio, by extension, Content-Type or leading bytes code is unsupported_audio_format. | Use one of the extensions listed under file, or send an audio/* Content-Type. |
| 400 | stream=true was sent code is streaming_unsupported. | Omit it, or set it to false. |
| 400 | a single-value part was sent twice code is duplicate_<field>_field. | Send each part once; the last value does not win. timestamp_granularities[] is the exception. |
| 400 | temperature is outside 0 to 1, or response_format is not one of the five code is temperature_out_of_range or unsupported_response_format. | Send an allowed value, or omit the field. |
| 400 | language is not an ISO-639-1 code code is invalid_language. | Send a two-letter code such as en or es (yue, nan, wuu and cmn are also accepted), or omit the field. |
| 413 | no backend serving this model accepts a file this size, even under 25 MiB code is audio_too_large_for_runtime. | Send a smaller file. |
| 503 | too many audio uploads are in flight code is audio_capacity. | Wait for Retry-After, then retry. |
Which errors are specific to speech synthesis?
Additional failures on /v1/audio/speech.
| Row label | Why it happened | What to do |
|---|---|---|
| 400 | a field failed validation code is model_required, input_required, voice_required, unsupported_response_format or speed_out_of_range. | Send an allowed value. |
| 413 | input is longer than 4096 characters code is input_too_long. Counted in characters, not bytes. | Split the text and stitch the audio, or send less. |
| 400 | the model rejected the request, most often an unknown voice The body is the model's own error, passed through and capped at 512 bytes, so it may not use the envelope above. | Check the voice. |
Which errors are safe to retry?
429, 503 and 504 are transient and a retry is the right response. Honour Retry-After where it is present rather than retrying immediately — on a 503 it is usually a model still starting, and retrying before it is ready only spends your own attempt. A 504 is not charged.
400, 401, 402, 404, 413, 415 and 422 will not succeed on a retry: something about the request, the key or the balance has to change first.
Quote the request id
x-request-id. Include it when contacting support about a 500 or a persistent 502 — it is what lets the failure be found. Full reference: the API docs.