Errors and limits

Every HTTP error code, the failed and cancelled response states, headers, rate limits and the retry policy.

HTTP errors

A refused request answers with OpenAI's error object and no envelope:

JSON
{ "error": { "message": "...", "type": "invalid_request_error", "param": null, "code": "invalid_request" } }

param names the offending field when there is one. Branch on code, never on message.

HTTPtypecodeWhen
400invalid_request_errorinvalid_requestThe body is invalid; param names the field
400invalid_request_errorunsupported_parameterprevious_response_id, conversation and similar
400invalid_request_errorunsupported_jurisdictionX-Jurisdiction holds us, oecd, ifrs or an unknown code
400invalid_request_erroridempotency_key_reusedThe same Idempotency-Key with a different request
401authentication_errorinvalid_api_keyThe key is missing, unknown, revoked or expired
402billing_errorinsufficient_creditsThe balance cannot cover the request, or there is no account
402billing_errorspend_cap_reachedThe key's monthly spend cap is reached
403permission_erroraccount_suspendedThe account is suspended
404not_found_errornot_foundUnknown response, or one that belongs to another key
409invalid_request_erroridempotency_key_in_useThe same key is still being processed
409invalid_request_errorresponse_finishedCancel on a response that has ended
429rate_limit_errorrate_limit_exceededThe requests-per-minute limit
429rate_limit_errorconcurrency_limit_exceededThe in-progress responses limit
500server_errorserver_errorAnything else; never exception text
503server_errorledger_unavailableThe balance cannot be checked right now, so the API refuses rather than run unbilled

A failed or cancelled response

A response that fails or is cancelled is not a refused request. It answers 200 and keeps the Responses envelope, with status and error: {code, message}:

error.codeMeaning
invalid_promptThe turn was declined: the question is outside what the service answers. Change the question
server_errorThe run could not produce an answer
cancelledYou cancelled the response

These are terminal states. Sending the same turn again reaches the same result, so they are not retried as such. Failed and declined runs are free (see Pricing).

Answers outside the error object

Two answers come from the layers around the API and are not in the error shape. Each carries x-request-id.

  • A request that matches no route, such as an unknown path under /v1 or a method the path does not accept, answers 404 or 405 with {"detail": "..."}.
  • A body over 256 KiB answers 413. It is the plain text Content Too Large when the request declares its Content-Length, and {"detail": "Content Too Large"} for a chunked body.

A request for an unknown response id on a known route is the exception: it is 404 not_found in the error object.

Headers

HeaderMeaning
x-request-idreq_ plus 32 lowercase hex characters, on every /v1 request including errors. Quote it when you contact support
Retry-AfterWhole seconds, on every 429 and 503
x-ratelimit-limit-requestsThe requests-per-minute limit
x-ratelimit-remaining-requestsRequests left in the current window
x-ratelimit-reset-requestsTime until the window resets, in OpenAI's duration form (1s, 6m0s)

Rate limits

Limits are per key and depend on its mode. Requests are counted in one-minute windows; in-progress responses are counted from creation until the response ends.

KeyPOST /v1/responsesIn-progress responsesLookups
Live60 per minute10600 per minute
Sandbox10 per minute260 per minute

Past the per-minute limit the answer is 429 rate_limit_exceeded. With the in-progress count at its limit it is 429 concurrency_limit_exceeded; nothing is reserved or charged for either.

Retry policy

  • Retry 429 and 503 after the Retry-After seconds. Retry 500 too, with a short backoff.
  • Always reuse the same Idempotency-Key on the retry. A retry without Idempotency-Key is a new, charged request (see Responses).
  • Never retry 400, 401, 402 or 403. The same request fails the same way; fix the request or the account first.
  • Stop after a few attempts. The quickstart samples make at most 3.

On this page