PassingRight API Errors
How PassingRight returns errors in an OpenAI-compatible format on the OpenAI-compatible endpoints.
On the OpenAI-compatible endpoints, PassingRight 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 PassingRight; 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/videos) use the standard OpenAI error envelope:
{
"error": {
"message": "Unauthorized: PassingRight 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:
- 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).
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.
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. 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 PassingRight's own content filter, which runs the prompt (and any 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. PassingRight 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 PassingRight'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 PassingRight staff enable enterprise enforcement. If a legitimate request is blocked, email support@passingright.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