> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withhopper.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> OpenAI error envelope; every error code grouped by HTTP status

Every error is JSON in the OpenAI envelope:

```json theme={null}
{
  "error": {
    "message": "...",
    "type": "...",
    "code": "...",
    "param": null
  }
}
```

WebSocket routes write the same envelope as a raw HTTP response when the upgrade is rejected (bad key, rate limit, zero balance, invalid params).

## 400 — invalid request

| Code                        | Returned when                                                                                                              |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `invalid_json`              | Request body is not a JSON object.                                                                                         |
| `transcript_too_long`       | Pronunciation-dictionary alias expansion pushed the transcript past 20,000 characters (4× the 5,000-character submit cap). |
| `invalid_output_format`     | `stream: true` with an mp3 container. Message: "Streaming TTS does not support mp3; use wav or pcm/raw."                   |
| `invalid_generation_config` | `stream: true` with `generation_config.speed` ≠ 1.                                                                         |
| `unsupported_audio_format`  | STT file is not raw PCM16 or WAV — mp3, ogg, flac, mp4, and m4a are rejected by magic bytes.                               |
| `invalid_sample_rate`       | `sample_rate` outside 8000–48000 or not in the model's allowlist.                                                          |
| `invalid_turn_detection`    | `turn_detection` is not `balanced`, `patient`, or `responsive`.                                                            |
| `upgrade_required`          | Plain HTTP GET to `/stt/websocket` without a WebSocket upgrade.                                                            |

## 401 — authentication

| Code               | Returned when                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `invalid_api_key`  | No key on the request ("You didn't provide an API key. Get one at [https://withhopper.com/dashboard](https://withhopper.com/dashboard) and pass it via the Authorization header: 'Authorization: Bearer sk\_hopper\_...'.") or the key does not exist ("Incorrect API key provided. Check your key at [https://withhopper.com/dashboard](https://withhopper.com/dashboard)."). |
| `api_key_disabled` | The key was revoked. Message: "This API key has been disabled."                                                                                                                                                                                                                                                                                                                |

## 402 — out of credits

| Code                 | Returned when                                                                                                                                                                                                    |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `insufficient_quota` | Credit balance is zero on any metered route, including STT WebSocket upgrade. Message: "You have run out of credits. Contact us to add more." A live STT session that hits zero closes with WebSocket code 1008. |

## 403 — forbidden

| Code              | Returned when                                                                                                        |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- |
| `voice_read_only` | Mutating a platform voice. Platform voices are read-only; only your own voices can be renamed, retagged, or deleted. |

## 404 — not found

| Code              | Returned when                                                             |
| ----------------- | ------------------------------------------------------------------------- |
| `model_not_found` | The model id does not resolve to an active model of the route's modality. |
| `voice_not_found` | The voice does not exist or is not visible to your org.                   |
| `dict_not_found`  | `pronunciation_dict_id` does not match one of your dictionaries.          |

## 409 — conflict

| Code                    | Returned when                                                                                                                                      |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `voice_profile_missing` | The voice has no ready profile for the requested model ("Voice 'X' is not prepared for model 'Y'."). Prepare one with `POST /voices/:id/profiles`. |

## 413 — payload too large

| Code             | Returned when                                                                                         |
| ---------------- | ----------------------------------------------------------------------------------------------------- |
| `body_too_large` | Request body exceeds the route cap: 10 MB on `/v1/*` LLM routes, 25 MB on `/v1/audio/transcriptions`. |

## 429 — rate limited

| Code                  | Returned when                                                                                                                                                                                                                         |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rate_limit_exceeded` | More than 600 requests in the key's fixed one-minute window. Message: "Rate limit reached: 600 requests per minute per key. Retry after Ns." Comes with a `Retry-After: <seconds>` header — see [Rate limits](/platform/rate-limits). |

## 5xx — server errors

| Status | Code                                     | Returned when                                                                                                | Retry                                                                              |
| ------ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| 500    | `internal_error`                         | Unhandled gateway exception.                                                                                 | Retry once; persistent 500s are a gateway fault, not your request.                 |
| 502    | `upstream_unavailable`, `upstream_error` | The model upstream is unreachable, timed out, or returned an error.                                          | Retry with backoff.                                                                |
| 503    | `verify_unavailable`                     | Key verification is temporarily down. Message: "Key verification is temporarily unavailable. Retry shortly." | Retry within seconds; your key is fine.                                            |
| 503    | `model_offline`                          | The model has no healthy upstream.                                                                           | Back off in minutes, not milliseconds — tight retries do not bring the model back. |
| 504    | `upstream_timeout`                       | The upstream exceeded the 300 s deadline.                                                                    | Retry with a shorter request; a full 300 s timeout rarely resolves on replay.      |
