200 and plausible output while doing something other than what you asked. For the exhaustive list of statuses and messages, see the error reference.
No audio at all
The file exists but will not play. Check what is actually in it before anything else:{, you received JSON, which means Accept was missing or unrecognized. If it contains readable English, you received an error message written to the file by a client that did not check the status. See the quickstart’s success check.
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.
A 401 you did not expect. 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.
Audio arrives but is wrong
The voice is not the one you asked for. Most likely thespeaker, modelId, and lang combination is not one the catalog serves, and it was not rejected. Verify against the Coda or 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 are ignored above or below 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.
Pronunciation overrides do nothing. phonemizeBetweenBrackets is served only by Mist v2 and Mist v1. On Mist v3, Coda, and Arcana 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 whenlang is omitted. In the other six 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; 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 before investigating anything else, then see Latency.
Retrying safely
Retry only what can succeed on a second attempt, and know what a retry costs.
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.
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 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: every status and message, per transport.
- Voices: verify a voice, model, and language combination.

