Safeguard Docs
API Platform (Console)

Errors

Every status and error code the inference API returns, the error body, Retry-After, the order checks run in, and which errors to retry.

The error body

Errors from the inference API use OpenAI's shape:

{
  "error": {
    "message": "Not enough credit for this request. Add credit in the Console, or lower max_tokens.",
    "type": "insufficient_quota",
    "code": "insufficient_credit",
    "param": null
  }
}
  • code is the field to branch on. It is stable; the message wording may change.
  • type follows the status: invalid_request_error for 400, 404 and 413, authentication_error for 401, insufficient_quota for 402, permission_error for 403, rate_limit_error for 429, and api_error for 5xx.
  • param names the offending field when there is one, such as model or messages[0].content.
  • Messages are written by Safeguard. A provider's own error text is never copied into them; a provider failure is described by its HTTP status only.
  • An error returned after the gateway accepted the request and called a provider also carries an X-Generation-Id header with the request's id (gen-…), because the request is in the request log. A refusal before that, such as a 401, 402 or 429 rate_limited, has no request id. X-Request-Id is a different, internal id for Safeguard's audit trail.

The OpenAI SDKs turn these into their usual exceptions, with the status code and this body.

Every status and code

StatuscodeWhenRetry?
400invalid_requestThe body is not valid JSON or not an object, or a field is missing or out of range, such as an unknown role, temperature above 2 or more than 2,000 messages. Also a custom: model that cannot be used.No. Fix the request.
400unsupported_parameterA message part that is not text, n other than 1, or a custom: model sent with an API key. Also a routing field (models, provider.order, only, ignore, sort) where routing is not switched on, or on an embeddings request; and the completions fields that are not supported. param names the field.No.
400upstream_rejectedThe provider refused the request: it answered 400, 404, 413 or 422.No. Change the request.
401invalid_api_keyThe key is missing, malformed, unknown, revoked or expired, or its owner can no longer use it.No.
402insufficient_creditThe workspace's available credit does not cover the most this request could cost, or the balance is at or below zero.After credit is added, or with a lower max_tokens.
402key_spend_limit_exceededThe request would take the key past its monthly spend limit.After the key's limit is raised, or next month.
402account_spend_limit_exceededThe request would take the workspace past its monthly spend limit.After a tenant admin or super admin raises it, or next month.
403gateway_disabledThe API Platform is not switched on for this workspace, or the endpoint you called (embeddings, completions) is not.No.
404model_not_foundmodel is not in the catalog.No.
413request_too_largeThe request body is larger than 8 MiB.No.
429rate_limitedThe key reached its requests-per-minute limit. Retry-After says how many seconds to wait.Yes, after Retry-After.
429upstream_rate_limitedThe provider is rate limiting the gateway. Retry-After is 5.Yes, after Retry-After.
500internal_errorThe gateway failed unexpectedly.Yes, with backoff.
502upstream_errorThe provider returned an error, could not be reached, or its stream broke.Yes, with backoff.
502upstream_authThe provider refused Safeguard's own credentials.Later. Tell Safeguard if it persists.
503model_unavailableThe model cannot be called through the API: it has not passed the launch checks, or zero data retention was required and the model does not offer it, or the model catalog could not be read.Only the catalog case clears by itself.
503auth_unavailableSafeguard could not check API keys at that moment.Yes, after a short wait.
503billing_unavailableSafeguard could not check credit at that moment. The gateway refuses rather than serve a request it cannot meter.Yes, after a short wait.
504upstream_timeoutThe provider did not answer in time, or a stream ran past 900 seconds.Yes, with backoff.

Two answers do not use this body, because they come from the API's router before the gateway's code runs: a path the API does not serve, such as /embeddings, returns 404 with {"detail": "Not Found"}, and a wrong method, such as GET /chat/completions, returns 405 with {"detail": "Method Not Allowed"}.

The messages you will see most

codemessage
invalid_api_keyInvalid, revoked or expired API key. Keys start with sg-api- and are sent as 'Authorization: Bearer <key>'.
gateway_disabledThe Safeguard inference API is not enabled for this account.
insufficient_creditNot enough credit for this request. Add credit in the Console, or lower max_tokens.
key_spend_limit_exceededThis API key's monthly spend limit would be exceeded.
account_spend_limit_exceededYour account's monthly spend limit would be exceeded.
rate_limitedToo many requests for this API key (limit 60 per minute). The number is the key's limit.
model_not_foundModel not found: <id>
model_unavailableModel <id> is not available: it is not available through the API yet. Or: zero data retention is not offered for it.
unsupported_parameterOnly text content is supported (got 'image_url'). Or: Only n=1 is supported.

Retry-After

Two errors carry a Retry-After header, in whole seconds:

  • 429 rate_limited: the time until your oldest counted request leaves the 60-second window. A refused request is not counted, so a retry after that wait goes through.
  • 429 upstream_rate_limited: always 5.

The order of the checks

The gateway checks a request in this order and answers with the first problem it finds:

  1. The key (401), then whether the API Platform is on for the workspace (403).
  2. The body: size (413) and fields (400).
  3. The key's requests per minute (429 rate_limited).
  4. The model: known (404) and callable (503).
  5. Credit and spend limits for the most the request could cost (402).
  6. The provider call (400 upstream_rejected, 429 upstream_rate_limited, 502, 504).

A request refused at steps 1 to 5 never reaches a provider and costs nothing.

Errors during a stream

Once a stream has started, the status is already 200, so a failure arrives as an event in the stream instead:

data: {"error": {"message": "The provider stream ended with an error.", "type": "api_error", "code": "upstream_error", "param": null}}

It is followed by the usage chunk, if you asked for one, and data: [DONE]. See Streaming.

How to retry

  • Retry 429 after Retry-After. Retry 500, 502, 503 auth_unavailable, 503 billing_unavailable and 504 with exponential backoff and a cap on attempts.
  • Do not retry the other 4xx errors unchanged; they will fail the same way.
  • Each retry is a new request with a new request id. A retry that reaches a provider and gets an answer is billed like any other request.
  • When your workspace or request allows fallbacks, the gateway already retries a failed provider call once before it answers with an error. See Reliability and fallbacks.

Troubleshooting walks through the common cases and their fixes.

On this page