Skip to content

Errors

All upstream errors flow through a single normalizer and come back as an OpenAI/Anthropic-shaped error object with a public provider label only — upstream identity and keys are never leaked.

{
"error": {
"type": "invalid_request_error",
"message": "model 'foo/bar-9000' is not embedding-capable",
"code": "model_task_mismatch",
"provider": "opengateway"
}
}

| Status | Meaning | What to do | | --- | --- | --- | | 400 invalid_model | Malformed model id / bad request shape | Use a curated alias or a valid org/model[:policy] id. | | 401 / 403 | Missing or wrong key / scheme | Send Authorization: Bearer <key> (or x-api-key). Check the key is active. | | 404 model | Unknown id, or non-/oss model on /oss | GET /<lane>/v1/models and copy an exact id. | | 422 model_task_mismatch | Model can’t serve this endpoint | Pick a model capable of the task (e.g. an embedding model for /v1/embeddings). | | 429 | Rate / concurrency limit | Back off with jitter; lower concurrency; check plan limits. | | 402 | Upstream credits exhausted | Hard stop — top up upstream credits. Not retried. | | 503 | Provider/model offline | Use :fastest/:cheapest to pick a live provider; retry. | | 4xx (context) | Request exceeds the model’s window | Trim context or target a 1M model. |

OpenGateway keys retry decisions off the HTTP status, not the response body (upstreams pass through varied error shapes):

  • Retry with backoff + provider failover: 5xx, 429.
  • Never retry: 401, 403, 404, 422.
  • Hard stop: 402 (credits exhausted).

| Symptom | Likely cause | Fix | | --- | --- | --- | | “No usable models” (Claude Desktop) | Wrong base URL or discovery contract | Point ANTHROPIC_BASE_URL at the lane root (…/oss); confirm /v1/models. | | Cursor won’t enable the endpoint | /v1/models not returning 200 | OpenGateway returns 200 (OpenAI shape) for any valid-looking key. | | Streaming not rendering | stream not set / client buffering | Set stream: true; read incrementally; expect text/event-stream. |