# Errors (/docs/errors)

Every error message says what to do next, so you can show it to whoever can act on it and branch your code on the HTTP status. Every response, errors included, carries an `X-Request-ID`; include it when you contact support.

## Status codes [#status-codes]

| Status | `code` | What to do |
|---|---|---|
| 400 | `invalid_request`, `invalid_parameter`, `missing_required_parameter`, `unsupported_parameter`, `unsupported_content`, `unsupported_endpoint`, `context_length_exceeded`, `content_policy_violation` | Fix or remove the parameter, content or endpoint the message names, then send again. |
| 401 | `invalid_api_key`, `api_key_expired`, `api_key_disabled` | Use a valid key from the [API keys](https://www.ohmygpt.com/keys) page. |
| 402 | `insufficient_credits`, `api_key_spend_limit_exceeded` | Top up on the [Billing](https://www.ohmygpt.com/billing) page, or raise the key's spending limit. |
| 403 | `model_not_allowed`, `account_suspended` | Add the model to the key's allowed models, or contact support. |
| 404 | `model_not_found` | Copy the model ID from `GET /v1/models`. |
| 413 | `request_too_large` | Send a smaller request body. |
| 429 | `rate_limit_exceeded` | Wait `Retry-After` seconds, then send again. |
| 500, 502, 503, 504 | `model_error`, `model_overloaded`, `model_unavailable`, `model_timeout`, `service_unavailable`, `internal_error` | Retry with backoff, or switch to another model. |

Parameter errors keep the model's own wording, so the message tells you the accepted range:

```json
{
  "error": {
    "param": null,
    "code": "invalid_request",
    "message": "Invalid 'temperature': decimal above maximum value. Expected a value <= 2, but got 5 instead.",
    "type": "invalid_request_error"
  }
}
```

## Error body [#error-body]

The body follows the protocol of the endpoint you called, so your SDK raises its usual exception types.

```json tab="Chat Completions, Responses"
{
  "error": {
    "param": "model",
    "code": "model_not_found",
    "message": "The model `no/such-model` does not exist. List available models with `GET /v1/models`.",
    "type": "not_found_error"
  }
}
```

```json tab="Anthropic Messages"
{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key. Create or manage your keys at https://www.ohmygpt.com/keys."
  }
}
```

```json tab="Gemini"
{
  "error": {
    "code": 401,
    "message": "Invalid API key. Create or manage your keys at https://www.ohmygpt.com/keys.",
    "status": "UNAUTHENTICATED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "INVALID_API_KEY",
        "domain": "ohmygpt.com"
      }
    ]
  }
}
```

In the OpenAI shape, branch on `code`. The Anthropic shape carries the status category in `error.type`, and Gemini carries the code upper-cased in `details[].reason`.

With the OpenAI Python SDK:

```python
import os

import openai
from openai import OpenAI

client = OpenAI(base_url="https://api.ohmygpt.com/v1", api_key=os.environ["OHMYGPT_API_KEY"])

try:
    completion = client.chat.completions.create(
        model="no/such-model",
        messages=[{"role": "user", "content": "Hi"}],
    )
except openai.RateLimitError as e:          # 429
    retry_after = int(e.response.headers.get("retry-after", "1"))
except openai.APIStatusError as e:          # any other non-2xx
    print(e.status_code, e.code, e.response.headers.get("x-request-id"))
```

```text
404 model_not_found 01a19b5f-6ab6-7dc0-88ff-f5c95e0169e4
```

## Errors during a stream [#errors-during-a-stream]

A stream that has started already has status 200. If generation stops partway, the stream ends with an error event in place of its normal final event:

```text tab="Chat Completions"
data: {"error":{"param":null,"code":"model_error","message":"The model `zhipu/glm-5.3-flash` stopped mid-response, so the output is incomplete. Try again.","type":"server_error"}}
```

```text tab="Responses"
event: response.failed
data: {"type":"response.failed","response":{"status":"failed","error":{"code":"model_error","message":"..."}, ...}}
```

```text tab="Anthropic Messages"
event: error
data: {"type":"error","error":{"type":"api_error","message":"..."}}
```

The OpenAI and Anthropic SDKs raise this as an exception while you iterate, so handle it like any other error. If you parse the stream yourself, treat a stream that ends without its final event (`data: [DONE]`, `message_stop` or `response.completed`) as incomplete.

## When to retry [#when-to-retry]

OhMyGPT already sends the request to another provider when one fails before answering, so you don't need retry logic for that. In your code:

- **400, 401, 402, 403, 404:** change the request, key or balance first; sending it again unchanged gives the same answer.
- **429:** wait `Retry-After` seconds, then send again.
- **500, 502, 503, 504:** retry a few times with exponential backoff, waiting `Retry-After` seconds when the header is present. If the error continues, switch to another model.
