Skip to main content

Error shape

Chat Completions, Responses and every non-chat endpoint return the OpenAI shape:
/v1/messages returns the Anthropic shape:
message is text for people, and NagaAI can change it. Decide in code by the HTTP status first, then by error.type or error.code. code and param are missing or null on many errors. On /v1/messages, error.type uses Anthropic’s names by status, such as authentication_error, billing_error and rate_limit_error, and there is no code. Every response from an API endpoint, error or not, carries an x-request-id header. Include it when you contact support.

Where an error comes from

Your request. NagaAI checks the request before it picks a provider. A missing field, a wrong type or an image sent to a text-only model fails here with 400 and a message such as body.messages.0.content: .... Fix the request and send it again. A provider that could not serve it. On a timeout, a 5xx, a rate limit or an exhausted provider quota, NagaAI moves the request to another provider, up to three attempts. If every attempt fails you get 503 with a generic message, and NagaAI does not charge the request. A provider’s content filter. You get 400 with the message Request rejected by upstream content moderation. and, in the OpenAI formats, code: "content_moderation". Change the content, or try another model. A provider that rejected a request NagaAI accepted. You get 400 with the provider’s text after Upstream returned an error: . This is a bug in NagaAI’s conversion, not in your request. Report it with the x-request-id.

Status codes

Retry-After holds seconds. It comes with 429 and with some 503 responses.

Errors in a stream

NagaAI holds back the HTTP status until the first piece of content is ready. If every provider fails before that point, you get a normal error response with one of the status codes listed under Status codes. After content has started, the status is already 200, so an error arrives inside the stream: NagaAI does not charge a stream that fails midway, so a retry costs only the new request.

Retry pattern

The OpenAI and Anthropic SDKs already retry 408, 409, 429 and 5xx twice by default and read Retry-After. Raise max_retries (Python) or maxRetries (Node.js) instead of writing a loop, unless you need custom backoff. A request your client gave up on can still finish at NagaAI and be charged. Retrying it after a client timeout can charge twice, so set the client timeout above your longest expected answer.