Error codes

Every error code with its HTTP status, fixed message and what to do; 402 versus 429; the three error formats.

When a request fails, the HTTP status and code tell you what happened. Match on code, not on the message text.

Error formats

OpenAI-format and query endpoints return the OpenAI error object, /v1/messages returns Anthropic's and the Gemini endpoints return Gemini's. The examples below show the same 500 upstream_timeout in all three.

OpenAI
{
  "error": {
    "message": "Model processing timed out.",
    "type": "api_error",
    "param": null,
    "code": "upstream_timeout"
  }
}
Note

The Gemini format has no code field: use the HTTP status and status. Every response, success or error, carries an x-robi-request-id header; include it when you contact support.

All error codes

Fixed messages are exact English sentences. Other messages may change and are only meant for people to read.

HTTPcodeFixed messageWhenWhat to do
400invalid_requestThe request was rejected by the model as invalid.A parameter is invalid. If the model rejected it, the message is this sentence, or Invalid value for parameter <param>. with param set.Fix the request; do not retry it unchanged.
400unsupported_parameterVariesThe request uses something Relayvia does not offer: stored server-side state, a hosted tool or a remote file. param names it.Remove the field or send the content inline; see the differences on each endpoint's page.
400invalid_mediaUnsupported input media format.The model reports that an input image or file format is not supported.Convert it to a supported format.
400media_unreachableUnable to access the input media URL.The model could not read the media URL you sent.Make sure the URL is public, or send the media inline.
400content_policyInput content did not pass safety review.The input did not pass the model's safety review. If the model does not say whether the input or the output was refused, the message is Content did not pass safety review.Change the input; the same input fails again.
400content_policy_outputGenerated content did not pass safety review.The model generated a result, but the result did not pass safety review. Your input was not the problem.Rephrase the request or adjust parameters, then try again.
401invalid_api_keyVariesThe API key does not exist, is disabled or has expired.Check the key in the console, or create a new one.
402insufficient_quotaVariesNot enough credits: the account's credits, the key's limit, the team member's limit or an account spend limit cannot cover the request, or the account is frozen.Top up or raise the limit; retrying does not help.
403forbiddenVariesThe key may not use this model, the source IP is not on the allowlist, or the account is disabled.Check the key's allowed models and IP allowlist.
404model_not_foundVariesThe model is not listed.Use a name from GET /v1/models.
404not_foundVariesThe path does not exist, for example a base URL with /v1 added twice.Check the base URL and the path; see Authentication.
413request_too_largeThe input exceeds the model's limit.The request body is over 20 MB, or the model reports that the input exceeds its context or size limit (then with this sentence).Shorten or split the input.
429rate_limitedVariesToo many requests: per IP, per key, per account, or too many requests in progress at once.Wait the seconds in Retry-After, then retry.
500model_price_errorVariesThe model has no price yet, so it cannot be called.Choose another model or contact support.
500internal_errorVariesSomething went wrong inside Relayvia; the details are only in our logs.Retry later; if it keeps happening, contact support with the x-robi-request-id.
500upstream_errorModel service is temporarily unavailable.Relayvia tried other model services and every attempt failed.Retry later with backoff; the request was already retried, so do not retry in a tight loop.
503no_available_channelVariesNo model service is available for this model right now.Retry later or choose another model.
503service_busyThe service is currently busy.Every model service for this model reported being busy.Wait the seconds in Retry-After, then retry.
503service_unavailableVariesRelayvia's own storage is briefly unavailable; the response carries Retry-After: 1.Wait the seconds in Retry-After, then retry.
500upstream_timeoutModel processing timed out.Every attempt timed out.Retry later; use streaming for long outputs.

402 is not 429

Warning · 402 insufficient_quota: out of credits

The account's credits, the key's credit limit, the team member's credit limit or an account spend limit cannot cover the request, or the account is frozen because its credits went below zero. The request was not sent to the model. Retrying will not help: top up, or ask an admin to raise the limit. The reservation includes your output limit, so a very large max_tokens can also cause a 402; lower it.

Note · 429 rate_limited: too many requests

You sent requests faster than a rate limit allows. Nothing was charged. Wait the number of seconds in Retry-After and retry; most SDKs do this for you.

Retry-After

429 rate_limited, 503 service_busy and 503 service_unavailable carry a Retry-After header in seconds. For service_busy it is the longest wait any model service asked for, or 5 seconds by default; for service_unavailable it is 1. Wait at least that long before retrying.

Response
HTTP/1.1 503 Service Unavailable
Retry-After: 5
x-robi-request-id: 0193f2c1-7a4e-7cc2-9b1d-5f0e2a6c8d41

{"error":{"message":"The service is currently busy.","type":"api_error","param":null,"code":"service_busy"}}

Errors after retries

When a model service fails, Relayvia retries the request on other services for the same model before answering. If every attempt fails, the error depends on how they failed:

  • Every attempt was busy: 503 service_busy with Retry-After.
  • Every attempt timed out: 500 upstream_timeout.
  • Any other mix: 500 upstream_error.

Both of these come back as HTTP 500, so tell them apart by code; in the Gemini format, which has no code, by status (DEADLINE_EXCEEDED for a timeout, INTERNAL otherwise). SDKs retry them as usual.

Errors during streaming

Once the first byte is sent the status stays 200. If the model fails mid-stream, you receive an error event in the endpoint's format and the stream ends; Relayvia does not retry after that point. The same applies to non-streaming requests sent with X-Robi-Keepalive: 1: a failure arrives as an error object in the body.

Safety refusals

content_policy means the input was refused; content_policy_output means the generated result was refused, not your input. A chat model that declines to answer is a normal response, for example Gemini finishReason: SAFETY or Anthropic stop_reason: refusal, and is passed through as is.