At a glance
Any other
4xx is the provider’s own error, passed through. See
Errors from the provider.
Error format
/v1/messages answers in the Anthropic shape. /v1/responses and /v1/embeddings answer in the
OpenAI shape. GET /v1/models follows the path you call: /anthropic/v1/models or
/openai/v1/models, and on the bare /v1/models, the Anthropic shape when the request carries
Anthropic SDK headers and the OpenAI shape otherwise.
type follows the status code: invalid_request_error for 400 and 422,
authentication_error for 401, permission_error for 403, not_found_error for 404,
rate_limit_error for 429, and api_error for 5xx. param and code are always null.
/v1/images/generations doesn’t use the OpenAI shape for errors yet. Its error
body is {"detail": ...}, with the message under detail. A guardrail block
there carries an object with the guardrail’s type, stage, and reason.Which check fails first
The gateway checks a request in this order and stops at the first failure, so this decides which error a caller sees when several apply:- API key (
401). - Model access (
403). - Usage limits (
429). - Input guardrails (
422). Embeddings skip guardrails. - Routing and the provider call. A setup problem returns
503, and the provider’s own errors pass through. - Output guardrails (
422), on responses that don’t stream.
401 Unauthorized
The key is missing, isn’t recognized, or has been disabled or deleted. The message starts withMissing API key. or Invalid API key. Send the sk-olga- key your operator gave you, as
Authorization: Bearer <key> or in the x-api-key header.
403 Forbidden
A model access rule refuses the model named in the request. The message says which kind of rule it was. A block rule:422 Unprocessable Entity
A guardrail blocked the request on its way in, or the response on its way out. The message is the guardrail’s reason, and it doesn’t name the guardrail or the stage:- PII:
Detected high-risk PII entities: US_SSN - Prompt injection:
Detected prompt injection attempt (score: 0.987) - Content safety:
Detected toxic content: insult=0.912 (threshold: 0.5)
429 Too Many Requests
A usage limit on your key, user, or group is reached. The message says when it resets:on November 1. An all-time limit
never resets, and says so:
Retry-After, and retrying fails the same way until the limit resets.
OpenAI and Anthropic SDKs retry a 429 automatically, so expect their retries to fail too. Ask your
operator to raise the limit.
A 429 with a different message is the provider’s rate limit, passed through. That one clears with
backoff.
503 Service Unavailable
The message tells you which cause you hit. Some clear on their own and carry aRetry-After
header; the others need your operator.
The routing rule covers embeddings and image generation routed to a provider that isn’t OpenAI or
Azure OpenAI, and embeddings matched by a model-based routing rule. The message names the rule’s
target and the change to make.
502 Bad Gateway and 504 Gateway Timeout
A 502 means the provider answered with a5xx error, or closed the connection without
answering. The message is the provider’s. A 504 means the provider didn’t answer in time. Both
are worth retrying with backoff.
400 Bad Request
Right after the API key check, the gateway rejects a few requests it can’t serve as sent:Streaming image generation is not supported.Send the image request withoutstream.- On
/v1/embeddings, a body that isn’t a JSON object or doesn’t name amodel.
Errors from the provider
The gateway passes a provider’s4xx errors through with the provider’s status code and message,
maps a provider’s 429 to 429, and maps any provider 5xx to 502. So a 403, 404, 422,
or 429 can come from the provider as well as from the gateway. The message tells them apart: the
gateway’s own messages are the ones quoted on this page.
The type is set from the status code, and the provider’s own error code, such as OpenAI’s
insufficient_quota, isn’t kept. The provider’s Retry-After header isn’t forwarded.
Streaming responses
A streamed request gets the same errors as any other, as long as they happen before the first event: every check before the provider call, and any error the provider answers with up front. Once events have started, the status is already200, so a failure partway through ends the stream early instead.
Find a request in the logs
Send anX-Request-ID header with each request. The gateway uses it in its logs and as the
Openlayer trace ID, so your operator can find the exact request behind an
error. When you omit it, the gateway generates an ID but doesn’t return it, so send your own if you
might need to trace an error.