Skip to content

API reference

Errors

Errors come back in the shape of the API you called, with a stable code, so your SDK raises the exception it already knows how to handle and your code can tell a typo from a busy model.

Error shapes#

The OpenAI-compatible endpoints put the code in both error.code and error.type; the Anthropic-compatible ones use Anthropic's error.type. The HTTP status is the same either way.

{  "error": {    "message": "The model `gpt-4o` does not exist or is not available.",    "type": "model_not_found",    "code": "model_not_found",    "request_id": "req_64c97dcaee881c19a0187fae"  }}

Request IDs#

Every response from /v1, successful or not, carries an x-request-id header like req_b7fc216b3c39b963328f4ff1. Error bodies repeat it as request_id: inside error on the OpenAI-compatible endpoints, at the top level on the Anthropic-compatible ones (where Anthropic puts its own). The same ID shows when you open the call's row in Logs.

Log it with your errors, and include it when contacting support: it finds the exact call. The SDKs' errors keep the response headers, so it's there in Python as error.response.headers["x-request-id"].

Error codes#

StatusCode (OpenAI)Type (Anthropic)What happenedWhat to doRetry
400invalid_request_errorinvalid_request_errorThe body is malformed, or the model rejected a field. The message says which.Fix the request; the same request fails the same way.No
400invalid_model_kindinvalid_request_errorThe model is another kind than the endpoint serves: an embedding model at chat completions, say.Call chat models at /v1/chat/completions or /v1/messages, embedding models at /v1/embeddings and rerankers at /v1/rerank.No
401invalid_api_keyauthentication_errorNo key, an unknown key, or a revoked one.Check the header and the key on the API keys page.No
401key_expiredauthentication_errorThe key passed its expiry date.Create a new key and switch your app over.No
401project_archivedauthentication_errorThe key's project was archived, which revoked its keys.Create a key in another project.No
402insufficient_quotabilling_errorYour prepaid balance is empty and this month's plan allowance is used up.Add credit, turn on auto top-up, or upgrade your plan.Later
403account_suspendedpermission_errorThe account is suspended.Email support.No
403model_not_allowedpermission_errorThe key is locked to other models.Use an allowed model, or change the key's model list.No
403ip_not_allowedpermission_errorThe key only accepts certain IP addresses, and this wasn't one.Call from an allowed address, or add this one to the key.No
404model_not_foundnot_found_errorNo live model has that ID (or it was retired).Check the ID against GET /v1/models.No
429rate_limit_exceededrate_limit_errorToo many requests this minute for the key on this model, or for the account.Wait for retry-after, then retry with backoff.Yes
429key_limit_reachedrate_limit_errorThe key hit its monthly spend cap.Raise the cap on the API keys page, or wait for the new month.Later
429project_budget_reachedrate_limit_errorThe key's project hit its monthly budget.Raise it under Developers → API projects, or wait for the new month.Later
502upstream_errorapi_errorThe model's host failed or couldn't be reached. You aren't charged.Retry after a moment.Yes
503overloadedoverloaded_errorThe model is at capacity right now. You aren't charged.Retry with exponential backoff.Yes
504upstream_timeoutapi_errorThe model didn't start answering within 60 seconds.Retry; if it keeps happening, try another model.Yes

Refused calls (anything before the model runs) are never charged. Messages are written for people and may change; branch on the status and code, not the text.

Which errors to retry#

  • Retry with backoff: 429 rate_limit_exceeded (after retry-after), 502, 503 and 504. The OpenAI and Anthropic SDKs already do this (twice by default). A backoff example is on Rate limits.
  • Retry after a change: 402, key_limit_reached and project_budget_reached clear when credit is added, a cap is raised, or the month (UTC) turns.
  • Don't retry: 400, 401, 403 and 404 fail the same way until the request or the key changes.

Before you ever see a 502 or 503, FullsendAI has already retried a busy model once and, for models with a backup host, moved the call there at the same price (see Automatic failover). Live and past uptime per model is on the status page.

Errors during a stream#

An error before the first token is an ordinary JSON error with its status. Once a stream has started the status is already 200, so if the model goes quiet for 60 seconds the stream ends with an error event instead, and you're charged only for what was sent:

data: {"error":{"message":"The model stopped answering for 60 seconds, so the answer was cut off.","type":"upstream_timeout","code":"upstream_timeout"}}

Finding failed calls#

Every call, refused ones included, is listed in Logs with its status, code, message, key, model and the calling app and IP address. A stream you stopped yourself shows as Stopped (status 499), charged only for what was generated. Open a call to see its request ID, with a button to copy it. Turn on body logging for a project to see the exact request and reply (how).

Stuck? Email [email protected]System statusChangelog