Status codes

On 403 for bad keys. A rejected API key currently returns 403, not 401. If your client refreshes credentials on 401, it will not fire. Treat 401 and 403 together as “auth failed”. We intend to move invalid keys to 401 with a WWW-Authenticate header; the change will be announced before it ships.

Error body shapes

Not every endpoint returns the same shape yet. Write your parser to tolerate all of them. 1. Plain message
2. Structured, on quota and limit errors
3. Validation errors
A defensive extractor looks like this:
4. Top-level error, on 501 from account and billing routes
We are consolidating on shape 2 ({"error", "message"}) across every endpoint. The others will remain available for one release after that lands.

Machine-readable codes

These codes appear on quota, credit, and concurrency errors:

WebSocket close codes

Retrying safely

Retry 429, 502, and 504 with exponential backoff and jitter. Do not retry 4xx otherwise.
When retrying a create, send an Idempotency-Key so a retry after a timeout cannot leave you paying for two sessions.

Request IDs

Every response carries X-Request-ID. Include it when contacting support.