LLM Gateway API Errors
How LLMGateway returns errors in an OpenAI-compatible format on the OpenAI-compatible endpoints.
On the OpenAI-compatible endpoints, LLMGateway returns errors in the same format as the OpenAI API, so existing OpenAI SDKs and tooling can parse gateway errors without changes. This applies to errors forwarded from upstream providers as well as errors raised by the gateway itself (authentication failures, usage limits, validation problems, timeouts, and so on). The Anthropic-compatible Messages endpoint (/v1/messages) instead returns Anthropic-native errors — see Anthropic Endpoint below.
Upstream rate limits are treated as provider errors and are eligible for retries and fallback. Rate-limit headers returned to clients describe only limits enforced by LLMGateway; upstream Retry-After and rate-limit headers are not forwarded.
Error Format
Errors on the OpenAI-compatible endpoints (/v1/chat/completions, /v1/embeddings, /v1/images, /v1/models, /v1/moderations, /v1/rerank, /v1/responses, /v1/search, /v1/videos) use the standard OpenAI error envelope:
{
"error": {
"message": "Unauthorized: LLMGateway API key reached its usage limit.",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key"
}
}| Field | Description |
|---|---|
error.message | Human-readable description of what went wrong. |
error.type | High-level error category (see the table below). |
error.param | The request parameter that caused the error, or null when not parameter-specific. |
error.code | A more specific machine-readable code, or null when no specific code applies. |
For normal JSON responses, the HTTP status code matches the error and is the authoritative signal — read it from the response status line rather than the body. The exception is an error arriving mid-stream, where the status is already 200 and the error must be read from the SSE event payload (see Streaming Errors).
Status Codes
For gateway-raised errors (authentication failures, usage limits, validation problems, rate limits, timeouts), the gateway maps HTTP status codes to OpenAI error types and codes as follows:
| Status | type | code |
|---|---|---|
| 400 | invalid_request_error | (varies / null) |
| 401 | invalid_request_error | invalid_api_key |
| 402 | invalid_request_error | billing_error |
| 403 | invalid_request_error | permission_denied |
| 404 | invalid_request_error | not_found |
| 408 | timeout_error | timeout |
| 410 | invalid_request_error | (varies / null) |
| 413 | invalid_request_error | request_too_large |
| 415 | invalid_request_error | unsupported_media_type |
| 429 | rate_limit_error | rate_limit_exceeded |
| 499 | invalid_request_error | request_cancelled |
| 504 | timeout_error | timeout |
| 529 | overloaded | overloaded |
| 5xx | api_error | (null) |
Validation errors raised before a request reaches a provider often include a
more specific code and a param pointing at the offending field — for
example invalid_json, model_not_found, or
unsupported_parameter_combination.
Upstream Provider Errors
Errors from the upstream provider follow different rules on the chat completions path. The status codes below apply to non-streaming requests; for streaming requests these same outcomes arrive as SSE error events on the already-open 200 response instead, while failures raised before the stream opens still return normal JSON — see Streaming Errors.
- Upstream 4xx client errors (a genuinely invalid request — any 4xx other than 401/402/403/404/405/429, or a 400 whose body signals a provider-side problem such as bad credentials, an exhausted provider account, or an unknown model — those are treated as provider-side failures) are passed through with their original status code. An already OpenAI-shaped error body is forwarded unchanged; bare provider shapes are wrapped in the OpenAI envelope with
typeandcodeset toclient_error(or the provider's own error type), and only these wrapped bodies carry extra diagnostic fields insideerror:requestedProvider,usedProvider,requestedModel,usedInternalModel, andresponseText. - Upstream provider/gateway-side failures (5xx, upstream 429/404, provider credential or funding problems) first go through automatic retry and fallback. If no provider succeeds, the gateway returns HTTP 500 with
type/codeofupstream_errororgateway_errorand the same diagnostic fields — the upstream status code is not passed through (it is recorded in the request log's error details). Some exhaustion paths instead return HTTP 502 withtypeupstream_errorandcodeall_providers_failed, without the diagnostic fields. - Connection failures and upstream timeouts return HTTP 502 (
upstream_error/fetch_failed) or HTTP 504 (upstream_timeout/timeout). - Provider content-moderation blocks (a recognized safety rejection, such as Azure's
ResponsibleAIPolicyViolationor a provider's content-policy403) are not returned as errors at all: the gateway returns HTTP 200 with a normalchat.completionwhose messagecontentisnulland whosefinish_reasonis"content_filter"(on streaming, a chunk carrying that finish reason). Usage covers the prompt tokens, and the request is not logged as an error.
Blocked Accounts
When an administrator blocks an account, gateway requests return HTTP 410.
If a reason was provided, it appears in error.message. The same reason is shown
when affected members try to sign in (HTTP 403) and in authenticated API errors.
Older blocks and blocks without a reason retain the generic error message.
Blocking also signs out all members and cancels the organization's subscriptions.
Re-enabling the organization does not reactivate its members or restore subscriptions.
Rejected Request Logs
Rejected inference requests with a recognized API key are recorded in request logs, including account review or disabled-account errors, billing restrictions, and rate or concurrency limits. These rejections have no inference or storage charge. Requests rejected before body parsing may have an unknown model and no request payload. Unrecognized or missing keys cannot be attributed to an organization and are not recorded.
Logs include a nullable errorCategory for distinguishing account restrictions,
authentication, permissions, billing, rate limits, concurrency limits, validation,
guardrails, upstream failures, and gateway failures. Older rows may have no category.
The dashboard shows Error Category beside the finish reasons in expanded activity
cards and full log details when a category is available. Payload retention settings
still apply. This metadata does not enable alerts.
Streaming Errors
For streaming requests ("stream": true), an error that occurs after the stream has started is delivered as an SSE error event whose payload uses the same { "error": { ... } } envelope. Because the HTTP status is already 200 at that point, read the error from the event payload; its type/code values are gateway-specific (for example upstream_timeout/timeout, upstream_error/all_providers_failed, or gateway_error) rather than the status-code table above, and param may be absent. An upstream 4xx client error arrives the same way, with the provider's error body in the event payload, normalized under the same rules as the non-streaming pass-through: an already OpenAI-shaped body is forwarded unchanged, and bare provider shapes are wrapped in the OpenAI envelope. Errors that occur before streaming begins (such as authentication failures) are returned as a normal JSON error response with the appropriate status code.
Gateway Content Filter
Requests routed to some providers may be screened by LLM Gateway's own content filter, which runs the prompt (and, where enabled, image inputs) through a moderation model before the request reaches the provider. The filter runs on a sample of requests and its strictness follows your organization's trust tier: tiers 0–2 use strict thresholds, tiers 3–4 lenient ones. LLM Gateway staff can pin an organization's content filter tier independently of its trust tier.
By default the filter only records its findings. When blocking is active, a request over its tier's thresholds is rejected before dispatch and the response makes clear that the gateway filter, not the provider, stopped it:
- Chat Completions (and the Responses endpoint): HTTP
200withfinish_reason: "content_filter". The assistant message content explains that the request was blocked by LLM Gateway's content filter and how to contact support. Streaming responses send one chunk carrying that content and finish reason, then[DONE]. - Messages (
/v1/messages):stop_reason: "refusal"with the same explanation as the text content. - Images: HTTP
200with an emptydataarray. - Videos: HTTP
403with the explanation inerror.message; no job is created.
A moderation outage never fails a request: if the moderation model is unavailable, the request goes through as normal.
An occasional block is not a problem. From October 15, 2026, a high rate or volume of content filter violations can get the account rate-limited, restricted, suspended, or terminated at our discretion — see Section 6 of the Terms of Use.
Enterprise organizations are exempt from blocking by default; they are only ever blocked if LLM Gateway staff enable enterprise enforcement. If a legitimate request is blocked, email contact@llmgateway.io so we can review your use case against the Terms of Use and help you get unblocked.
Anthropic Endpoint
The Anthropic-compatible Messages endpoint (/v1/messages) returns errors in Anthropic's native format instead, so the Anthropic SDK can parse them:
{
"type": "error",
"error": {
"type": "authentication_error",
"message": "Unauthorized: invalid API key."
}
}Related
- Rate Limits — details on
429responses and rate limit headers.
How is this guide?
Last updated on