Errors
Every error uses the OpenAI envelope, so existing client error handling works unchanged.
{
"error": {
"message": "insufficient credits",
"type": "insufficient_quota",
"code": null,
"param": null
}
}
| Field | Type | Required | Description |
|---|---|---|---|
error.message | string | optional | Human-readable description. |
error.type | string | optional | Stable machine code (see table below). |
error.code | string | null | optional | Finer-grained code where applicable. |
error.param | string | null | optional | Offending request field, if any. |
Status codes
| HTTP | error.type | Meaning |
|---|---|---|
| 400 | invalid_request_error | Malformed body, unknown/unsupported model, bad params. |
| 401/403 | authentication_error / permission_error | Missing, invalid or disallowed key. |
| 402 | insufficient_quota | Not enough prepaid credits. Top up in billing. |
| 429 | rate_limit_error | RPM or TPM limit hit. Back off and retry. |
| 500 | server_error | Unexpected server error. |
| 503 | service_unavailable | No healthy execution route is available. Retry. |
Handling
- Retry
429,500,503with exponential backoff + jitter; SDKs do this by default. - Don’t retry
400,401,402,403— fix the request, key or balance first. - Inspect the HTTP status and
error.type, not the prose inerror.message, for branching.
POST /v1/messages uses the Messages-style { "type": "error", "error": { ... } }
envelope documented on the Messages reference.
See also Rate limits, caps & scopes.