Build with the API

Errors and how to handle them

A call that succeeds is answered 200. A call that is refused or fails is answered with another status and a JSON object that says what happened. Quote the x-request-id response header when you ask support about a call.

The error object#

On every route except /v1/messages, the body is this error object, which OpenAI's clients read as their own:

json
{
  "error": {
    "message": "the account does not have enough credit for this request",
    "type": "insufficient_quota"
  }
}
  • message says what to change, in words.
  • type is the kind of error, for code to branch on.
  • code is present where a refusal has a more specific cause, such as which limit was reached.
  • param is present on a 400 and names the request field at fault.

/v1/messages answers in the form Anthropic's clients read instead, {"type": "error", "error": {"type": "...", "message": "..."}}. See Using Anthropic's client.

Statuses#

StatusTypeWhenWhat to do
400invalid_request_errorThe request is malformed, sets a parameter the model does not accept (param names it), or carries a conversation longer than the model can take.Fix the request. Retrying it unchanged fails again.
401authentication_errorNo key, or a key that is unknown, expired or removed.Send a valid key.
402insufficient_quotaYour credit, the key's spending limit or the account's monthly budget does not cover what this call could cost. code is key_spend_limit or monthly_budget when a limit refused it, and absent when credit ran out.Add credit or raise the limit. Retrying does not help until you do.
403permission_errorThe key is restricted to other models, or the model may keep data and sharing data with it is not allowed: code is data_sharing_not_allowed (the person can allow it) or data_sharing_forbidden (their organisation does not allow it).Use a model the key may call or one that keeps no data, a different key, or allow the model under Settings, Models.
404model_not_foundThere is no such model, or it has no price and is not for sale.Take an id from the model list.
404not_found_errorOn /v1/invocations and /v1/files: no such file or conversation for this key. A file of another conversation answers the same.Use a file reference an earlier answer gave this key.
409idempotency_errorA call with this Idempotency-Key is still running, or it finished and its stored answer is gone.Wait and retry, or send a new key. See Safe retries.
410goneThe file is no longer kept.Make it again.
413invalid_request_errorThe request body is past the size limit.Send less.
429rate_limit_errorToo many calls per minute or at once, or the model is busy. code is key_rate or workspace_concurrency when a limit refused it.Wait the seconds in the Retry-After header. See Rate limits.
500server_errorSomething failed inside the service. The response says nothing about how.Retrying is safe but may fail again.
502upstream_errorOn /v1/invocations: the model delivered something other than it said, or too much of it. Nothing was kept or charged.Retry, or choose another model.
503server_errorThe model is temporarily unavailable, or a model is not for sale right now.Retry shortly.
507storage_fullOn /v1/invocations: the storage quota of the person whose file the result would be is full. Nothing ran and nothing was charged.Delete files or chats under Settings, Storage, then retry.
529overloaded_errorOn /v1/messages only: the model is temporarily unavailable.Retry shortly.

On /v1/messages the types are the ones Anthropic's clients expect, for the same statuses: invalid_request_error, authentication_error, billing_error (402), permission_error, not_found_error, request_too_large (413), rate_limit_error, api_error (500) and overloaded_error, which is status 529 instead of 503.

Errors in the middle of a stream#

A streamed call that has started is already 200. If it fails after that, the failure arrives as an event and the stream ends. See Streaming.

Handle them in code#

Retry what is temporary, with a pause that grows (the Python example honours Retry-After), and stop on what a retry cannot fix.

import os
import time
import openai
from openai import OpenAI

client = OpenAI(base_url="https://sven.swedishembedded.com/v1", api_key=os.environ["SVEN_API_KEY"], max_retries=0)

def ask(question: str, attempts: int = 5) -> str:
    for attempt in range(attempts):
        try:
            reply = client.chat.completions.create(
                model="MODEL_ID",
                messages=[{"role": "user", "content": question}],
            )
            return reply.choices[0].message.content
        except openai.APIStatusError as error:
            retryable = error.status_code in (429, 500, 503)
            if not retryable or attempt == attempts - 1:
                raise
            wait = float(error.response.headers.get("retry-after", 2**attempt))
            time.sleep(wait)
    raise RuntimeError("unreachable")

If a retry could run a call twice, send an Idempotency-Key so it cannot be charged twice. See Safe retries.