OpenFill is in development. Inference is off, but is tested end to end, and will switch on at launch. All data currently on the site is for live testing: it will be erased at launch.

Skip to content
openfill

Errors and retries

A failed order is charged nothing, with one exception the 500 row names: a response that was produced and delivered but could not be completed. The codes below distinguish a problem you can fix from one you should retry, and each row says what was charged.

The error envelope

Chat, completions and Responses HTTP failures use the OpenAI error shape. Branch on code where it is set, and on type otherwise: the table below names which field carries the identifier for each status. Where a Retry-After header is sent it is in whole seconds. Every response carries an x-request-id header, which the OpenAI SDKs expose as _request_id; quote it when you write to us about a failure and we can find that exact request in the gateway log.

json
{  "error": {    "message": "no price limit set for model '<model_id>': every request needs one, and it is set per model. Pass price_limit (extra_body with the OpenAI SDK) or an X-Price-Limit header, or set a default for this model on the Bidding page (per key, or per account).",    "type": "invalid_request_error",    "param": null,    "code": "missing_price_limit"  }}

Status codes

StatusIdentifierMeaningChargedRetry
400
  • code missing_price_limit
  • code invalid_output_cap
  • code model_deprecated
  • code model_preview
  • code fixed_price_model
  • code unknown_model
  • code image_url_unfetchable
  • type invalid_request_error
Malformed request, no price set anywhere, a retired model, or a request the model itself refused. model_preview: a request to a preview of the market, which opens soon; its prices are simulated until then, and the fixed-price models run today. fixed_price_model: a market endpoint asked about a fixed-price model, or a price limit set for one on the account or a key. unknown_model: a model filter naming no served model. image_url_unfetchable: an image URL that could not be fetched, with the part it sits in and the reason in the messageNoNo, fix the request
401
  • type authentication_error
Missing, invalid or revoked API keyNoNo
402
  • code insufficient_balance
  • type insufficient_quota
Your available balance, after holds for orders already executing, cannot cover this request at the current clearing level, capped by the price you set, or at a fixed-price model's prices. A level of 0 needs no balanceNoAfter topping up, or when the level falls on a market model
403
  • type email_unverified
  • type authentication_error
Your account is not active: unverified, suspended, or deletion requestedNoNo
404
  • code model_not_found
  • code not_found
  • type invalid_request_error
The model is not available (model_not_found); no such order, file or batch (code null); or no such route (not_found). GET /v1/models lists the models servedNoNo, fix the request
408
  • type order_expired
An unlocked order on a market model waited out its timeout (max_wait, else your account's order timeout) without startingNoYes, with a higher price or a longer max_wait
409
  • type order_not_cancelable
  • type order_canceled
  • type idempotency_error
  • type batch_not_cancelable
  • type result_write_pending
  • type batch_in_progress
  • type file_in_use
The order is executing or already finished, so it cannot be cancelled; the original of an idempotent replay was cancelled; a result cannot be deleted yet because its write or its batch has not finished; or a file cannot be deleted while a batch is still working from itNoNo, except a result whose write has not landed, which carries Retry-After
410
  • type result_unavailable
The result is gone: nothing was stored (storage is off by default), its storage period has passed, or you deleted itAs the original wasNo. Use a new Idempotency-Key to execute again
413
  • type invalid_request_error
Request body over the size limit (8 MB)NoNo, split the request
429
  • code capacity_unavailable
  • code result_pending
  • type rate_limit_error
A rate limit or queue cap, a missed lock window (10 seconds), a request to a fixed-price model that did not start before its timeout, or result_pending while an already completed result is being storedNo new charge; result_pending keeps the original chargeYes, after Retry-After where one is sent. SDKs do this
500
  • type server_error
An error on our side. Where the response was already produced and charged the message says soRecorded or uncertain; inspect the message and usageYes, unless the response was produced
502
  • type server_error
The backend failed after part of a stream had been delivered. This one arrives inside the stream alone; no HTTP response carries itNoYes
503
  • code image_fetch_unavailable
  • type server_error
Backend unavailable, a deploy in progress, unavailable object storage, or a stored result that could not be read. image_fetch_unavailable: image URLs cannot be fetched right now, and the same image sent as a base64 data URL is acceptedNo new charge; a failed read keeps the original chargeYes, after Retry-After where one is sent

Two 429s mean different things. rate_limit_error is a ceiling on rate limits and clears with time. capacity_unavailable is a price-locked request that did not start inside its execute window, or a request to a fixed-price model that did not start before its timeout. A locked retry gets a fresh window at the standing quote, whose interval is published on the quote endpoint, and is never charged more than that quote; a fixed-price retry waits again at the model's prices.

The envelope on /v1/messages

POST /v1/messages answers every error in the Anthropic shape instead, {type: error, error: {type, message, code}}, with the same message and the same code as the rows above and the type from Anthropic's vocabulary. The Messages API page maps the two.

Retrying

DoStatusesHow
Retry with backoff429, 500, 503, and a 502 inside a streamHonour Retry-After where it is sent. The OpenAI SDKs retry 408, 409, 429 and every 5xx on their own with exponential backoff, honouring Retry-After; an in-band error is yours to retry.
Retry after a change402, 408Add credits, or wait for the level to fall; raise the price limit or the timeout.
Do not retry400, 401, 403, 404, 409, 410, 413The same request gets the same answer. Fix it, or use a new Idempotency-Key where the row says so.

A retry of an unlocked request re-queues it with a fresh deadline, so an SDK left on its default retries can wait several timeouts in a row. Set max_retries when you want a hard cutoff, and carry an Idempotency-Key so a retry can never run a successful request twice while that key remains valid.

Errors on a streaming request

A streaming request is answered 200 once its order is queued, and every failure after that arrives inside the stream in the wire's error event, with no status code and no Retry-After, so SDK retries do not engage. The streaming page has the frames.

Idempotency

Send an Idempotency-Key header of up to 255 characters on a chat or completion, Responses or Messages request to make retries safe. The key is scoped to your account, and a replay returns the original order's outcome rather than running it again. The work runs once and is charged once.

The original order isA replay gets
Still queued or executingThe same response, when it arrives. Chat and completions replay one chunk; Responses and Messages replay their event sequences. The replay waits without opening a stream, so its caller timeout still applies.
Done, with the result storedThe stored response, with the same usage and x_market.
Done, with nothing stored410 result_unavailable. Data storage is off by default, so this is the default after completion; use a new key to execute again.
Done, but its result is still being written429 result_pending with Retry-After. Retry with the same key.
Expired, failed or cancelledThe key is released, so the same key can run a new order. A replay arriving before release sees the original outcome; a persisted error can replay as 503.
Sent with different execution fields or price and wait headers409 idempotency_error. A key names one translated request. Native wires can replay after a change to an ignored or echo-only field.
Still being created429 with Retry-After of a second. The first request is between claim and insert.

Caution

Once the order has finished, a replay can only return the original response if the result was stored. Data storage is off by default, so a replay after completion returns 410 result_unavailable. Use a new key to execute again, or turn storage on in Settings.

A key lives for the longest of one day, your storage period, and the order's own lifetime plus an hour, so a replay always works for the full life of a queued order. The fingerprint covers the endpoint, the body, the X-Price-Limit and X-Expires-After headers, and the key's own price limit for the model.