failed or timed_out reports why through its error_code; see Read how the run ended.
Error object
Every error response carries the same envelope: amessage that summarizes what went wrong, and a detail array with one entry per problem:
Error envelope
detail entry keeps the failing field’s path and reason, and message flattens them into a single line:
Validation error (422)
message when you just need something to log or display; reach into detail when you need per-field specifics. Requests rejected before they reach the API (for example a missing or invalid key, 401) may carry only a message.
HTTP status codes
Success codes
Client error codes
Server error codes
Handling errors with the SDK
The SDKs raise a typed error on any non-2xx response (carrying thestatus_code / statusCode and parsed body) and return the parsed model on success, so you never narrow a data | error union by hand:
408, 429, and all 5xx) with backoff automatically, twice by default. Tune it with max_retries (Python) / maxRetries (TypeScript) on the client, or per call via request options. Calling the API directly? Retry those same codes with backoff, honoring Retry-After when present. Over-quota session creates don’t need retry logic at all: they queue by default and start on their own as slots free up.
Do not retry 400, 401, 402, 403, 404, or 422 errors: they signal a problem with the request itself, and the same request will fail the same way. Fix the request instead.