ORYNX

Errors

Status codes, error shapes per API format, and when to retry.

ORYNX returns errors in the format of the API you called, so your SDK raises its usual exception types. Every response carries an x-request-id header (req_...). Include it when you report a problem.

Status codes

StatusMeaningRetry?
400The request is invalid: bad JSON, no model, a model this route doesn't serve, or a provider rejection such as a prompt that is too long.No, fix the request.
401The key is missing, malformed, unknown, disabled, revoked or expired.No.
403The key may not use this model, or the calling IP is not on the key's allowlist.No.
404Unknown model or route, or a token counting endpoint.No.
413The request body is larger than 50 MB.No.
429A rate or concurrency limit, credit held by your own running requests, too many failed key attempts from your IP, or a busy model.Yes, after Retry-After.
500, 502, 503, 504ORYNX or the model provider failed, or the model took too long.Yes, with backoff.

A key that is out of credit gets 429 (400 on the Anthropic format) with no Retry-After. Don't retry it; the request can't succeed until the key is topped up.

Out of credit

When a key has no credit left, each format gets the error its clients expect:

  • OpenAI (Chat and Responses): 429 with type and code insufficient_quota.
  • Anthropic: 400 with type invalid_request_error and a message that the credit balance is too low. The Anthropic API answers the same way, so Claude Code shows the error instead of retrying.
  • Gemini: 429 with status RESOURCE_EXHAUSTED.

If the credit runs out while a response is streaming, the stream ends with an error of the same type.

Before a request starts, ORYNX sets aside the most it can cost: its input plus the full output cap (max_tokens, or the model's maximum output when you send none). Unused credit returns to the key as soon as the request finishes. This means:

  • When the key can't cover the full output cap, the request still runs, with a smaller cap that the key can pay for.
  • Attachments count at their largest possible size (a PDF by its page count). Input the request doesn't carry itself, such as previous_response_id or Gemini cachedContent, counts at the model's full context window. A key with a small balance may get the out-of-credit error for such a request.
  • If your own parallel requests have already set aside all the remaining credit, a new request gets a 429 rate-limit error with Retry-After: 2. Retry it once they finish. Claude Code, Codex and the OpenAI and Anthropic SDKs retry it automatically.

Error shapes

{ "error": { "message": "Rate limit reached for this API key. Please slow down.", "type": "rate_limit_error", "param": null, "code": "rate_limit_exceeded" } }

Errors after a response has started

Once a stream has started, the HTTP status is already 200, so a failure arrives as the last event:

  • OpenAI Chat: a data: {"error": {...}} line.
  • Anthropic: an event: error event.
  • Responses: a response.failed event.
  • Gemini: an error object as the last data: line, or as the last element of the JSON array.

The same applies to a non-streaming request that runs longer than 30 seconds: ORYNX has already sent status 200, so check the JSON body for an error field. Treat a stream that ends without a finish reason as failed, and retry.

Provider messages

Errors that come from the model provider, such as "prompt is too long" or thinking-block validation errors, keep their original wording, so tools like Claude Code and Codex can react to them.

On this page