Skip to main content

How Errors Arrive

Codex is a GraphQL API, so most errors come back in the errors array of an otherwise normal response — HTTP 200 with an errors key, not an HTTP error status. Only authentication and rate limiting fail at the HTTP layer.
If your error handling only inspects HTTP status codes, it will treat these as successful responses. Always check whether the body contains an errors array.

Which Errors to Retry

There is one field to watch: if an error carries extensions.retryAfterSeconds, wait that many seconds before retrying that request. On rate-limited responses the same value is also sent as the standard Retry-After header, so most HTTP client libraries will honor it without any code from you.

Rate limited

A TOO_MANY_REQUESTS error means you exceeded your plan’s per-second rate limit. When we can tell you exactly when the limit lifts, we do, via retryAfterSeconds and the Retry-After header. A 429 without retryAfterSeconds means your request budget is momentarily empty rather than your account being throttled — capacity typically returns within a second. Back off on your own schedule and retry; don’t retry immediately in a tight loop. See Rate Limits & Connection Limits for the limits themselves.

Over capacity

An OVER_CAPACITY error means the data your query needs is temporarily under more load than it can serve, and we’re scaling up. It is not caused by anything wrong with your request — the same query will succeed once you retry. These arrive as HTTP 200 with the error in the body. Retry after retryAfterSeconds (currently 30). Retrying sooner is likely to be throttled and slows the recovery for everyone.

Everything else

Unexpected errors return a generic message with an error code:
Don’t retry these automatically — the same request will usually fail the same way. Include that error code when you contact support or ask on Discord; it lets us find the exact failure in our logs.

Retry Strategy

Fixed retry intervals are the most common cause of prolonged rate limiting. If your interval is shorter than the penalty window, every retry lands inside it and extends the problem.
A retry policy that works well against Codex:
  1. Honor retryAfterSeconds whenever it’s present. It’s computed from the actual condition — it isn’t a guess, and it overrides whatever interval you’d otherwise use.
  2. Otherwise use exponential backoff with jitter. Jitter matters if you run multiple workers: without it they synchronize and retry in a thundering herd.
  3. Cap your retries. Three to five attempts is plenty; past that the condition needs attention rather than another request.
  4. Don’t retry non-retriable errors. Auth failures and malformed queries will fail identically every time.
If you’re hitting rate limits often enough that retry behavior matters, Optimization covers how to reduce request volume — usually the better fix.