- an HTTP status that tells you the class of failure,
- a stable error code (
error_codeon task endpoints,codeon LLM endpoints) that tells you the exact reason, so your code can branch on it without parsing the message, - a
request_idyou can quote to support so we can find the exact request in our logs.
- Task endpoints (
/v1/tasks,/v1/account,/v1/resources) wrap every response in a{ success, code, data }envelope. See Task Endpoints. - LLM endpoints (
/v1/chat/completions,/v1/responses,/v1/messages,/v1/models) return the provider-native error shape. See LLM Endpoints.
Task Endpoints
Response Structure
Success Response
Error Response
Empty arrays and objects are omitted from responses when not needed.
Response Fields
boolean
Indicates whether the request was successful (
true) or failed (false)integer
HTTP status code of the response
object
Response data on success, error details on failure
string
Human-readable description of the error. Safe to show to your users
string
Stable machine-readable reason. Present when the failure has a defined code (see Error Codes). Branch on this, not on
message, since message text can changestring
Unique id of this request. Include it when contacting support. On
5xx responses the same id is also appended to messageHTTP Status Codes
Example Error Responses
Missing API key (401)
Missing API key (401)
Insufficient balance (402)
Insufficient balance (402)
Model not allowed for this key (403)
Model not allowed for this key (403)
Rate limit exceeded (429)
Rate limit exceeded (429)
Validation error (422)
Validation error (422)
Model disabled (540)
Model disabled (540)
Server error (500)
Server error (500)
LLM Endpoints
The LLM endpoints do not use the{ success, code, data } envelope. They return the error shape of the API they are compatible with, so drop-in OpenAI and Anthropic clients parse it natively. The code and request_id fields are the same values as error_code and request_id on task endpoints.
/v1/chat/completions, /v1/responses, and /v1/models return OpenAI-style errors:
/v1/messages returns Anthropic-style errors:
type field follows the status: authentication_error (401), permission_error (403), not_found_error (404), rate_limit_error (429), invalid_request_error (other 4xx), and service_unavailable (OpenAI-style) or api_error (Anthropic-style) for 5xx. Billing failures on /v1/chat/completions and /v1/responses use type insufficient_balance or billing_error. Use code for the exact reason.
HTTP Status Codes
On
/v1/chat/completions, a 400 is also returned when messages is empty or not an array, or when a message has a role other than system, developer, user, assistant, tool, or function.
Errors During Streaming
Once a stream has started, the HTTP status is already200. A later error arrives inside the stream, in the same shape as a non-stream error and with the same code and request_id:
-
/v1/chat/completions: adata:chunk with anerrorobject. -
/v1/responses: anerrorevent, with no[DONE]after it. -
/v1/messages: anerrorevent.
error before reading choices. On the other two, handle the error event. Treat it as a failed request. The most common in-stream error is insufficient_balance: your balance ran out mid-generation. You are billed only for the tokens received before the stop.
Error Codes
The code isdata.error_code on task endpoints and error.code on LLM endpoints. Codes are stable: a code’s meaning never changes, and new codes may be added. The messages next to them are examples and may be reworded. An error without a code is an internal failure; the HTTP status says all there is to say about it.
Authentication
Models and access
Request validation
Billing
Rate limits
Idempotency
These apply only when you send anIdempotency-Key header. The header makes a repeated request with the same key, body, and route return the original response instead of running again. Keys are scoped to the API key that sent them.
Upstream providers
Best Practices
Branch on the code
Use
error_code / code to decide what to do. Fall back to the HTTP status when there is no codeImplement Retry Logic
Retry with exponential backoff on 429, 500, and 503. Never retry 540 or 402
Log the request id
Log every error response with its
request_id. Support can trace a request by that id aloneCheck streams too
An error can arrive inside a
200 stream. Handle the error chunk or event like a failed request