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

# Troubleshooting the API

> Diagnose Rime API failures by what you observe, including failures that arrive wrapped by LiveKit, Pipecat, Vapi, or the CLI.

Many Rime API failures are silent: a request returns `200` and plausible output while doing something other than what you asked. This page starts from what you observe. For the exhaustive list of statuses and messages, see [the error reference](/docs/errors).

<Warning>**Capture evidence before you retry.** No response carries a request ID you can quote, so record the UTC timestamp, the endpoint and region, `modelId`, `speaker`, and `lang` as sent, the status and full body or the WebSocket close code and its complete reason string, and whether any audio had arrived. A reproduction is often the only diagnostic available.</Warning>

## No audio at all

### The file exists but will not play

Check what is actually in it before anything else:

```bash theme={null}
file output.wav       # expect: RIFF (little-endian) data, WAVE audio
head -c 4 output.wav  # expect: RIFF
```

What the first bytes tell you:

* **`RIFF`:** the file has a WAV header. If it still won't play, check its size: a file of a few hundred bytes means the stream ended early.
* **`{`:** you received the legacy JSON envelope. Only Mist v1 and Mist v2 return it, when `Accept` is missing or doesn't name a type the API can stream.
* **Unreadable binary without `RIFF`:** on Coda and Mist v3, a missing or wildcard `Accept` returns raw 16-bit PCM (`audio/pcm`), which players won't open. Set `Accept: audio/wav`.
* **Readable English:** a client that didn't check the status wrote an error message to the file. An `Accept` naming an unsupported type, for example, returns `406` with a plain-text list of supported types.

See [the quickstart's success check](/docs/quickstart-five-minute#confirm-it-worked).

### The file is zero bytes

The request never completed. Confirm the URL is `https://users.rime.ai/v1/rime-tts` and reachable, and that your client is not silently following a redirect or failing TLS.

### An unexpected `401`

Five different messages produce a `401`, and they mean different things. `invalid subscription` is a billing state, not a bad key, so regenerating the credential will not help. `empty apikey` almost always means a shell variable did not expand. See [401 in the error reference](/docs/errors#401-authentication-failed).

## Audio arrives but is wrong

### The voice is not the one you asked for

Most likely the `speaker`, `modelId`, and `lang` combination is not one the catalog serves, and it was not rejected. Verify against the [Coda](/docs/voices-coda) or [Mist v3](/docs/voices-mist-v3) catalog. Remember that every Coda voice serves exactly one language, so the voice determines `lang`.

Second possibility: `modelId` contains a typo. An unrecognized value is served by Mist v3 without an error, so `codaa` returns working audio from the wrong model.

### Speed changes stop taking effect past a point

`timeScaleFactor` is clamped to 0.4 to 2.5 without notice. Also check you are using the right parameter for the model: `speedAlpha` is inverted on Mist v2 relative to every other model. See [Speed](/docs/speed).

### Pronunciation overrides do nothing

`phonemizeBetweenBrackets` is served by Mist v1, Mist v2, and English Mist v3. On Coda and non-English Mist v3 it is accepted and ignored. See the model reference.

## Streaming and WebSocket problems

### Timestamps never arrive

They are emitted only for English and Spanish, or when `lang` is omitted. In other Coda languages the stream sends `chunk` and `done` with no `timestamps` event and no error, so never block playback waiting for one.

### The connection closes mid-utterance

A server-side failure closes with `1011` and puts the message in the close reason, often prefixed with an HTTP-equivalent status as in `400: text is too long`. Log the whole reason string. Read the prefix when diagnosing, but do not branch on it.

### The upgrade fails before a socket opens

Connection-time failures arrive as an HTTP status on the upgrade, not as a close code. A `429` there means you are opening connections too fast, so back off and reuse connections rather than opening one per utterance.

### Audio is choppy or late under load

Check you are calling the nearest [regional endpoint](/docs/regional-endpoints) before investigating anything else, then see [Latency](/docs/latency).

## Retrying safely

Retry only what can succeed on a second attempt, and know what a retry costs.

| What happened | Retry? | Notes |
| :- | :- | :- |
| `400` | No | The request is malformed. It will fail identically. |
| `401`, `403` | No | Fix the credential or the account. Repeated attempts with a bad key are indistinguishable from an attack. |
| `429` at the upgrade | Yes, after backoff | Retry the connection, not the synthesis. Reduce connection churn. |
| `500`, `502` | Yes, with backoff | The only failures where an immediate retry is reasonable. |
| `1011` close, no audio yet | Usually | Read the reason string first. If it describes a malformed request, fix the request instead of retrying. |
| `1011` close, audio already sent | Only deliberately | See the billing warning below. |
| Upgrade succeeded, then silence | Reconnect | Do not retry the whole utterance without deciding what to do about the partial audio. |

<Warning>**Retries are billed as new synthesis.** Rime bills by characters synthesized, and each request is billed independently. If a connection drops partway through a long utterance, resynthesizing the full text incurs its full character count again. For long utterances, synthesize in sentence-aligned chunks and resume from the last chunk you received, so a retry only re-sends what was lost.</Warning>

Rime does not send a `Retry-After` header, so choose your own backoff. Exponential with jitter, capped, is the usual choice.

## Failures that arrive wrapped

Most developers meet the Rime API through an integration rather than directly, and see a framework exception instead of a status code. Map it back before diagnosing.

| Where you are | What you see | How to get the real cause |
| :- | :- | :- |
| LiveKit agents | A plugin exception during TTS, often without the HTTP status | Reproduce the same `speaker`, `modelId`, and `lang` with a raw cURL request. Older LiveKit Rime plugin releases default to the retired `arcana` identifier, so set `model="coda"` explicitly. See [LiveKit](/docs/quickstart-livekit). |
| Pipecat | A service error in the pipeline log | Pipecat defaults to Coda from v1.3.0. Confirm your version, then reproduce with cURL. See [Pipecat](/docs/pipecat). |
| Vapi | A provider error in the call log | Voice and model are set in the Vapi dashboard rather than in your code, so check there first. See [Vapi](/docs/vapi). |
| Rime CLI | A command error | Run with the same values through [`rime curl`](/cli-reference/rime-curl) to see the unwrapped response, and see [CLI troubleshooting](/cli-reference/troubleshooting). |
| MCP server | A tool error in your assistant | `list_voices` needs no key, so if that works and synthesis does not, the problem is the key rather than the connection. See [MCP](/docs/mcp). |

The general method is the same in every row: reduce to one raw HTTP request with the identical `speaker`, `modelId`, `lang`, and `Accept`, and read the plain-text body. If the raw request succeeds, the problem is in the integration or its configuration rather than in the API.

## Still stuck

Contact [support@rime.ai](mailto:support@rime.ai) with the evidence listed at the top of this page. Because no request ID exists, the reproduction and the exact timestamp are what make a report actionable.

## Related

* [Error reference](/docs/errors): every status and message, per transport.
* [Voices](/docs/voices): verify a voice, model, and language combination.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.