Skip to content

Errors

Status codes, the error body, and which failures are worth retrying.

Errors come back as JSON with the status code that matches:

json
{
  "error": {
    "type": "insufficient_credit",
    "message": "The organization's balance cannot cover this request."
  }
}

Status codes

Code Type Retry?
400 invalid_request No — fix the body
401 invalid_api_key No — the key is wrong or revoked
402 insufficient_credit After topping up
404 model_not_found No — check the catalogue
408 timeout Yes, with backoff
429 rate_limited Yes, honour Retry-After
5xx upstream_error Yes, with backoff

What is charged

A request that fails before the provider generated anything costs nothing.

A request that fails partway — a stream that dropped, a timeout after the first tokens — is charged for what was generated, because the provider generated it. Those rows appear in Usage with a non-ok status and a real cost.

Retrying

Exponential backoff with jitter, and a ceiling. Retrying a 429 immediately is how a rate limit becomes an outage.

Do not retry a 400 or a 401. Neither will succeed the second time, and both usually mean a deploy shipped something wrong.

402 is a runway problem, not a request problem. If you are seeing it, auto-reload is the fix rather than a retry loop.