# Arcana streaming HTTP (deprecated) Source: https://docs.rime.ai/api-reference/arcana/http POST https://users.rime.ai/v1/rime-tts Deprecated Arcana HTTP reference. Cloud Arcana requests switch to Coda on August 15, 2026 at 12:00 UTC. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. The streaming endpoint returns audio bytes in the format specified by the `Accept` header. ## Audio formats Set the `Accept` header to one of the following values: | Format | Accept Header | Notes | | ----------- | ------------------------ | ---------------------------------------------------------------------------------------------------------- | | Opus (WebM) | `audio/webm;codecs=opus` | Recommended. Smaller files than MP3 at comparable quality. WebM streams natively in browsers. | | Opus (OGG) | `audio/ogg;codecs=opus` | Opus in an OGG container. Smaller files than MP3 at comparable quality. | | MP3 | `audio/mpeg` | Lower compression rate than Opus. Highest compatibility across devices and players. | | WAV | `audio/wav` | Uncompressed. RIFF WAVE header with 16-bit little-endian linear PCM samples. Streams natively in browsers. | | PCM | `audio/L16` | Headerless 16-bit little-endian linear PCM. | | G.711 μ-law | `audio/PCMU` | Headerless stream of audio bytes. | ### Deprecated aliases Still accepted for backwards compatibility; new code should use the RFC types above. | Deprecated | Use instead | | --------------- | ------------ | | `audio/mp3` | `audio/mpeg` | | `audio/pcm` | `audio/L16` | | `audio/x-mulaw` | `audio/PCMU` | ## Variable parameters Must be a voice available on arcana. See the voice catalog. The text you'd like spoken. Unlimited via API. Character limit per request is 3,000 in the dashboard UI. Set to `arcana`. If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. The sampling rate (Hz). The time scaling factor. Accepted range is 0.4 to 2.5; values outside it are clamped without an error. A value above 1.0 slows down the audio, a value below 1.0 speeds up the audio. ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Accept: audio/webm;codecs=opus' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --output output.webm \ --fail \ --data '{ "text": "Hello from Rime!", "modelId": "arcana", "speaker": "astra", "lang": "en", "samplingRate": 24000 }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/v1/rime-tts" payload = { "speaker": "astra", "text": "Hello from Rime!", "modelId": "arcana", "samplingRate": 24000 } headers = { "Accept": "audio/webm;codecs=opus", "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } with requests.post(url, headers=headers, json=payload, stream=True) as response: response.raise_for_status() with open("output.webm", "wb") as f: for chunk in response.iter_content(chunk_size=4096): if chunk: f.write(chunk) ``` ```javascript JavaScript theme={null} const fs = require("fs"); const options = { method: 'POST', headers: { Accept: 'audio/webm;codecs=opus', Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: '{"speaker":"astra","text":"Hello from Rime!","modelId":"arcana","samplingRate":24000}' }; fetch('https://users.rime.ai/v1/rime-tts', options) .then(response => response.arrayBuffer()) .then(buffer => { fs.writeFileSync("output.webm", Buffer.from(buffer)); console.log("Audio saved to output.webm"); }) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/v1/rime-tts", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"arcana\",\n \"samplingRate\": 24000\n}", CURLOPT_HTTPHEADER => [ "Accept: audio/webm;codecs=opus", "Authorization: Bearer YOUR_API_KEY", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "io" "net/http" "os" "strings" ) func main() { url := "https://users.rime.ai/v1/rime-tts" payload := strings.NewReader("{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"arcana\",\n \"samplingRate\": 24000\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "audio/webm;codecs=opus") req.Header.Add("Authorization", "Bearer YOUR_API_KEY") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) _ = os.WriteFile("output.webm", body, 0644) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/v1/rime-tts") .header("Accept", "audio/webm;codecs=opus") .header("Authorization", "Bearer YOUR_API_KEY") .header("Content-Type", "application/json") .body("{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"arcana\",\n \"samplingRate\": 24000\n}") .asBytes(); Files.write(Paths.get("output.webm"), response.getBody()); ``` # Arcana WebSockets (deprecated) Source: https://docs.rime.ai/api-reference/arcana/websockets GET wss://users-ws.rime.ai/ws Deprecated Arcana plain-text WebSocket reference. Cloud Arcana requests switch to Coda on August 15, 2026 at 12:00 UTC. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. Include `modelId=arcana` in the connection query. If you omit it, the server routes the request to Mist v3 and speakers outside the Mist v3 catalog can fail with `Speaker not found`. ## Overview Rime's websocket implementation accepts bare text, and responds with audio bytes of the selected format. All synthesis arguments are provided as query parameters when establishing the connection. ## Messages ### Send The messages your client will send to the websocket API will be bare (non-serialized) text. ```example theme={null} This will be converted to audio via websockets ``` ### Receive The messages your client will receive will be raw audio bytes in the audio format specified at connection time. ```example theme={null} ^@^@^@9LAME3.100^AP^@^@^@^@^@^@^@^@^T$^D>"^@^@^@^@<9D>G^N^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^@^@^@^@^@^@^@ ``` ## Commands Use these commands to manipulate the stored text buffer. ### `` This clears the current buffer. Used in the event of interruptions. ### `` This forces whatever buffer exists, if any, to be synthesized, and the generated audio to be sent over. ### `` This forces whatever buffer exists, if any, to be synthesized, and for the server to close the connection after sending the generated audio. ## Variable parameters Must be an `arcana` voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set this to `arcana`. It is not strictly required, but if you omit it the server defaults to the Mist v3 backend, and speakers outside the Mist v3 catalog fail with a "Speaker not found" error. One of `mp3`, `ogg`, `mulaw`, or `pcm` If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. The sampling rate (Hz). * **On-cloud**: Accepted values: 8000, 16000, 22050, 24000, 44100, 48000, 96000. Anything above 24000 is up sampling. * **On-prem**: Any value is accepted. Controls how text is segmented for synthesis. Available options: * "immediate" - Synthesizes text immediately without waiting for complete sentences * "never" - Never segments the text, waits for explicit flush or EOS * "bySentence" (default) - Waits for complete sentences before synthesis Note: For backward compatibility, setting `immediate=true` in query params is equivalent to `segment=immediate`. If a null value is provided, it will default to "bySentence". ```python Python theme={null} import asyncio import websockets import os from dotenv import load_dotenv load_dotenv() api_key = os.environ.get('RIME_API_KEY') if not api_key: raise ValueError("RIME_API_KEY environment variable is not set") FILE_PATH = "arcana_ws.wav" class RimeClient: def __init__(self, speaker, api_key): self.url = f"wss://users-ws.rime.ai/ws?speaker={speaker}&modelId=arcana&audioFormat=wav" self.auth_headers = { "Authorization": f"Bearer {api_key}" } self.audio_data = b'' async def send_tokens(self, websocket, message): for token in message: await websocket.send(token) async def handle_audio(self, websocket): while True: try: audio = await websocket.recv() except websockets.exceptions.ConnectionClosedOK: break self.audio_data += audio async def run(self, message): async with websockets.connect(self.url, additional_headers=self.auth_headers) as websocket: await asyncio.gather( self.send_tokens(websocket, message), self.handle_audio(websocket), ) def save_audio(self, file_path): with open(file_path, 'wb') as f: f.write(self.audio_data) message = [ "This ", "is ", "a ", "test ", "of ", "the ", "arcana ", "model ", "using ", "websockets ", "and ", "python.", "", ] client = RimeClient("astra", api_key=api_key) asyncio.run(client.run(message)) print(f"Saving audio to {FILE_PATH}") client.save_audio(FILE_PATH) ``` # Arcana WebSockets JSON (deprecated) Source: https://docs.rime.ai/api-reference/arcana/websockets-json GET wss://users-ws.rime.ai/ws3 Deprecated Arcana JSON WebSocket reference. Cloud Arcana requests switch to Coda on August 15, 2026 at 12:00 UTC. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. Include `modelId=arcana` in the connection query. If you omit it, the server routes the request to Mist v3 and speakers outside the Mist v3 catalog can fail with `Speaker not found`. ## Overview In addition to a plaintext websocket implementation, Rime also has an implementation that sends and receives events as JSON objects. Like the other implementation, all synthesis arguments are provided as query parameters when establishing the connection. The WebSocket API buffers inputs up to one of the following punctuation characters: `.`, `?`, `!`. This is most pertinent for the initial messages sent to the API, as synthesis won't begin until there are sufficient tokens to generate audio with natural prosody. After the first synthesis of any given utterance, typically enough time has elapsed that subsequent audio contains multiple clauses, and the buffering becomes largely invisible. ## Messages ### Send #### Text This is the most common message, which contains text for synthesis. schema: ```typescript theme={null} type TextMessage = { text: string, contextId?: string, } ``` examples: ```json theme={null} { "text": "this is the minimum text message." } { "text": "this is a text message with a context id.", "contextId": "159495B1-5C81-4C73-A51A-9CE10A08239E" } ``` Context IDs can be provided, which will be attached to subsequent messages that the server sends back to the client. Rime will not maintain multiple simultaneous context IDs. The events will contain the most recent context ID at the time that audio was requested. In the above examples, even if both messages are received by the server before it sends any audio, the audio response for the first sentence will be tagged with `contextId: null`, and the audio for the second will be tagged with its UUID. #### Clear Your client can clear out the accumulated buffer, which is useful in the case of interruptions. ```json theme={null} { "operation": "clear" } ``` #### Flush This forces whatever buffer exists, if any, to be synthesized, and the generated audio to be sent over. ```json theme={null} { "operation": "flush" } ``` #### EOS At times, your client would like to generate audio for whatever remains in the buffer, and then have the connection immediately closed. ```json theme={null} { "operation" : "eos" } ``` ### Receive #### Chunk The most common event will be the audio chunk. ```typescript theme={null} type Base64String = string type AudioChunkEvent = { type: "chunk", data: Base64String, contextId: string | null, } ``` The audio will be a base64 encoded chunk of audio bytes in the audio format specified when the connection was established. If you provided any context id when sending the relevant text, it'll be included here. #### Timestamps Word-level timestamps are emitted alongside the audio chunks so the client can tell exactly which words have been spoken at any point. This is especially useful for handling interruptions: when the user starts talking over the output, you can map the playback position back to the last word that was actually heard. Timestamps are emitted only when `lang` is `en`/`eng` or `es`/`spa`, or when `lang` is omitted. Requests in any other language receive `chunk` and `done` events with no `timestamps` event and no error (this includes fr, de, ja, pt, ar, and hi). Do not block playback while waiting for a timestamps event. ```typescript theme={null} type TimestampsEvent = { type: "timestamps", word_timestamps: { words: string[], start: number[], end: number[], }, contextId: string | null, } ``` The three arrays inside `word_timestamps` are the same length and index-aligned: for a given index `i`, `words[i]` is spoken from `start[i]` to `end[i]`. Times are in seconds, measured from the beginning of the audio for the current synthesis. If a context id was attached to the text that produced this audio, it is included on the event. Example payload: ```json theme={null} { "type": "timestamps", "word_timestamps": { "words": ["Hello", "from", "a", "timestamps", "probe."], "start": [0, 0.32462, 0.48693, 0.64924, 0.97386], "end": [0.32462, 0.48693, 0.64924, 0.97386, 1.78541] }, "contextId": null } ``` #### Done After the last audio chunk for a synthesis batch has been sent, the server emits a `done` event. This signals that the current synthesis is fully complete. If the client sends more text and triggers further synthesis, another `done` will follow. ```typescript theme={null} type DoneEvent = { type: "done", contextId: string | null, } ``` When exactly `done` fires depends on the `segment` setting. See [Segmentation and behavior settings](/docs/websockets-segment) for full details. #### Error In the event of a malformed or unexpected input, the server will immediately respond with an error message. The server will *not* close the connection, and will still accept subsequent well-formed messages. It's up to the client to decide if it wants to close upon receiving an error. ```typescript theme={null} type ErrorEvent = { type: "error", message: string, } ``` ## Variable parameters Must be an `arcana` voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set this to `arcana`. It is not strictly required, but if you omit it the server defaults to the Mist v3 backend, and speakers outside the Mist v3 catalog fail with a "Speaker not found" error. One of `mp3`, `mulaw`, or `pcm` If provided, the language must match the language spoken by the provided speaker. Verify the pairing in the Rime voice catalog. The sampling rate (Hz). * **On-cloud**: Accepted values: 8000, 16000, 22050, 24000, 44100, 48000, 96000. Anything above 24000 is up sampling. * **On-prem**: Any value is accepted. Controls how text is segmented for synthesis. Available options: * "immediate" - Synthesizes text immediately without waiting for complete sentences * "never" - Never segments the text, waits for explicit flush or EOS * "bySentence" (default) - Waits for complete sentences before synthesis Note: For backward compatibility, setting `immediate=true` in query params is equivalent to `segment=immediate`. If a null value is provided, it will default to "bySentence". ```python Python theme={null} import asyncio import json import websockets import base64 class RimeClient: def __init__(self, speaker, api_key): self.url = f"wss://users-ws.rime.ai/ws3?speaker={speaker}&modelId=arcana&audioFormat=mp3" self.auth_headers = { "Authorization": f"Bearer {api_key}" } self.audio_data = b'' async def send_messages(self, websocket, messages): for message in messages: await websocket.send(json.dumps(message)) async def handle_audio(self, websocket): while True: try: audio = await websocket.recv() except websockets.exceptions.ConnectionClosedOK: break message = json.loads(audio) if message['type'] == 'chunk': self.audio_data += base64.b64decode(message['data']) if message['type'] == 'timestamps': print("Rime model pronounced the words...\n") for w, t in zip(message['word_timestamps']['words'], message['word_timestamps']['start']): print(f"'{w}' at time {t}") async def run(self, messages): async with websockets.connect(self.url, additional_headers=self.auth_headers) as websocket: await asyncio.gather( self.send_messages(websocket, messages), self.handle_audio(websocket), ) def save_audio(self, file_path): with open(file_path, 'wb') as f: f.write(self.audio_data) print(f"\n Audio saved at {file_path}") message = [ {"text": "This "}, {"text": "is "}, {"text": "a "}, {"text": "test "}, {"operation":"clear"}, {"text": "This "}, {"text": "is "}, {"text": "an "}, {"text": "incomplete "}, {"text": "sentence "}, {"operation": "eos"}, ] client = RimeClient("astra", api_key="xxx") asyncio.run(client.run(message)) client.save_audio("output.mp3") ``` # Streaming HTTP Source: https://docs.rime.ai/api-reference/coda/http POST https://users.rime.ai/v1/rime-tts Coda streaming HTTP endpoint: synthesize speech with Rime's flagship model and stream audio back. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. The streaming endpoint returns audio bytes in the format specified by the `Accept` header. ## Audio formats Set the `Accept` header to one of the following values: | Format | Accept Header | Notes | | ----------- | ------------------------ | ---------------------------------------------------------------------------------------------------------- | | Opus (WebM) | `audio/webm;codecs=opus` | Recommended. Smaller files than MP3 at comparable quality. WebM streams natively in browsers. | | Opus (OGG) | `audio/ogg;codecs=opus` | Opus in an OGG container. Smaller files than MP3 at comparable quality. | | MP3 | `audio/mpeg` | Lower compression rate than Opus. Highest compatibility across devices and players. | | WAV | `audio/wav` | Uncompressed. RIFF WAVE header with 16-bit little-endian linear PCM samples. Streams natively in browsers. | | PCM | `audio/L16` | Headerless 16-bit little-endian linear PCM. | | G.711 μ-law | `audio/PCMU` | Headerless stream of audio bytes. | ### Deprecated aliases Still accepted for backwards compatibility; new code should use the RFC types above. | Deprecated | Use instead | | --------------- | ------------ | | `audio/mp3` | `audio/mpeg` | | `audio/pcm` | `audio/L16` | | `audio/x-mulaw` | `audio/PCMU` | ## Variable parameters Must be a voice available on coda. See the voice catalog. The text you'd like spoken. The API accepts up to 1,000 characters per request. Set to `coda` to select the Coda voice lineup. If provided, the language must match the language spoken by the provided speaker. Both the 2-letter ISO 639-1 and the 3-letter ISO 639-2/3 form are accepted: | 639-1 | 639-2/3 | Language | | ----- | ------- | ---------- | | `en` | `eng` | English | | `es` | `spa` | Spanish | | `fr` | `fra` | French | | `pt` | `por` | Portuguese | | `de` | `ger` | German | | `ja` | `jpn` | Japanese | | `ar` | `ara` | Arabic | | `hi` | `hin` | Hindi | See the voices documentation for which speakers support each language. The sampling rate (Hz). The time scaling factor. Accepted range is 0.4 to 2.5; values outside it are clamped without an error. A value above 1.0 slows down the audio, a value below 1.0 speeds up the audio. ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Accept: audio/webm;codecs=opus' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --output output.webm \ --fail \ --data '{ "text": "Hello from Rime!", "modelId": "coda", "speaker": "astra", "lang": "en", "samplingRate": 24000 }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/v1/rime-tts" payload = { "speaker": "astra", "text": "Hello from Rime!", "modelId": "coda", "samplingRate": 24000 } headers = { "Accept": "audio/webm;codecs=opus", "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } with requests.post(url, headers=headers, json=payload, stream=True) as response: response.raise_for_status() with open("output.webm", "wb") as f: for chunk in response.iter_content(chunk_size=4096): if chunk: f.write(chunk) ``` ```javascript JavaScript theme={null} const fs = require("fs"); const options = { method: 'POST', headers: { Accept: 'audio/webm;codecs=opus', Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: '{"speaker":"astra","text":"Hello from Rime!","modelId":"coda","samplingRate":24000}' }; fetch('https://users.rime.ai/v1/rime-tts', options) .then(response => response.arrayBuffer()) .then(buffer => { fs.writeFileSync("output.webm", Buffer.from(buffer)); console.log("Audio saved to output.webm"); }) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/v1/rime-tts", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"coda\",\n \"samplingRate\": 24000\n}", CURLOPT_HTTPHEADER => [ "Accept: audio/webm;codecs=opus", "Authorization: Bearer YOUR_API_KEY", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "io" "net/http" "os" "strings" ) func main() { url := "https://users.rime.ai/v1/rime-tts" payload := strings.NewReader("{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"coda\",\n \"samplingRate\": 24000\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "audio/webm;codecs=opus") req.Header.Add("Authorization", "Bearer YOUR_API_KEY") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) _ = os.WriteFile("output.webm", body, 0644) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/v1/rime-tts") .header("Accept", "audio/webm;codecs=opus") .header("Authorization", "Bearer YOUR_API_KEY") .header("Content-Type", "application/json") .body("{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"coda\",\n \"samplingRate\": 24000\n}") .asBytes(); Files.write(Paths.get("output.webm"), response.getBody()); ``` # Websockets Source: https://docs.rime.ai/api-reference/coda/websockets GET wss://users-ws.rime.ai/ws Coda plain-text WebSocket (/ws): send text, receive raw audio bytes. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. Include `modelId=coda` in the connection query. If you omit it, the server routes the request to Mist v3 and speakers outside the Mist v3 catalog can fail with `Speaker not found`. ## Overview Rime's websocket implementation accepts bare text, and responds with audio bytes of the selected format. All synthesis arguments are provided as query parameters when establishing the connection. ## Messages ### Send The messages your client will send to the websocket API will be bare (non-serialized) text. ```example theme={null} This will be converted to audio via websockets ``` ### Receive The messages your client will receive will be raw audio bytes in the audio format specified at connection time. ```example theme={null} ^@^@^@9LAME3.100^AP^@^@^@^@^@^@^@^@^T$^D>"^@^@^@^@<9D>G^N^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^@^@^@^@^@^@^@ ``` ## Commands Use these commands to manipulate the stored text buffer. ### `` This clears the current buffer. Used in the event of interruptions. ### `` This forces whatever buffer exists, if any, to be synthesized, and the generated audio to be sent over. ### `` This forces whatever buffer exists, if any, to be synthesized, and for the server to close the connection after sending the generated audio. ## Variable parameters Must be a `coda` voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set this to `coda`. It is not strictly required, but if you omit it the server defaults to the Mist v3 backend, and speakers outside the Mist v3 catalog fail with a "Speaker not found" error. One of `mp3`, `ogg`, `mulaw`, or `pcm` If provided, the language must match the language spoken by the provided speaker. Both the 2-letter ISO 639-1 and the 3-letter ISO 639-2/3 form are accepted: | 639-1 | 639-2/3 | Language | | ----- | ------- | ---------- | | `en` | `eng` | English | | `es` | `spa` | Spanish | | `fr` | `fra` | French | | `pt` | `por` | Portuguese | | `de` | `ger` | German | | `ja` | `jpn` | Japanese | | `ar` | `ara` | Arabic | | `hi` | `hin` | Hindi | See the voices documentation for which speakers support each language. The sampling rate (Hz). * **On-cloud**: Accepted values: 8000, 16000, 22050, 24000, 44100, 48000, 96000. Anything above 24000 is up sampling. * **On-prem**: Any value is accepted. Controls how text is segmented for synthesis. Available options: * "immediate" - Synthesizes text immediately without waiting for complete sentences * "never" - Never segments the text, waits for explicit flush or EOS * "bySentence" (default) - Waits for complete sentences before synthesis Note: For backward compatibility, setting `immediate=true` in query params is equivalent to `segment=immediate`. If a null value is provided, it will default to "bySentence". ```python Python theme={null} import asyncio import websockets import os from dotenv import load_dotenv load_dotenv() api_key = os.environ.get('RIME_API_KEY') if not api_key: raise ValueError("RIME_API_KEY environment variable is not set") FILE_PATH = "coda_ws.wav" class RimeClient: def __init__(self, speaker, api_key): self.url = f"wss://users-ws.rime.ai/ws?speaker={speaker}&modelId=coda&audioFormat=wav" self.auth_headers = { "Authorization": f"Bearer {api_key}" } self.audio_data = b'' async def send_tokens(self, websocket, message): for token in message: await websocket.send(token) async def handle_audio(self, websocket): while True: try: audio = await websocket.recv() except websockets.exceptions.ConnectionClosedOK: break self.audio_data += audio async def run(self, message): async with websockets.connect(self.url, additional_headers=self.auth_headers) as websocket: await asyncio.gather( self.send_tokens(websocket, message), self.handle_audio(websocket), ) def save_audio(self, file_path): with open(file_path, 'wb') as f: f.write(self.audio_data) message = [ "This ", "is ", "a ", "test ", "of ", "the ", "coda ", "model ", "using ", "websockets ", "and ", "python.", "", ] client = RimeClient("astra", api_key=api_key) asyncio.run(client.run(message)) print(f"Saving audio to {FILE_PATH}") client.save_audio(FILE_PATH) ``` # Websockets JSON Source: https://docs.rime.ai/api-reference/coda/websockets-json GET wss://users-ws.rime.ai/ws3 Coda JSON WebSocket (/ws3): structured events with base64 audio chunks and word-level timestamps. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. Include `modelId=coda` in the connection query. If you omit it, the server routes the request to Mist v3 and speakers outside the Mist v3 catalog can fail with `Speaker not found`. ## Overview In addition to a plaintext websocket implementation, Rime also has an implementation that sends and receives events as JSON objects. Like the other implementation, all synthesis arguments are provided as query parameters when establishing the connection. The WebSocket API buffers inputs up to one of the following punctuation characters: `.`, `?`, `!`. This is most pertinent for the initial messages sent to the API, as synthesis won't begin until there are sufficient tokens to generate audio with natural prosody. After the first synthesis of any given utterance, typically enough time has elapsed that subsequent audio contains multiple clauses, and the buffering becomes largely invisible. ## Messages ### Send #### Text This is the most common message, which contains text for synthesis. schema: ```typescript theme={null} type TextMessage = { text: string, contextId?: string, } ``` examples: ```json theme={null} { "text": "this is the minimum text message." } { "text": "this is a text message with a context id.", "contextId": "159495B1-5C81-4C73-A51A-9CE10A08239E" } ``` Context IDs can be provided, which will be attached to subsequent messages that the server sends back to the client. Rime will not maintain multiple simultaneous context IDs. The events will contain the most recent context ID at the time that audio was requested. In the above examples, even if both messages are received by the server before it sends any audio, the audio response for the first sentence will be tagged with `contextId: null`, and the audio for the second will be tagged with its UUID. #### Clear Your client can clear out the accumulated buffer, which is useful in the case of interruptions. ```json theme={null} { "operation": "clear" } ``` #### Flush This forces whatever buffer exists, if any, to be synthesized, and the generated audio to be sent over. ```json theme={null} { "operation": "flush" } ``` #### EOS At times, your client would like to generate audio for whatever remains in the buffer, and then have the connection immediately closed. ```json theme={null} { "operation" : "eos" } ``` ### Receive #### Chunk The most common event will be the audio chunk. ```typescript theme={null} type Base64String = string type AudioChunkEvent = { type: "chunk", data: Base64String, contextId: string | null, } ``` The audio will be a base64 encoded chunk of audio bytes in the audio format specified when the connection was established. If you provided any context id when sending the relevant text, it'll be included here. #### Timestamps Word-level timestamps are emitted alongside the audio chunks so the client can tell exactly which words have been spoken at any point. This is especially useful for handling interruptions: when the user starts talking over the output, you can map the playback position back to the last word that was actually heard. Timestamps are emitted only when `lang` is `en`/`eng` or `es`/`spa`, or when `lang` is omitted. Requests in any other language receive `chunk` and `done` events with no `timestamps` event and no error (this includes fr, de, ja, pt, ar, and hi). Do not block playback while waiting for a timestamps event. ```typescript theme={null} type TimestampsEvent = { type: "timestamps", word_timestamps: { words: string[], start: number[], end: number[], }, contextId: string | null, } ``` The three arrays inside `word_timestamps` are the same length and index-aligned: for a given index `i`, `words[i]` is spoken from `start[i]` to `end[i]`. Times are in seconds, measured from the beginning of the audio for the current synthesis. If a context id was attached to the text that produced this audio, it is included on the event. Example payload: ```json theme={null} { "type": "timestamps", "word_timestamps": { "words": ["Hello", "from", "Coda", "over", "JSON", "websockets."], "start": [0, 0.36106, 0.54159, 0.72212, 0.90265, 1.08318], "end": [0.36106, 0.54159, 0.72212, 0.90265, 1.08318, 2.88848] }, "contextId": null } ``` #### Done After the last audio chunk for a synthesis batch has been sent, the server emits a `done` event. This signals that the current synthesis is fully complete. If the client sends more text and triggers further synthesis, another `done` will follow. ```typescript theme={null} type DoneEvent = { type: "done", contextId: string | null, } ``` When exactly `done` fires depends on the `segment` setting. See [Segmentation and behavior settings](/docs/websockets-segment) for full details. #### Error In the event of a malformed or unexpected input, the server will immediately respond with an error message. The server will *not* close the connection, and will still accept subsequent well-formed messages. It's up to the client to decide if it wants to close upon receiving an error. ```typescript theme={null} type ErrorEvent = { type: "error", message: string, } ``` ## Variable parameters Must be a `coda` voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set this to `coda`. It is not strictly required, but if you omit it the server defaults to the Mist v3 backend, and speakers outside the Mist v3 catalog fail with a "Speaker not found" error. One of `mp3`, `mulaw`, or `pcm` If provided, the language must match the language spoken by the provided speaker. Both the 2-letter ISO 639-1 and the 3-letter ISO 639-2/3 form are accepted: | 639-1 | 639-2/3 | Language | | ----- | ------- | ---------- | | `en` | `eng` | English | | `es` | `spa` | Spanish | | `fr` | `fra` | French | | `pt` | `por` | Portuguese | | `de` | `ger` | German | | `ja` | `jpn` | Japanese | | `ar` | `ara` | Arabic | | `hi` | `hin` | Hindi | See the voices documentation for which speakers support each language. The sampling rate (Hz). * **On-cloud**: Accepted values: 8000, 16000, 22050, 24000, 44100, 48000, 96000. Anything above 24000 is up sampling. * **On-prem**: Any value is accepted. Controls how text is segmented for synthesis. Available options: * "immediate" - Synthesizes text immediately without waiting for complete sentences * "never" - Never segments the text, waits for explicit flush or EOS * "bySentence" (default) - Waits for complete sentences before synthesis Note: For backward compatibility, setting `immediate=true` in query params is equivalent to `segment=immediate`. If a null value is provided, it will default to "bySentence". ```python Python theme={null} import asyncio import json import websockets import base64 class RimeClient: def __init__(self, speaker, api_key): self.url = f"wss://users-ws.rime.ai/ws3?speaker={speaker}&modelId=coda&audioFormat=mp3" self.auth_headers = { "Authorization": f"Bearer {api_key}" } self.audio_data = b'' async def send_messages(self, websocket, messages): for message in messages: await websocket.send(json.dumps(message)) async def handle_audio(self, websocket): while True: try: audio = await websocket.recv() except websockets.exceptions.ConnectionClosedOK: break message = json.loads(audio) if message['type'] == 'chunk': self.audio_data += base64.b64decode(message['data']) if message['type'] == 'timestamps': print("Rime model pronounced the words...\n") for w, t in zip(message['word_timestamps']['words'], message['word_timestamps']['start']): print(f"'{w}' at time {t}") async def run(self, messages): async with websockets.connect(self.url, additional_headers=self.auth_headers) as websocket: await asyncio.gather( self.send_messages(websocket, messages), self.handle_audio(websocket), ) def save_audio(self, file_path): with open(file_path, 'wb') as f: f.write(self.audio_data) print(f"\n Audio saved at {file_path}") message = [ {"text": "This "}, {"text": "is "}, {"text": "a "}, {"text": "test "}, {"operation":"clear"}, {"text": "This "}, {"text": "is "}, {"text": "an "}, {"text": "incomplete "}, {"text": "sentence "}, {"operation": "eos"}, ] client = RimeClient("astra", api_key="xxx") asyncio.run(client.run(message)) client.save_audio("output.mp3") ``` # List Voice Details Source: https://docs.rime.ai/api-reference/data/voice-details GET https://users.rime.ai/data/voices/voice_details.json Voice metadata endpoint: list every Rime voice with demographic and model details. This is a public endpoint; no `Authorization` header or API key is required. ## View in browser [https://users.rime.ai/data/voices/voice\_details.json](https://users.rime.ai/data/voices/voice_details.json) ## Description These details are based on subjective assessment and are meant to serve as a general guide. They describe the demographics of the voices and don't represent API parameters. Please see [Finding a Voice](/docs/voices) and the [Explanation of Fields section](#explanation-of-fields) for more information. ## Example structure ```json theme={null} [ { "speaker": "astra", "gender": "Female", "age": "Young Adult", "country": "US", "dialect": "American", "demographic": "White", "genre": [ "Any" ], "modelId": "coda", "language": "English", "lang": "eng", "flagship": true }, { "speaker": "cove", "gender": "Male", "age": "Middle", "country": "US", "dialect": "Generic", "demographic": "General American", "genre": [ "Conversational" ], "modelId": "mistv3", "language": "English", "lang": "eng" }, // and more... ] ``` ## Explanation of fields The response object is an array of objects, each representing a voice. Each object contains the following fields: * `speaker`: Represents the name of the voice. * `gender`: Indicates the gender of the voice. * `age`: Describes the age group of the voice. * `country`: The country that the voice is associated with, typically representing the accent or regional dialect. * `dialect`: More specific than country, this field can indicate a particular area within a country. * `demographic`: Describes the demographic group the voice represents. * `genre`: An array of genres that the voice is suitable for, such as 'Conversational'. * `language`: The spoken language that the model is usable for. * `lang`: This is the value you pass to specify the language the selected speaker should speak * `modelId`: The model id that the speaker is available under # List All Voices Source: https://docs.rime.ai/api-reference/data/voices-v2 GET https://users.rime.ai/data/voices/all-v2.json List every Rime voice, keyed by modelId and language. This is a public endpoint; no `Authorization` header or API key is required. ## View in browser [https://users.rime.ai/data/voices/all-v2.json](https://users.rime.ai/data/voices/all-v2.json) ## Example structure ```json theme={null} { "coda": { "eng": [ "astra", "albion", // ...and more... ], "spa": [ "aurelio", "celestino", // ...and more... ] }, "mistv3": { "eng": [ "alexis", "astra", // ...and more... ], "spa": [ "diego", "isa", // ...and more... ] } } ``` ## Explanation The response object is keyed by the applicable `modelId`. Pass the same `modelId` to the [Rime TTS APIs](/docs/api-reference). It is then further keyed by an ISO 639-2 language code. # Streaming HTTP Source: https://docs.rime.ai/api-reference/mistv2/http POST https://users.rime.ai/v1/rime-tts Mist v2 streaming HTTP endpoint. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. The streaming endpoint returns audio bytes in the format specified by the `Accept` header. ## Audio formats Set the `Accept` header to one of the following values: | Format | Accept Header | Default Sampling Rate | Notes | | ----------- | ------------- | --------------------- | ------------------------------------------- | | MP3 | `audio/mpeg` | 22050 | | | PCM | `audio/L16` | 16000 | Headerless 16-bit little-endian linear PCM. | | G.711 μ-law | `audio/PCMU` | 8000 | Headerless stream of audio bytes. | ### Deprecated aliases Still accepted for backwards compatibility; new code should use the RFC types above. | Deprecated | Use instead | | --------------- | ------------ | | `audio/mp3` | `audio/mpeg` | | `audio/pcm` | `audio/L16` | | `audio/x-mulaw` | `audio/PCMU` | ## Variable parameters Must be a voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set to `mistv2`. If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds.
Example: "Hi. \<200> I'd love to have a conversation with you." adds a 200ms pause between the first and second sentences.
When set to true, you can specify the phonemes for a word enclosed in curly brackets.
Example: "\{h'El.o} World" will pronounce "Hello" as expected. Learn more about custom pronunciation.
Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. The value, if provided, must be between 4000 and 44100. Default depends on format (see table above). Adjusts the speed of speech. Lower than 1.0 is faster and higher than 1.0 is slower. *Note: this is the legacy Mist v2 convention. Coda and Mist v3 invert it; for those, higher than 1.0 is faster.* **mist/mistv2 only.** Skips text normalization of the input text prior to synthesizing audio. This will reduce latency at the cost of some possible mispronunciation of digits and abbreviations. ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Accept: audio/mpeg' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --output output.mp3 \ --fail \ --data '{ "text": "Hello from Rime!", "modelId": "mistv2", "speaker": "astra", "lang": "eng", "samplingRate": 22050, "speedAlpha": 1.0 }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/v1/rime-tts" payload = { "speaker": "astra", "text": "Hello from Rime!", "modelId": "mistv2", "lang": "eng", "samplingRate": 22050, "speedAlpha": 1.0 } headers = { "Accept": "audio/mpeg", "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } with requests.post(url, headers=headers, json=payload, stream=True) as response: response.raise_for_status() with open("output.mp3", "wb") as f: for chunk in response.iter_content(chunk_size=4096): if chunk: f.write(chunk) ``` ```javascript JavaScript theme={null} const options = { method: 'POST', headers: { Accept: 'audio/mpeg', Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: '{"speaker":"astra","text":"Hello from Rime!","modelId":"mistv2","lang":"eng","samplingRate":22050,"speedAlpha":1.0}' }; fetch('https://users.rime.ai/v1/rime-tts', options) .then(response => response.arrayBuffer()) .then(buffer => { require("fs").writeFileSync("output.mp3", Buffer.from(buffer)); console.log("Audio saved to output.mp3"); }) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/v1/rime-tts", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"mistv2\",\n \"lang\": \"eng\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0\n}", CURLOPT_HTTPHEADER => [ "Accept: audio/mpeg", "Authorization: Bearer YOUR_API_KEY", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "io" "net/http" "os" "strings" ) func main() { url := "https://users.rime.ai/v1/rime-tts" payload := strings.NewReader("{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"mistv2\",\n \"lang\": \"eng\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "audio/mpeg") req.Header.Add("Authorization", "Bearer YOUR_API_KEY") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) _ = os.WriteFile("output.mp3", body, 0644) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/v1/rime-tts") .header("Accept", "audio/mpeg") .header("Authorization", "Bearer YOUR_API_KEY") .header("Content-Type", "application/json") .body("{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"mistv2\",\n \"lang\": \"eng\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0\n}") .asString(); ``` # MP3 over JSON Source: https://docs.rime.ai/api-reference/mistv2/json-mp3 POST https://users.rime.ai/v1/rime-tts Mist v2 non-streaming endpoint that returns base64 MP3 audio inside a JSON envelope. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Fixed parameters ## Variable parameters Must be a voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set to `mistv2`. If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds.
Example: "Hi. \<200> I'd love to have a conversation with you." adds a 200ms pause between the first and second sentences.
When set to true, you can specify the phonemes for a word enclosed in curly brackets.
Example: "\{h'El.o} World" will pronounce "Hello" as expected. Learn more about custom pronunciation.
Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: For text "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. The value, if provided, must be between 4000 and 44100. Default: 22050 Adjusts the speed of speech. Lower than 1.0 is faster and higher than 1.0 is slower. *Note: this is the legacy Mist v2 convention. Coda and Mist v3 invert it; for those, higher than 1.0 is faster.* **mist/mistv2 only.** Skips text normalization of the input text prior to synthesizing audio. This will reduce latency at the cost of some possible mispronunciation of digits and abbreviations. ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Accept: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --output output.json \ --fail \ --data '{ "text": "Hello from Rime!", "modelId": "mistv2", "speaker": "astra", "lang": "eng", "audioFormat": "mp3", "inlineSpeedAlpha": "0.5, 3", "noTextNormalization": false, "pauseBetweenBrackets": false, "phonemizeBetweenBrackets": false, "samplingRate": 22050, "speedAlpha": 1.0 }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/v1/rime-tts" payload = { "speaker": "", "text": "", "modelId": "", "lang": "eng", "audioFormat": "mp3", "samplingRate": 22050, "speedAlpha": 1.0, "noTextNormalization": False } headers = { "Accept": "application/json", "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.request("POST", url, json=payload, headers=headers) print(response.text) ``` ```javascript JavaScript theme={null} const options = { method: 'POST', headers: { Accept: 'application/json', Authorization: 'Bearer ', 'Content-Type': 'application/json' }, body: '{"speaker":"","text":"", "modelId": "", "lang": "eng", "audioFormat": "mp3", "samplingRate":22050,"speedAlpha":1.0,"noTextNormalization":false}' }; fetch('https://users.rime.ai/v1/rime-tts', options) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/v1/rime-tts", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\":\"\",\n \"lang\":\"eng\",\n \"audioFormat\": \"mp3\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}", CURLOPT_HTTPHEADER => [ "Accept: application/json", "Authorization: Bearer ", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://users.rime.ai/v1/rime-tts" payload := strings.NewReader("{\n \"speaker\": \"\",\n \"modelId\": \"\",\n \"text\": \"\",\n \"lang\": \"eng\",\n \"audioFormat\": \"mp3\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "application/json") req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/v1/rime-tts") .header("Accept", "application/json") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\": \"eng\",\n \"audioFormat\": \"mp3\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") .asString(); ``` # μ-law over JSON Source: https://docs.rime.ai/api-reference/mistv2/json-mulaw POST https://users.rime.ai/v1/rime-tts Mist v2 non-streaming endpoint that returns base64 G.711 μ-law audio inside a JSON envelope. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Fixed parameters ## Variable parameters Must be a voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set to `mistv2`. If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds.
Example: "Hi. \<200> I'd love to have a conversation with you." adds a 200ms pause between the first and second sentences.
When set to true, you can specify the phonemes for a word enclosed in curly brackets.
Example: "\{h'El.o} World" will pronounce "Hello" as expected. Learn more about custom pronunciation.
Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. Adjusts the speed of speech. Lower than 1.0 is faster and higher than 1.0 is slower. *Note: this is the legacy Mist v2 convention. Coda and Mist v3 invert it; for those, higher than 1.0 is faster.* **mist/mistv2 only.** Skips text normalization of the input text prior to synthesizing audio. This will reduce latency at the cost of some possible mispronunciation of digits and abbreviations. ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Accept: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --output output.json \ --fail \ --data '{ "text": "Hello from Rime!", "modelId": "mistv2", "speaker": "astra", "lang": "eng", "audioFormat": "mulaw", "inlineSpeedAlpha": "0.5, 3", "noTextNormalization": false, "pauseBetweenBrackets": false, "phonemizeBetweenBrackets": false, "speedAlpha": 1.0 }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/v1/rime-tts" payload = { "speaker": "", "text": "", "modelId": "mistv2", "lang": "eng", "audioFormat": "mulaw", "speedAlpha": 1.0, "noTextNormalization": False, "pauseBetweenBrackets": False, "phonemizeBetweenBrackets": False } headers = { "Accept": "application/json", "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.request("POST", url, json=payload, headers=headers) print(response.text) ``` ```javascript JavaScript theme={null} const options = { method: 'POST', headers: { Accept: 'application/json', Authorization: 'Bearer ', 'Content-Type': 'application/json' }, body: '{"speaker":"","text":"","modelId":"","lang": "eng","audioFormat": "mulaw","speedAlpha":1.0,"noTextNormalization":false}' }; fetch('https://users.rime.ai/v1/rime-tts', options) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/v1/rime-tts", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\":\"eng\",\n \"audioFormat\": \"mulaw\",\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}", CURLOPT_HTTPHEADER => [ "Accept: application/json", "Authorization: Bearer ", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://users.rime.ai/v1/rime-tts" payload := strings.NewReader("{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\": \"eng\",\n \"audioFormat\": \"mulaw\",\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "application/json") req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/v1/rime-tts") .header("Accept", "application/json") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\": \"eng\",\n \"audioFormat\": \"mulaw\",\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") .asString(); ``` # OGG over JSON Source: https://docs.rime.ai/api-reference/mistv2/json-ogg POST https://users.rime.ai/v1/rime-tts Mist v2 non-streaming endpoint that returns base64 Opus/Ogg audio inside a JSON envelope. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Fixed parameters ## Variable parameters Must be a voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds.
Example: "Hi. \<200> I'd love to have a conversation with you." adds a 200ms pause between the first and second sentences.
When set to true, you can specify the phonemes for a word enclosed in curly brackets.
Example: "\{h'El.o} World" will pronounce "Hello" as expected. Learn more about custom pronunciation.
Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. Must be one of `8000`, `12000`, `16000`, or `24000` Set to `mistv2`. Adjusts the speed of speech. Lower than 1.0 is faster and higher than 1.0 is slower. *Note: this is the legacy Mist v2 convention. Coda and Mist v3 invert it; for those, higher than 1.0 is faster.* **mist/mistv2 only.** Skips text normalization of the input text prior to synthesizing audio. This will reduce latency at the cost of some possible mispronunciation of digits and abbreviations. ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Accept: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --output output.json \ --fail \ --data '{ "text": "Hello from Rime!", "modelId": "mistv2", "speaker": "astra", "lang": "eng", "audioFormat": "ogg", "inlineSpeedAlpha": "0.5, 3", "noTextNormalization": false, "pauseBetweenBrackets": false, "phonemizeBetweenBrackets": false, "samplingRate": 24000, "speedAlpha": 1.0 }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/v1/rime-tts" payload = { "speaker": "", "text": "", "modelId": "mistv2", "lang": "eng", "audioFormat": "ogg", "samplingRate": 24000, "speedAlpha": 1.0, "noTextNormalization": False, "pauseBetweenBrackets": False, "phonemizeBetweenBrackets": False } headers = { "Accept": "application/json", "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.request("POST", url, json=payload, headers=headers) print(response.text) ``` ```javascript JavaScript theme={null} const options = { method: 'POST', headers: { Accept: 'application/json', Authorization: 'Bearer ', 'Content-Type': 'application/json' }, body: '{"speaker":"","text":"","modelId":"", "lang": "eng", "audioFormat": "ogg","samplingRate":24000,"speedAlpha":1.0,"noTextNormalization":false}' }; fetch('https://users.rime.ai/v1/rime-tts', options) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/v1/rime-tts", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\":\"eng\",\n \"audioFormat\": \"ogg\",\n \"samplingRate\": 24000,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}", CURLOPT_HTTPHEADER => [ "Accept: application/json", "Authorization: Bearer ", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://users.rime.ai/v1/rime-tts" payload := strings.NewReader("{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\": \"eng\",\n \"audioFormat\": \"ogg\",\n \"samplingRate\": 24000,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "application/json") req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/v1/rime-tts") .header("Accept", "application/json") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\": \"eng\",\n \"audioFormat\": \"ogg\",\n \"samplingRate\": 24000,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") .asString(); ``` # WAV over JSON Source: https://docs.rime.ai/api-reference/mistv2/json-wav POST https://users.rime.ai/v1/rime-tts Mist v2 non-streaming endpoint that returns base64 WAV audio inside a JSON envelope. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Fixed parameters ## Variable parameters Must be a voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. Set to `mistv2`. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds.
Example: "Hi. \<200> I'd love to have a conversation with you." adds a 200ms pause between the first and second sentences.
When set to true, you can specify the phonemes for a word enclosed in curly brackets.
Example: "\{h'El.o} World" will pronounce "Hello" as expected. Learn more about custom pronunciation.
Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. The value, if provided, must be between 4000 and 44100. Default: 22050 Adjusts the speed of speech. Lower than 1.0 is faster and higher than 1.0 is slower. *Note: this is the legacy Mist v2 convention. Coda and Mist v3 invert it; for those, higher than 1.0 is faster.* **mist/mistv2 only.** Skips text normalization of the input text prior to synthesizing audio. This will reduce latency at the cost of some possible mispronunciation of digits and abbreviations. ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Accept: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --output output.json \ --fail \ --data '{ "text": "Hello from Rime!", "modelId": "mistv2", "speaker": "astra", "lang": "eng", "audioFormat": "wav", "inlineSpeedAlpha": "0.5, 3", "noTextNormalization": false, "pauseBetweenBrackets": false, "phonemizeBetweenBrackets": false, "samplingRate": 22050, "speedAlpha": 1.0 }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/v1/rime-tts" payload = { "speaker": "", "text": "", "modelId": "", "lang": "eng", "audioFormat": "wav", "samplingRate": 22050, "speedAlpha": 1.0, "noTextNormalization": False, "phonemizeBetweenBrackets": False, "pauseBetweenBrackets": False } headers = { "Accept": "application/json", "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.request("POST", url, json=payload, headers=headers) print(response.text) ``` ```javascript JavaScript theme={null} const options = { method: 'POST', headers: { Accept: 'application/json', Authorization: 'Bearer ', 'Content-Type': 'application/json' }, body: '{"speaker":"","text":"","modelId":"", "lang": "eng", "audioFormat": "wav","samplingRate":22050,"speedAlpha":1.0,"noTextNormalization":false}' }; fetch('https://users.rime.ai/v1/rime-tts', options) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/v1/rime-tts", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\":\"eng\",\n \"audioFormat\": \"wav\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}", CURLOPT_HTTPHEADER => [ "Accept: application/json", "Authorization: Bearer ", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://users.rime.ai/v1/rime-tts" payload := strings.NewReader("{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\": \"eng\",\n \"audioFormat\": \"wav\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "application/json") req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/v1/rime-tts") .header("Accept", "application/json") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"speaker\": \"\",\n \"text\": \"\",\n \"audioFormat\": \"wav\", \n \"modelId\": \"\", \n \"lang\": \"eng\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") .asString(); ``` # Server-sent Events Source: https://docs.rime.ai/api-reference/mistv2/sse POST https://users.rime.ai/v1/rime-tts Mist v2 Server-Sent Events endpoint for streaming audio chunks over text/event-stream. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Fixed headers ## Variable parameters Must be a voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set to `mistv2`. One of `mp3`, `mulaw`, or `pcm` If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds.
Example: "Hi. \<200> I'd love to have a conversation with you." adds a 200ms pause between the first and second sentences.
When set to true, you can specify the phonemes for a word enclosed in curly brackets.
Example: "\{h'El.o} World" will pronounce "Hello" as expected. Learn more about custom pronunciation.
Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. The value, if provided, must be between 4000 and 44100. Default: 22050 Adjusts the speed of speech. Lower than 1.0 is faster and higher than 1.0 is slower. *Note: this is the legacy Mist v2 convention. Coda and Mist v3 invert it; for those, higher than 1.0 is faster.* **mist/mistv2 only.** Skips text normalization of the input text prior to synthesizing audio. This will reduce latency at the cost of some possible mispronunciation of digits and abbreviations. ## Example output ``` event: chunk data: {"data": "vv+t/7j/sv+8/8j/zv/U/9T/z//P/87/yv/J/8n/0//X/9r/5f/p/+//8f/y//b/8f/x//P/9v/+/wAAAAD3/+3/7v/v//X/+P/0//r/8v/r//D/8P/x/+v/7P/1//D/7//0//b/9//7//r/8//5//7/9//8/wYABwAHAAgADAAKAAEA///8//n/9P/w/+//7P/p/+L/5f/l/+D/6v/s/+//9f/r/+z/8P/u/+//8//t/+j/7//t/9//3//f/97/4P/f/+D/4P/k/+P/3v/f/9//4//p/+b/5f/l/9z/4f/p/+H/5//m/+H/8P/x/+7/9f/9//z/8//2//r/9v/w/+//8f/p/+P/4f/d/9z/2//Z/9r/3P/e/9z/4P/k/+L/4//f/9z/2f/a/9v/0v/N/8n/yf/J/8D/tv+z/7f/s/+x/7f/sv+x/8D/xP/C/8b/yv/S/9H/xf/D/8n/zv/S/8//0P/X/9D/z//X/9T/0P/L/8X/yP/S/9X/0f/L/83/1f/b/+D/2//W/9X/0P/U/9j/0P/U/9n/2v/i/+v/8v/s/9z/2f/U/8f/yP/M/8n/yf/P/9D/yf/Q/8r/xP/Q/8v/zf/T/9L/2v/Z/9z/5v/o/+j/6f/o/+b/5//o//H/+P/z//L/7//o/+T/5P/m/+3/7//v//P/6//p//P/8P/p/+X/4//j/+X/6P/l/+X/7P/o/9//5P/h/9n/2//b/93/5f/g/9r/0//L/8//yf++/7//vP+8/8H/wf/C/8H/v/+6/7T/sf+u/63/qv+t/6//q/+t/6v/p/+l/6T/pf+t/7L/r/+u/7f/vf+7/7r/vf+6/7v/u//A/83/yf/I/w=="} event: chunk data: {"data": "zP/J/8P/uP+8/7r/tf+//7j/tP+3/7X/uv+//8H/x//F/8L/yf/J/8n/y//H/8P/vf+7/73/xv/J/8r/z//N/8//yf/D/8P/xf/M/8z/yP/G/8H/vP+//8X/xf/J/8//0P/P/9T/2P/Y/9v/2f/Z/9//2v/d/+H/3f/d/9v/0//U/9j/1v/Z/+L/6v/s/+7/6v/g/9v/1//P/8n/x//I/8f/v/+3/7X/uP+7/7T/tP+6/7T/sP+6/8P/zP/Q/8z/z//T/9j/4f/c/+D/5v/d/+X/7v/o/+n/6v/o/+j/6P/i/9z/2//f/9z/3P/e/9j/2f/g/+z/7v/q/+n/5v/r//L/8v/n/9z/5P/u/+3/6f/p/+//7//o/+r/9P/v//H/+P/t/+//9f/2//T/8P/1//X/9f/+/wcABAAIABIAFAAYABcAEwAYABgAGwAlACgAKAAoACQAJAAnACYAJwAoACAAGwAiACYAKQArACsALwAuACkAKwAqACkAJQAXABcAGAAQABIAGAAaABgAHgAlACIAJAAjACUAKwAkACEAJAAjACYAKwAzADUAMAAyADgAMwArAC8AMgA0ADgAOAA6ADYAPABCAEEARABHAEQAQwBDAD8APQBDAEUARgBDADsAPgBBADgAPABDAD4ARQBMAEkARwBCAEIAQwBFAEcAQABCAEcAPgBBAEYAQwA7ADYAPQBDAEcARABEAEgARwBOAE0ARwBOAE0ASABEADgANQA2ADoAQAA5ADIANQA0ADUAOQA5ADwAQgBDAEIARQBGAEIAPgA9AD4AOwA7ADsAQwBJAEYAVQBaAFUAUwBNAFIAVgBQAE8AUgBYAFQATQBQAA=="} event: timestamps data: {"word_timestamps": {"words": ["over", "the", "last", "six", "months", ",", "there", "has", "been", "a", "lot", "of", "talk", "about", "the", "future", "of", "theatrical", "exhibition"], "start": [0, 0.624, 0.816, 1.12, 1.52, 2.08, 2.3, 2.496, 2.7, 2.896, 3.024, 3.232, 3.408, 3.664, 4.0, 4.192, 4.608, 4.768, 5.456], "end": [0.624, 0.816, 1.12, 1.52, 2.08, 2.304, 2.496, 2.704, 2.896, 3.024, 3.232, 3.408, 3.664, 4.0, 4.192, 4.608, 4.768, 5.456, 6.672]}} event: done data: {"done": true} ``` ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Accept: text/event-stream' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --output output.txt \ --fail \ --data '{ "text": "Hello from Rime!", "modelId": "mistv2", "speaker": "astra", "lang": "eng", "inlineSpeedAlpha": "0.5, 3", "noTextNormalization": false, "pauseBetweenBrackets": false, "phonemizeBetweenBrackets": false, "samplingRate": 22050, "speedAlpha": 1.0 }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/v1/rime-tts" payload = { "speaker": "", "text": "", "modelId": "", "lang": "eng", "samplingRate": 22050, "speedAlpha": 1.0, "noTextNormalization": False, "pauseBetweenBrackets": False, "phonemizeBetweenBrackets": False } headers = { "Accept": "text/event-stream", "Authorization": "Bearer ", "Content-Type": "application/json" } # Use stream=True to handle streaming response response = requests.request("POST", url, json=payload, headers=headers, stream=True) # Check if the request was successful if response.status_code == 200: with open("audio_output.mp3", "wb") as f: for chunk in response.iter_content(chunk_size=1024): if chunk: f.write(chunk) else: print("Error:", response.status_code) print(response.text) ``` ```javascript JavaScript theme={null} const options = { method: 'POST', headers: { Accept: 'text/event-stream', Authorization: 'Bearer ', 'Content-Type': 'application/json' }, body: '{"speaker":"","text":"","modelId":"","lang": "eng", "samplingRate":22050,"speedAlpha":1.0,"noTextNormalization":false}' }; fetch('https://users.rime.ai/v1/rime-tts', options) .then(response => response.text()) .then(response => console.log(response)) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/v1/rime-tts", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\":\"eng\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}", CURLOPT_HTTPHEADER => [ "Accept: text/event-stream", "Authorization: Bearer ", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://users.rime.ai/v1/rime-tts" payload := strings.NewReader("{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\": \"eng\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "text/event-stream") req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/v1/rime-tts") .header("Accept", "text/event-stream") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"speaker\": \"\",\n \"text\": \"\",\n \"modelId\": \"\",\n \"lang\": \"eng\",\n \"samplingRate\": 22050,\n \"speedAlpha\": 1.0,\n \"noTextNormalization\": false\n}") .asString(); ``` # Websockets Source: https://docs.rime.ai/api-reference/mistv2/websockets GET wss://users-ws.rime.ai/ws Mist v2 plain-text WebSocket (/ws): send text, receive raw audio bytes. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Overview Rime's websocket implementation accepts bare text, and responds with audio bytes of the selected format. All synthesis arguments are provided as query parameters when establishing the connection. The WebSocket API buffers inputs up to one of the following punctuation characters: `.`, `,`, `?`, `!`. This is most pertinent for the initial messages sent to the API, as synthesis won't begin until there are sufficient tokens to generate audio with natural prosody. After the first synthesis of any given utterance, typically enough time has elapsed that subsequent audio contains multiple clauses, and the buffering becomes largely invisible. ## Messages ### Send The messages your client will send to the websocket API will be bare (non-serialized) text. ```example theme={null} This will be converted to audio via websockets ``` ### Receive The messages your client will receive will be raw audio bytes in the audio format specified at connection time. ```example theme={null} ^@^@^@9LAME3.100^AP^@^@^@^@^@^@^@^@^T$^D>"^@^@^@^@<9D>G^N^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^@^@^@^@^@^@^@ ``` ## Commands Use these commands to manipulate the stored text buffer. ### `` This clears the current buffer. Used in the event of interruptions. ### `` This forces whatever buffer exists, if any, to be synthesized, and the generated audio to be sent over. ### `` This forces whatever buffer exists, if any, to be synthesized, and for the server to close the connection after sending the generated audio. ## Variable parameters Must be a voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set to `mistv2`. One of `mp3`, `mulaw`, or `pcm` If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds.
Example: "Hi. \<200> I'd love to have a conversation with you." adds a 200ms pause between the first and second sentences.
When set to true, you can specify the phonemes for a word enclosed in curly brackets.
Example: "\{h'El.o} World" will pronounce "Hello" as expected. Learn more about custom pronunciation.
Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster.. The value, if provided, must be between 4000 and 44100. Default: 22050 Adjusts the speed of speech. Lower than 1.0 is faster and higher than 1.0 is slower. *Note: this is the legacy Mist v2 convention. Coda and Mist v3 invert it; for those, higher than 1.0 is faster.* **mist/mistv2 only.** Skips text normalization of the input text prior to synthesizing audio. This will reduce latency at the cost of some possible mispronunciation of digits and abbreviations. Controls how text is segmented for synthesis. Available options: * "immediate" - Synthesizes text immediately without waiting for complete sentences * "never" - Never segments the text, waits for explicit flush or EOS * "bySentence" (default) - Waits for complete sentences before synthesis Note: For backward compatibility, setting `immediate=true` in query params is equivalent to `segment=immediate`. If a null value is provided, it will default to "bySentence". ```python Python theme={null} import asyncio import websockets class RimeClient: def __init__(self, speaker, api_key): self.url = f"wss://users-ws.rime.ai/ws?speaker={speaker}&modelId=mistv2&audioFormat=mp3" self.auth_headers = { "Authorization": f"Bearer {api_key}" } self.audio_data = b'' async def send_tokens(self, websocket, message): for token in message: await websocket.send(token) async def handle_audio(self, websocket): while True: try: audio = await websocket.recv() except websockets.exceptions.ConnectionClosedOK: break self.audio_data += audio async def run(self, message): async with websockets.connect(self.url, additional_headers=self.auth_headers) as websocket: await asyncio.gather( self.send_tokens(websocket, message), self.handle_audio(websocket), ) def save_audio(self, file_path): with open(file_path, 'wb') as f: f.write(self.audio_data) message = [ "This ", "is ", "a ", "test ", "", "This ", "is ", "a ", "sentence, ", "that ", "will ", "produce ", "audio ", "across ", "two ", "messages.", "", ] client = RimeClient("cove", api_key="xxx") asyncio.run(client.run(message)) client.save_audio("output.mp3") ``` # Websockets JSON Source: https://docs.rime.ai/api-reference/mistv2/websockets-json GET wss://users-ws.rime.ai/ws2 Mist v2 JSON WebSocket (/ws2): structured events with base64 audio chunks and word-level timestamps. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Overview In addition to a plaintext websocket implementation, Rime also has an implementation that sends and receives events as JSON objects. Like the other implementation, all synthesis arguments are provided as query parameters when establishing the connection. The WebSocket API buffers inputs up to one of the following punctuation characters: `.`, `?`, `!`. This is most pertinent for the initial messages sent to the API, as synthesis won't begin until there are sufficient tokens to generate audio with natural prosody. After the first synthesis of any given utterance, typically enough time has elapsed that subsequent audio contains multiple clauses, and the buffering becomes largely invisible. ## Messages ### Send #### Text This is the most common message, which contains text for synthesis. schema: ```typescript theme={null} type TextMessage = { text: string, contextId?: string, } ``` examples: ```json theme={null} { "text": "this is the minimum text message." } { "text": "this is a text message with a context id.", "contextId": "159495B1-5C81-4C73-A51A-9CE10A08239E" } ``` Context IDs can be provided, which will be attached to subsequent messages that the server sends back to the client. Rime will not maintain multiple simultaneous context ids. The events will contain the most recent context ID at the time that audio was requested. In the above examples, even if both messages are received by the server before it sends any audio, the audio response for the first sentence will be tagged with `contextId: null`, and the audio for the second will be tagged with its UUID. #### Clear Your client can clear out the accumulated buffer, which is useful in the case of interruptions. ```json theme={null} { "operation": "clear" } ``` #### Flush This forces whatever buffer exists, if any, to be synthesized, and the generated audio to be sent over. ```json theme={null} { "operation": "flush" } ``` #### EOS At times, your client would like to generate audio for whatever remains in the buffer, and then have the connection immediately closed. ```json theme={null} { "operation" : "eos" } ``` ### Receive #### Chunk The most common event will be the audio chunk. ```typescript theme={null} type Base64String = string type AudioChunkEvent = { type: "chunk", data: Base64String, contextId: string | null, } ``` The audio will be a base64 encoded chunk of audio bytes in the audio format specified when the connection was established. If you provided any context id when sending the relevant text, it'll be included here. #### Timestamps Word-level timestamps are emitted alongside the audio chunks so the client can tell exactly which words have been spoken at any point. This is especially useful for handling interruptions: when the user starts talking over the output, you can map the playback position back to the last word that was actually heard. Timestamps are emitted only when `lang` is `en`/`eng` or `es`/`spa`, or when `lang` is omitted. Requests in any other language receive `chunk` and `done` events with no `timestamps` event and no error. Do not block playback while waiting for a timestamps event. ```typescript theme={null} type TimestampsEvent = { type: "timestamps", word_timestamps: { words: string[], start: number[], end: number[], }, contextId: string | null, } ``` The three arrays inside `word_timestamps` are the same length and index-aligned: for a given index `i`, `words[i]` is spoken from `start[i]` to `end[i]`. Times are in seconds, measured from the beginning of the audio for the current synthesis. If a context id was attached to the text that produced this audio, it is included on the event. Example payload: ```json theme={null} { "type": "timestamps", "word_timestamps": { "words": ["Hello", "from", "a", "timestamps", "probe", "."], "start": [0, 0.35991, 0.51084, 0.59211, 1.10295, 1.41642], "end": [0.35991, 0.51084, 0.59211, 1.10295, 1.41642, 1.5093] }, "contextId": null } ``` #### Done After the last audio chunk for a synthesis batch has been sent, the server emits a `done` event. This signals that the current synthesis is fully complete. If the client sends more text and triggers further synthesis, another `done` will follow. The `eos` operation always emits a final `done` before the server closes the connection. ```typescript theme={null} type DoneEvent = { type: "done", done: true, contextId: string | null, } ``` On `/ws2`, the `done` event carries an extra boolean `done: true` field in addition to `type: "done"`. On `/ws3` the event contains only `type` and `contextId`. Match on `type === "done"` to handle both. When exactly `done` fires depends on the `segment` setting. See [Segmentation and behavior settings](/docs/websockets-segment) for full details. #### Error In the event of a malformed or unexpected input, the server will immediately respond with an error message. The server will *not* close the connection, and will still accept subsequent well-formed messages. It's up to the client to decide if it wants to close upon receiving an error. ```typescript theme={null} type ErrorEvent = { type: "error", message: string, } ``` ## Variable parameters Must be a voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set to `mistv2`. One of `mp3`, `mulaw`, or `pcm` If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds.
Example: "Hi. \<200> I'd love to have a conversation with you." adds a 200ms pause between the first and second sentences.
When set to true, you can specify the phonemes for a word enclosed in curly brackets.
Example: "\{h'El.o} World" will pronounce "Hello" as expected. Learn more about custom pronunciation.
Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. The value, if provided, must be between 4000 and 44100. Default: 22050 Adjusts the speed of speech. Lower than 1.0 is faster and higher than 1.0 is slower. *Note: this is the legacy Mist v2 convention. Coda and Mist v3 invert it; for those, higher than 1.0 is faster.* **mist/mistv2 only.** Skips text normalization of the input text prior to synthesizing audio. This will reduce latency at the cost of some possible mispronunciation of digits and abbreviations. Controls how text is segmented for synthesis. Available options: * "immediate" - Synthesizes text immediately without waiting for complete sentences * "never" - Never segments the text, waits for explicit flush or EOS * "bySentence" (default) - Waits for complete sentences before synthesis Note: For backward compatibility, setting `immediate=true` in query params is equivalent to `segment=immediate`. If a null value is provided, it will default to "bySentence". ```python Python theme={null} import asyncio import json import websockets import base64 class RimeClient: def __init__(self, speaker, api_key): self.url = f"wss://users-ws.rime.ai/ws2?speaker={speaker}&modelId=mistv2&audioFormat=mp3" self.auth_headers = { "Authorization": f"Bearer {api_key}" } self.audio_data = b'' async def send_messages(self, websocket, messages): for message in messages: await websocket.send(json.dumps(message)) async def handle_audio(self, websocket): while True: try: audio = await websocket.recv() except websockets.exceptions.ConnectionClosedOK: break message = json.loads(audio) if message['type'] == 'chunk': self.audio_data += base64.b64decode(message['data']) if message['type'] == 'timestamps': print("Rime model pronounced the words...\n") for w, t in zip(message['word_timestamps']['words'], message['word_timestamps']['start']): print(f"'{w}' at time {t}") async def run(self, messages): async with websockets.connect(self.url, additional_headers=self.auth_headers) as websocket: await asyncio.gather( self.send_messages(websocket, messages), self.handle_audio(websocket), ) def save_audio(self, file_path): with open(file_path, 'wb') as f: f.write(self.audio_data) print(f"\n Audio saved at {file_path}") message = [ {"text": "This "}, {"text": "is "}, {"text": "a "}, {"text": "test "}, {"operation":"clear"}, {"text": "This "}, {"text": "is "}, {"text": "an "}, {"text": "incomplete "}, {"text": "sentence "}, {"operation": "eos"}, ] client = RimeClient("cove", api_key="xxx") asyncio.run(client.run(message)) client.save_audio("output.mp3") ``` # Streaming HTTP Source: https://docs.rime.ai/api-reference/mistv3/http POST https://users.rime.ai/v1/rime-tts Mist v3 streaming HTTP endpoint: low-latency TTS with the updated Mist engine. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. The streaming endpoint returns audio bytes in the format specified by the `Accept` header. ## Audio formats Set the `Accept` header to one of the following values: | Format | Accept Header | Notes | | ----------- | ------------------------ | ---------------------------------------------------------------------------------------------------------- | | Opus (WebM) | `audio/webm;codecs=opus` | Recommended. Smaller files than MP3 at comparable quality. WebM streams natively in browsers. | | Opus (OGG) | `audio/ogg;codecs=opus` | Opus in an OGG container. Smaller files than MP3 at comparable quality. | | MP3 | `audio/mpeg` | Lower compression rate than Opus. Highest compatibility across devices and players. | | WAV | `audio/wav` | Uncompressed. RIFF WAVE header with 16-bit little-endian linear PCM samples. Streams natively in browsers. | | PCM | `audio/L16` | Headerless 16-bit little-endian linear PCM. | | G.711 μ-law | `audio/PCMU` | Headerless stream of audio bytes. | ### Deprecated aliases Still accepted for backwards compatibility; new code should use the RFC types above. | Deprecated | Use instead | | --------------- | ------------ | | `audio/mp3` | `audio/mpeg` | | `audio/pcm` | `audio/L16` | | `audio/x-mulaw` | `audio/PCMU` | ## Variable parameters Must be a voice from the Rime voice catalog. The text you'd like spoken. Character limit per request is 1,000 via the API and in the dashboard UI. Set to `mistv3`. The sampling rate (Hz). The time scaling factor. Accepted range is 0.4 to 2.5; values outside it are clamped without an error. A value above 1.0 slows down the audio, a value below 1.0 speeds up the audio. If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds. Example: `Hi. <200> I'd love to have a conversation with you.` adds a 200ms pause. Learn more about [custom pauses](/docs/custom-pauses). Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Accept: audio/webm;codecs=opus' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --output output.webm \ --fail \ --data '{ "text": "Hello from Rime!", "modelId": "mistv3", "speaker": "cove", "lang": "en", "samplingRate": 24000 }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/v1/rime-tts" payload = { "speaker": "cove", "text": "Hello from Rime!", "modelId": "mistv3", "samplingRate": 24000 } headers = { "Accept": "audio/webm;codecs=opus", "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } with requests.post(url, headers=headers, json=payload, stream=True) as response: response.raise_for_status() with open("output.webm", "wb") as f: for chunk in response.iter_content(chunk_size=4096): if chunk: f.write(chunk) ``` ```javascript JavaScript theme={null} const fs = require("fs"); const options = { method: 'POST', headers: { Accept: 'audio/webm;codecs=opus', Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: '{"speaker":"cove","text":"Hello from Rime!","modelId":"mistv3","samplingRate":24000}' }; fetch('https://users.rime.ai/v1/rime-tts', options) .then(response => response.arrayBuffer()) .then(buffer => { fs.writeFileSync("output.webm", Buffer.from(buffer)); console.log("Audio saved to output.webm"); }) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/v1/rime-tts", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"speaker\": \"cove\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"mistv3\",\n \"samplingRate\": 24000\n}", CURLOPT_HTTPHEADER => [ "Accept: audio/webm;codecs=opus", "Authorization: Bearer YOUR_API_KEY", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "io" "net/http" "os" "strings" ) func main() { url := "https://users.rime.ai/v1/rime-tts" payload := strings.NewReader("{\n \"speaker\": \"cove\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"mistv3\",\n \"samplingRate\": 24000\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "audio/webm;codecs=opus") req.Header.Add("Authorization", "Bearer YOUR_API_KEY") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) _ = os.WriteFile("output.webm", body, 0644) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/v1/rime-tts") .header("Accept", "audio/webm;codecs=opus") .header("Authorization", "Bearer YOUR_API_KEY") .header("Content-Type", "application/json") .body("{\n \"speaker\": \"cove\",\n \"text\": \"Hello from Rime!\",\n \"modelId\": \"mistv3\",\n \"samplingRate\": 24000\n}") .asBytes(); Files.write(Paths.get("output.webm"), response.getBody()); ``` # Websockets Source: https://docs.rime.ai/api-reference/mistv3/websockets GET wss://users-ws.rime.ai/ws Mist v3 plain-text WebSocket (/ws): send text, receive raw audio bytes. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Overview Rime's websocket implementation accepts bare text, and responds with audio bytes of the selected format. All synthesis arguments are provided as query parameters when establishing the connection. The websocket API buffers inputs up to one of the following punctuation characters: `.`, `,`, `?`, `!`. This is most pertinent for the initial messages sent to the API, as synthesis won't begin until there are sufficient tokens to generate audio with natural prosody. After the first synthesis of any given utterance, typically enough time has elapsed that subsequent audio contains multiple clauses, and the buffering becomes largely invisible. ## Messages ### Send The messages your client will send to the websocket API will be bare (non-serialized) text. ```example theme={null} This will be converted to audio via websockets ``` ### Receive The messages your client will receive will be raw audio bytes in the audio format specified at connection time. ## Commands ### `` This clears the current buffer. Used in the event of interruptions. ### `` This forces whatever buffer exists, if any, to be synthesized, and the generated audio to be sent over. ### `` This forces whatever buffer exists, if any, to be synthesized, and for the server to close the connection after sending the generated audio. ## Variable parameters Must be a voice from the Rime voice catalog. Set to `mistv3`. One of `pcm`, `mulaw`, or `mp3` If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds. Example: `Hi. <200> I'd love to have a conversation with you.` adds a 200ms pause. Learn more about [custom pauses](/docs/custom-pauses). The value, if provided, must be between 4000 and 44100. Default: 22050 Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. Adjusts the speed of speech. Higher than 1.0 is faster and lower than 1.0 is slower. Controls how text is segmented for synthesis. Available options: * "immediate" - Synthesizes text immediately without waiting for complete sentences * "never" - Never segments the text, waits for explicit flush or EOS * "bySentence" (default) - Waits for complete sentences before synthesis ```python Python theme={null} import asyncio import websockets class RimeClient: def __init__(self, speaker, api_key): self.url = f"wss://users-ws.rime.ai/ws?speaker={speaker}&modelId=mistv3&audioFormat=mp3" self.auth_headers = { "Authorization": f"Bearer {api_key}" } self.audio_data = b'' async def send_tokens(self, websocket, message): for token in message: await websocket.send(token) async def handle_audio(self, websocket): while True: try: audio = await websocket.recv() except websockets.exceptions.ConnectionClosedOK: break self.audio_data += audio async def run(self, message): async with websockets.connect(self.url, additional_headers=self.auth_headers) as websocket: await asyncio.gather( self.send_tokens(websocket, message), self.handle_audio(websocket), ) def save_audio(self, file_path): with open(file_path, 'wb') as f: f.write(self.audio_data) message = [ "This ", "is ", "a ", "sentence, ", "that ", "will ", "produce ", "audio.", "", ] client = RimeClient("cove", api_key="YOUR_API_KEY") asyncio.run(client.run(message)) client.save_audio("output.mp3") ``` # Websockets JSON Source: https://docs.rime.ai/api-reference/mistv3/websockets-json GET wss://users-ws.rime.ai/ws3 Mist v3 JSON WebSocket (/ws3): structured events with base64 audio chunks and word-level timestamps. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Overview In addition to a plaintext websocket implementation, Rime also has an implementation that sends and receives events as JSON objects. Like the other implementation, all synthesis arguments are provided as query parameters when establishing the connection. The websocket API buffers inputs up to one of the following punctuation characters: `.`, `?`, `!`. This is most pertinent for the initial messages sent to the API, as synthesis won't begin until there are sufficient tokens to generate audio with natural prosody. After the first synthesis of any given utterance, typically enough time has elapsed that subsequent audio contains multiple clauses, and the buffering becomes largely invisible. ## Messages ### Send #### Text This is the most common message, which contains text for synthesis. schema: ```typescript theme={null} type TextMessage = { text: string, contextId?: string, } ``` examples: ```json theme={null} { "text": "this is the minimum text message." } { "text": "this is a text message with a context id.", "contextId": "159495B1-5C81-4C73-A51A-9CE10A08239E" } ``` Context IDs can be provided, which will be attached to subsequent messages that the server sends back to the client. Rime will not maintain multiple simultaneous context ids. #### Clear Your client can clear out the accumulated buffer, which is useful in the case of interruptions. ```json theme={null} { "operation": "clear" } ``` #### Flush This forces whatever buffer exists, if any, to be synthesized, and the generated audio to be sent over. ```json theme={null} { "operation": "flush" } ``` #### EOS At times, your client would like to generate audio for whatever remains in the buffer, and then have the connection immediately closed. ```json theme={null} { "operation" : "eos" } ``` ### Receive #### Chunk The most common event will be the audio chunk. ```typescript theme={null} type Base64String = string type AudioChunkEvent = { type: "chunk", data: Base64String, contextId: string | null, } ``` The audio will be a base64 encoded chunk of audio bytes in the audio format specified when the connection was established. #### Timestamps Word-level timestamps are emitted alongside the audio chunks so the client can tell exactly which words have been spoken at any point. This is especially useful for handling interruptions: when the user starts talking over the output, you can map the playback position back to the last word that was actually heard. Timestamps are emitted only when `lang` is `en`/`eng` or `es`/`spa`, or when `lang` is omitted. Requests in any other language receive `chunk` and `done` events with no `timestamps` event and no error (this includes fr and de). Do not block playback while waiting for a timestamps event. ```typescript theme={null} type TimestampsEvent = { type: "timestamps", word_timestamps: { words: string[], start: number[], end: number[], }, contextId: string | null, } ``` The three arrays inside `word_timestamps` are the same length and index-aligned: for a given index `i`, `words[i]` is spoken from `start[i]` to `end[i]`. Times are in seconds, measured from the beginning of the audio for the current synthesis. If a context id was attached to the text that produced this audio, it is included on the event. Example payload: ```json theme={null} { "type": "timestamps", "word_timestamps": { "words": ["Testing", "mistv3", "timestamps."], "start": [0, 0.35396, 1.41584], "end": [0.35396, 1.41584, 3.18564] }, "contextId": null } ``` #### Done After the last audio chunk for a synthesis batch has been sent, the server emits a `done` event. This signals that the current synthesis is fully complete. If the client sends more text and triggers further synthesis, another `done` will follow. ```typescript theme={null} type DoneEvent = { type: "done", contextId: string | null, } ``` When exactly `done` fires depends on the `segment` setting. See [Segmentation and behavior settings](/docs/websockets-segment) for full details. #### Error In the event of a malformed or unexpected input, the server will immediately respond with an error message. The server will *not* close the connection, and will still accept subsequent well-formed messages. ```typescript theme={null} type ErrorEvent = { type: "error", message: string, } ``` ## Variable parameters Must be a voice from the Rime voice catalog. Set to `mistv3`. One of `pcm`, `mulaw`, or `mp3` If provided, the language must match the language spoken by the selected speaker. Verify the pairing in the Rime voice catalog. When set to true, adds pauses between words enclosed in angle brackets. The number inside the brackets specifies the pause duration in milliseconds. Example: `Hi. <200> I'd love to have a conversation with you.` adds a 200ms pause. Learn more about [custom pauses](/docs/custom-pauses). The value, if provided, must be between 4000 and 44100. Default: 22050 Comma-separated list of speed values applied to words in square brackets. Values \< 1.0 speed up speech, > 1.0 slow it down. Example: "This is \[slow] and \[fast]", use "3, 0.5" to make "slow" slower and "fast" faster. Adjusts the speed of speech. Higher than 1.0 is faster and lower than 1.0 is slower. Controls how text is segmented for synthesis. Available options: * "immediate" - Synthesizes text immediately without waiting for complete sentences * "never" - Never segments the text, waits for explicit flush or EOS * "bySentence" (default) - Waits for complete sentences before synthesis ```python Python theme={null} import asyncio import json import websockets import base64 class RimeClient: def __init__(self, speaker, api_key): self.url = f"wss://users-ws.rime.ai/ws3?speaker={speaker}&modelId=mistv3&audioFormat=mp3" self.auth_headers = { "Authorization": f"Bearer {api_key}" } self.audio_data = b'' async def send_messages(self, websocket, messages): for message in messages: await websocket.send(json.dumps(message)) async def handle_audio(self, websocket): while True: try: audio = await websocket.recv() except websockets.exceptions.ConnectionClosedOK: break message = json.loads(audio) if message['type'] == 'chunk': self.audio_data += base64.b64decode(message['data']) if message['type'] == 'timestamps': print("Rime model pronounced the words...\n") for w, t in zip(message['word_timestamps']['words'], message['word_timestamps']['start']): print(f"'{w}' at time {t}") async def run(self, messages): async with websockets.connect(self.url, additional_headers=self.auth_headers) as websocket: await asyncio.gather( self.send_messages(websocket, messages), self.handle_audio(websocket), ) def save_audio(self, file_path): with open(file_path, 'wb') as f: f.write(self.audio_data) print(f"\n Audio saved at {file_path}") message = [ {"text": "This "}, {"text": "is "}, {"text": "an "}, {"text": "incomplete "}, {"text": "sentence "}, {"operation": "eos"}, ] client = RimeClient("cove", api_key="YOUR_API_KEY") asyncio.run(client.run(message)) client.save_audio("output.mp3") ``` # Coverage Source: https://docs.rime.ai/api-reference/other/oov POST https://users.rime.ai/oov Coverage endpoint: check which input words are not yet in Rime's pronunciation dictionary. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Overview This endpoint returns the words in your input that are absent from Rime's pronunciation dictionary. Uncovered words are still synthesized using the model's predicted pronunciation, but brand names, technical terms, and names should be verified before production use. Dictionary additions typically take about a week. Contact your account manager through Slack or email, or write to [sales@rime.ai](mailto:sales@rime.ai), if you need a different turnaround or have an SLA. For immediate Mist v1 or Mist v2 control, [generate a custom pronunciation](/docs/custom-pronunciation) by hand or from a recording with the [Phonemize API](/api-reference/other/phonemize). ## Example A request takes only the string `text`, for example: ```bash theme={null} curl -X POST https://users.rime.ai/oov \ -H 'Authorization: Bearer ' \ -d '{"text": "This is just a testt. This, is, also, a, testtt"}'; ``` The response will include an array with any strings not covered by the current Rime dictionary: ```bash theme={null} ["testt","testtt"] ``` ## Variable parameters One or more words to check against Rime's pronunciation dictionary. Separate words with spaces, commas, or newlines. ```bash cURL theme={null} curl --request POST \ --url https://users.rime.ai/oov \ --header 'Accept: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --fail \ --data '{ "text": "" }' ``` ```python Python theme={null} import requests url = "https://users.rime.ai/oov" payload = { "text": "" } headers = { "Accept": "application/json", "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.request("POST", url, json=payload, headers=headers) print(response.text) ``` ```javascript JavaScript theme={null} const options = { method: 'POST', headers: { Accept: 'application/json', Authorization: 'Bearer ', 'Content-Type': 'application/json' }, body: '{"text":""}' }; fetch('https://users.rime.ai/oov', options) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://users.rime.ai/oov", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"text\": \"\"\n}", CURLOPT_HTTPHEADER => [ "Accept: application/json", "Authorization: Bearer ", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://users.rime.ai/oov" payload := strings.NewReader("{\n \"text\": \"\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "application/json") req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://users.rime.ai/oov") .header("Accept", "application/json") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"text\": \"\"\n}") .asString(); ``` ```json 200: words not in dictionary theme={null} ["testt", "testtt"] ``` ```json 200: all words covered theme={null} [] ``` # Phonemize Source: https://docs.rime.ai/api-reference/other/phonemize POST https://optimize.rime.ai/phonemize Phonemize endpoint: convert a recording of a word into a phonetic string in the Rime phonetic alphabet. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Overview This API endpoint converts a short audio recording of a word into a phonetic string in the [Rime phonetic alphabet](/platform/rime-phonetic-alphabet). Use it when you know how a word should sound but don't want to write the phonetic string by hand: record the word (or synthesize it), post the audio, and paste the returned string into a TTS request inside curly brackets with `phonemizeBetweenBrackets: true`. See [Custom pronunciation](/docs/custom-pronunciation). Custom pronunciation strings are supported by **Mist v1 and v2** only. For an overview of all the ways to control pronunciation, see [Pronunciation control](/platform/pronunciation-control). ## Request Unlike Rime's other endpoints, the request body is the **raw audio bytes**, not JSON or multipart form data. Set the `Content-Type` header to match the audio format. WAV (`audio/wav`) and MP3 (`audio/mpeg`) are supported. ## Example Generate or record audio of the word, for example with the [Rime CLI](/cli-reference/overview): ```bash theme={null} rime tts -m coda -l en -s astra "hello" -o speech.wav ``` Then post it to the endpoint: ```bash theme={null} curl -X POST https://optimize.rime.ai/phonemize \ -H "Authorization: Bearer $(rime key)" \ -H "Content-Type: audio/wav" \ --data-binary @speech.wav ``` The response includes the phonetic string: ```json theme={null} { "audioId": "9b2d8ad2-0618-4e96-b255-98b2f7488061", "phonemeString": "h0El1o !", "authed": 1 } ``` ## Response fields * `audioId`: identifier of the uploaded audio clip. * `phonemeString`: the phonetic transcription in the [Rime phonetic alphabet](/platform/rime-phonetic-alphabet). The string may end with a punctuation token (e.g. `!` or `?`); strip it before using the string inside `{}`. * `authed`: always `1`. ```bash cURL theme={null} curl --request POST \ --url https://optimize.rime.ai/phonemize \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: audio/wav' \ --fail \ --data-binary @speech.wav ``` ```python Python theme={null} import requests url = "https://optimize.rime.ai/phonemize" headers = { "Authorization": "Bearer ", "Content-Type": "audio/wav" } with open("speech.wav", "rb") as f: response = requests.request("POST", url, data=f, headers=headers) print(response.text) ``` ```javascript JavaScript theme={null} import { readFile } from 'node:fs/promises'; const audio = await readFile('speech.wav'); const options = { method: 'POST', headers: { Authorization: 'Bearer ', 'Content-Type': 'audio/wav' }, body: audio }; fetch('https://optimize.rime.ai/phonemize', options) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.error(err)); ``` ```json 200 theme={null} { "audioId": "9b2d8ad2-0618-4e96-b255-98b2f7488061", "phonemeString": "h0El1o !", "authed": 1 } ``` # Text Normalization Source: https://docs.rime.ai/api-reference/other/textnorm POST https://optimize.rime.ai/textnorm Return normalized text exactly as the TTS model receives it before synthesis. The Rime API authenticates every request with a bearer token in the `Authorization` header: `Authorization: Bearer YOUR_API_KEY`. See [API authentication](/docs/api-authentication) for how to create a key. ## Overview This endpoint returns the normalized form of an input string exactly as Rime's TTS models receive it before synthesis. Use it to preview how numbers, phone numbers, dates, and other non-standard words will be spoken, or to debug unexpected pronunciations. Defaults to English. Pass the `lang` field for other languages; see [Languages](/docs/voices#languages) for the full list. For details on what's normalized natively, known gaps, and how to pre-normalize problematic patterns, see [Text normalization](/docs/text-normalization). ## Example A request takes the string `text` and, optionally, a `lang` code: ```bash theme={null} curl -X POST https://optimize.rime.ai/textnorm \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"text":"1234 1,2,3,4 1-800-444-4141 "}' ``` The response includes the normalized string: ```json theme={null} {"normalized":"one two three four, one , two , three , four, one, eight hundred, four four four, four one four one"} ``` To normalize text in a non-English language, pass a language code: ```bash theme={null} curl -X POST https://optimize.rime.ai/textnorm \ -H "Authorization: Bearer $(rime key)" \ -H "Content-Type: application/json" \ -d '{"text":"Tengo 2 perros","lang":"es"}' ``` ## Variable parameters The string you'd like to normalize. Numbers, phone numbers, and other non-standard words will be expanded into their spoken form. Language code (e.g. `en`, `es`, `fr`, `de`, and [additional languages](/docs/voices#languages)) selecting the normalization rules. Defaults to English when omitted. ```bash cURL theme={null} curl --request POST \ --url https://optimize.rime.ai/textnorm \ --header 'Accept: application/json' \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --fail \ --data '{ "text": "" }' ``` ```python Python theme={null} import requests url = "https://optimize.rime.ai/textnorm" payload = { "text": "" } headers = { "Accept": "application/json", "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.request("POST", url, json=payload, headers=headers) print(response.text) ``` ```javascript JavaScript theme={null} const options = { method: 'POST', headers: { Accept: 'application/json', Authorization: 'Bearer ', 'Content-Type': 'application/json' }, body: '{"text":""}' }; fetch('https://optimize.rime.ai/textnorm', options) .then(response => response.json()) .then(response => console.log(response)) .catch(err => console.error(err)); ``` ```php PHP theme={null} "https://optimize.rime.ai/textnorm", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "{\n \"text\": \"\"\n}", CURLOPT_HTTPHEADER => [ "Accept: application/json", "Authorization: Bearer ", "Content-Type: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } ``` ```go Go theme={null} package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://optimize.rime.ai/textnorm" payload := strings.NewReader("{\n \"text\": \"\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Accept", "application/json") req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```java Java theme={null} HttpResponse response = Unirest.post("https://optimize.rime.ai/textnorm") .header("Accept", "application/json") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"text\": \"\"\n}") .asString(); ``` ```json 200 theme={null} { "normalized": "one two three four, one, eight hundred, four four four, four one four one" } ``` # Overview Source: https://docs.rime.ai/cli-reference/overview Install and get started with the Rime CLI: a command-line tool for synthesizing and listening to AI speech. The Rime CLI synthesizes AI speech from your terminal. It streams audio during generation, plays it live with a waveform visualization, and supports multiple output formats. ## Installation ```bash Shell script theme={null} curl -fsSL https://rime.ai/install-cli.sh | sh ``` ```bash Homebrew theme={null} brew tap rimelabs/rime-cli && brew install rime-cli ``` ## Commands Synthesize text to speech and play or save audio Generate curl commands for direct API requests Manage configuration and named environments Authenticate with the Rime dashboard rime play, rime hello, rime speedtest, rime usage, and more Global flags, environment variables, and configuration format Fix common errors and installation issues # Reference Source: https://docs.rime.ai/cli-reference/reference Global flags, environment variables, configuration file format, audio formats, and metadata embedding for the Rime CLI. ## Global flags (all commands) | Flag | Short | Default | Description | | ----------- | ----- | ------- | ------------------------------------ | | `--quiet` | `-q` | `false` | Suppress non-essential output | | `--json` | -- | `false` | Output results as JSON | | `--env` | `-e` | -- | Named environment to use from config | | `--config` | `-c` | -- | Path to a custom config file | | `--version` | `-v` | -- | Print version information | | `--help` | `-h` | -- | Help for any command | ## Environment variables | Variable | Description | | ------------------------- | --------------------------------------------------------------- | | `RIME_CLI_API_KEY` | API key for authentication (overrides the key in `rime.toml`) | | `RIME_API_URL` | API endpoint URL (overrides the URL in `rime.toml`) | | `RIME_AUTH_HEADER_PREFIX` | Authorization header prefix (default: `Bearer`) | | `RIME_DASHBOARD_URL` | Dashboard URL for `rime login` (default: `https://app.rime.ai`) | ## Configuration The CLI uses a TOML config file at `~/.rime/rime.toml`. You can define multiple named environments for different API endpoints. ```toml theme={null} api_key = "your_api_key" api_url = "https://users.rime.ai/v1/rime-tts" [env.staging] api_url = "https://staging.rime.ai/v1/rime-tts" [env.onprem] api_url = "https://rime.internal:8080/v1/rime-tts" api_key = "different_key" auth_header_prefix = "Api-Key" ``` Select an environment with the `--env` flag: ```bash theme={null} rime tts "Hello" -s astra -m coda --env staging ``` **Resolution order:** Environment variables override config file values, which override defaults. Within the config file, named environment values override top-level values. ## Audio formats | Format | Extension | Default for | Notes | | ------ | --------- | -------------------------------------- | ------------------------------------------ | | WAV | `.wav` | `coda`, `arcana`, `arcanav2`, `mistv3` | Uncompressed, higher quality, larger files | | MP3 | `.mp3` | `mistv2`, `mist` | Compressed, smaller files | The CLI retains `arcana` and `arcanav2` for deprecated integrations. Use `coda` or a Mist model for new requests. ## Metadata embedding Audio files saved by the CLI include embedded metadata (voice, model, text). This metadata is visible in `rime play` waveform output and in media players like Finder or Preview. * **WAV files:** LIST/INFO chunk (`IART`, `INAM`, `ICMT`) * **MP3 files:** ID3v2.3 tags (`TPE1`, `TIT2`, `COMM`) # Authentication Source: https://docs.rime.ai/cli-reference/rime-auth Authenticate the Rime CLI using rime login, rime logout, and rime key. ## `rime login` Authenticate with Rime. Opens your browser to the Rime dashboard for OAuth-based authentication. The CLI starts a local callback server, receives the API key from the dashboard, and writes it to `~/.rime/rime.toml`. ```bash theme={null} rime login ``` Demo of the rime login command No flags. The command validates the API key before saving. *** ## `rime logout` Remove your saved API key by deleting the config file at `~/.rime/rime.toml`. ```bash theme={null} rime logout ``` No flags. *** ## `rime key` Print the resolved API key (no trailing newline). Useful in shell scripts and as a subexpression; `rime curl` uses `$(rime key)` in its generated commands. ```bash theme={null} rime key ``` No flags. Resolves the key from config or `RIME_CLI_API_KEY`, using the active environment. # rime config Source: https://docs.rime.ai/cli-reference/rime-config Manage Rime CLI configuration and named environments with rime config subcommands. Manage CLI configuration. The config file is TOML-based and lives at `~/.rime/rime.toml`. ## `rime config init` Create a new config file. Prompts for an API key interactively. ```bash theme={null} rime config init ``` | Flag | Default | Description | | --------- | ------- | --------------------------------- | | `--force` | `false` | Overwrite an existing config file | The generated file looks like: ```toml theme={null} default_env = "users" [env.users] api_url = "https://users.rime.ai/v1/rime-tts" api_key = "your_api_key_here" [env.users-east] api_url = "https://users-east.rime.ai/v1/rime-tts" api_key = "your_api_key_here" ``` `rime config init` pre-configures both standard Rime endpoints as named environments. The `default_env` field names the active one. Older config files without `default_env` continue to work: the top-level `api_url` and `api_key` fields are still respected as the fallback default. ## `rime config list` List all configured environments. The currently active default environment is marked with a `*` in the `NAME` column. ```bash theme={null} rime config list ``` ``` NAME URL AUTH -------------------------------------------------------------------------------- users * https://users.rime.ai/v1/rime-tts Bearer users-east https://users-east.rime.ai/v1/rime-tts Bearer ``` | Flag | Default | Description | | -------- | ------- | -------------- | | `--json` | `false` | Output as JSON | ## `rime config default` Get or set the default environment. ```bash theme={null} # Print the current default environment name rime config default # Switch the default to a different environment rime config default users-east ``` With no arguments, prints the name of the current default environment: ``` users ``` With a name argument, updates `default_env` in `~/.rime/rime.toml` and confirms: ``` Default environment set to "users-east" ``` No flags. ## `rime config show` Show the fully resolved configuration for a given environment, including where the API key comes from (config file vs. environment variable). ```bash theme={null} rime config show ``` | Flag | Short | Default | Description | | ------------ | ----- | --------- | ---------------------------------------------- | | `--env` | `-e` | `default` | Environment to show | | `--json` | -- | `false` | Output as JSON | | `--show-key` | -- | `false` | Display the full API key (redacted by default) | **Example output:** ``` Environment: users API URL: https://users.rime.ai/v1/rime-tts API Key: rime_aHR0cHM6Ly... (redacted) Auth Prefix: Bearer Auth Header: Authorization: Bearer (redacted) ``` ## `rime config add` Add a named environment to `~/.rime/rime.toml`. Prompts interactively for API URL, API key (input hidden), and an optional auth prefix. You cannot add an environment named `default`. Use `rime config default` to change which environment is the default. ```bash theme={null} rime config add ``` | Flag | Description | | --------------- | ------------------------------------------------------ | | `--url` | API URL (default: `https://users.rime.ai/v1/rime-tts`) | | `--key` | API key (skips interactive prompt) | | `--auth-prefix` | Auth header prefix, e.g. `Bearer` (optional) | **Examples:** ```bash theme={null} # Add a staging environment interactively rime config add staging # Add an on-prem environment non-interactively rime config add onprem --url https://rime.internal:8080/v1/rime-tts --key your_key_here ``` ## `rime config rm` Remove a named environment from `~/.rime/rime.toml`. Prompts for confirmation unless `--yes` is passed. ```bash theme={null} rime config rm ``` | Flag | Short | Default | Description | | ------- | ----- | ------- | ------------------------ | | `--yes` | `-y` | `false` | Skip confirmation prompt | ## `rime config edit` Open `~/.rime/rime.toml` in your default editor (`$VISUAL` or `$EDITOR`, falling back to `nano` or `vi`). ```bash theme={null} rime config edit ``` No flags. Requires the config file to exist. Run `rime config init` first if needed. # rime curl Source: https://docs.rime.ai/cli-reference/rime-curl Generate a ready-to-run curl command for the Rime TTS API. Generate a curl command for making TTS API requests. The generated command uses `$(rime key)` as a shell expression, so it resolves your API key automatically when you paste and run it. Run without arguments to see an example. ```bash theme={null} rime curl [TEXT] ``` If you provide text, `--speaker` and `--model-id` are required. With no arguments, the command generates an example request. ## Optional flags | Flag | Short | Default | Description | | ----------------- | ----- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `--speaker` | `-s` | `astra`\* | Voice speaker to use | | `--model-id` | `-m` | `coda`\* | Model ID | | `--lang` | `-l` | `eng` | Language code | | `--speed-alpha` | -- | `1` | Speed multiplier; must be greater than 0 | | `--sampling-rate` | -- | -- | Output sampling rate in Hz. Coda and deprecated Arcana identifiers: `8000`, `16000`, `22050`, `24000`, `44100`, `48000`, `96000`. Mist: `4000`–`44100` | | `--oneline` | -- | `false` | Output as a single line for easy copy-paste | | `--api-url` | -- | -- | API URL override | ## Deprecated Arcana compatibility flags These flags remain for existing Arcana integrations. Do not use Arcana for new requests: [cloud Arcana requests are served by Coda from August 15, 2026](/docs/arcana-sunset). | Flag | Default | Description | | -------------- | ------- | ---------------------------- | | `--max-tokens` | `1200` | Max output tokens (200–5000) | ## Mist/Mist v2/Mist v3 flags | Flag | Description | | ---------------------------- | ---------------------------------------- | | `--inline-time-scale-factor` | Comma-separated per-segment speed values | | `--pause-between-brackets` | Insert pause at bracketed markers | ## Mist/Mist v2 flags Only `mist` and `mistv2` support these flags; `mistv3` does not. | Flag | Description | | ------------------------------ | ----------------------------------------------------------------------------------- | | `--phonemize-between-brackets` | Phonemize text in brackets (see [Custom pronunciation](/docs/custom-pronunciation)) | | `--no-text-normalization` | Disable text normalization | \*Defaults apply only when run without arguments. When text is provided, `--speaker` and `--model-id` are required. ## Examples ```bash theme={null} # Show example curl command rime curl # Generate curl for custom text rime curl "Hello from Rime" -s celeste -m coda # Single-line output rime curl "Hello" -s astra -m coda --oneline ``` # rime hello & rime play Source: https://docs.rime.ai/cli-reference/rime-hello-play Quick audio demo and terminal waveform playback with the Rime CLI. ## `rime hello` Quick demo that generates a time-appropriate greeting ("good morning/afternoon/evening from Rime AI!") using the Astra voice on the Coda model. ```bash theme={null} rime hello ``` Demo of the rime hello command ### Optional flags | Flag | Short | Default | Description | | ----------- | ----- | ------- | ----------------------------------------- | | `--output` | `-o` | -- | Output file path (plays audio by default) | | `--api-url` | -- | -- | API URL override | ### Examples ```bash theme={null} # Play the greeting rime hello # Save the greeting to a file rime hello -o greeting.wav # Output as JSON rime hello --json ``` *** ## `rime play` Play a WAV audio file with terminal waveform visualization. ```bash theme={null} rime play FILE ``` Demo of the rime play command ### Examples ```bash theme={null} rime play output.wav ``` # Monitoring and usage Source: https://docs.rime.ai/cli-reference/rime-monitoring Measure latency, view character usage, and uninstall the Rime CLI. ## `rime speedtest` Measure time-to-first-byte (TTFB) for configured environments. The command sends a TTS request to each endpoint and reports the latency. ```bash theme={null} rime speedtest ``` ### Flags | Flag | Short | Default | Description | | ----------- | ----- | ------- | ----------------------------------------------------------------------------------------- | | `--model` | `-m` | `coda` | Model ID for the test request | | `--runs` | -- | `1` | Number of requests per endpoint; reports mean/min/max when greater than 1 | | `--timeout` | -- | `10s` | Per-request timeout (`0` disables timeout) | | `--url` | -- | -- | Additional URL to test (repeatable). Forwards your configured API credentials to that URL | | `--env` | -- | -- | Only test these named environments from config (repeatable) | | `--yes` | `-y` | `false` | Automatically switch the default environment if a faster one is found | `--url` forwards your configured API credentials to every supplied URL. Use it only with endpoints you trust. The CLI also prints this warning at runtime. ### Behavior * No flags: tests all configured environments * `--url` alone: tests only the specified URLs and skips the config environments * `--env` + `--url`: tests both the named envs and the extra URLs * After the test completes, if the fastest environment differs from the current default, the CLI prompts you to switch. Use `--yes` to skip the prompt and switch automatically. ### Example output (single run) ``` ENV URL TTFB -------------------------------------------------------------------------------- users https://users.rime.ai/v1/rime-tts 245.12ms users-east https://users-east.rime.ai/v1/rime-tts 189.40ms Fastest: users-east (189.40ms) Switch default environment from "users" to "users-east"? [y/N]: ``` ### Example output (`--runs 3`) ``` ENV URL TTFB (3 runs) -------------------------------------------------------------------------------- users https://users.rime.ai/v1/rime-tts mean=245.12ms min=221.30ms max=271.50ms users-east https://users-east.rime.ai/v1/rime-tts mean=189.40ms min=175.10ms max=203.80ms Fastest: users-east (189.40ms) Switch default environment from "users" to "users-east"? [y/N]: ``` When `--runs` is greater than 1, the JSON output includes `ttfb_min_ms` and `ttfb_max_ms` fields in addition to `ttfb_ms` (mean). *** ## `rime usage` Display daily character usage history for the past week, broken down by Mist, Arcana, and Coda models. ```bash theme={null} rime usage ``` ### Flags | Flag | Default | Description | | ------- | ------- | ------------- | | `--csv` | `false` | Output as CSV | Also supports the global `--json` flag. ### Example output ``` Day Mist Chars Arcana Chars Coda Chars Total ---------- ---------- ------------ ---------- ---------- 2026-05-19 0 500 3,400 3,900 2026-05-18 500 2,100 0 2,600 ``` *** ## `rime uninstall` Remove the Rime CLI binary, configuration, and shell PATH entries. The command detects whether you installed the CLI via Homebrew or the shell script and prints instructions for that install method. ```bash theme={null} rime uninstall ``` ### Flags | Flag | Short | Default | Description | | ------- | ----- | ------- | ---------------------------- | | `--yes` | `-y` | `false` | Skip the confirmation prompt | If installed via Homebrew, the command prints `brew uninstall rime` instead of performing removal directly. # rime tts Source: https://docs.rime.ai/cli-reference/rime-tts Synthesize text to speech from the command line using the Rime CLI. Synthesize text to speech in WAV or MP3. The CLI picks the format from the model: `mist` and `mistv2` output MP3, while `coda` and `mistv3` default to WAV. Deprecated Arcana identifiers also default to WAV. Use `--format` to override. ```bash theme={null} rime tts TEXT --speaker VOICE --model-id MODEL ``` Demo of the rime tts command ## Required flags | Flag | Short | Description | | ------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------- | | `--speaker` | `-s` | Voice speaker to use (e.g., `astra`, `celeste`, `orion`) | | `--model-id` | `-m` | Model ID. Use `coda`, `mistv3`, `mistv2`, or `mist`. `arcana` and `arcanav2` remain available only for deprecated integrations. | ## Optional flags | Flag | Short | Default | Description | | ----------------- | ----- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `--output` | `-o` | -- | Output file path. Use `-` for stdout. If omitted, plays audio directly | | `--play` | `-p` | `false` | Play audio after synthesis (default behavior when no output is specified) | | `--lang` | `-l` | `eng` | Language code (e.g., `eng`, `es`, `fra`). Valid codes depend on model | | `--format` | `-f` | -- | Audio format: `wav` or `mp3` (overrides model default) | | `--speed-alpha` | -- | `1` | Speed multiplier. For `mist`/`mistv2`: lower is faster. For `coda`, `mistv3`, and deprecated Arcana identifiers: higher is faster | | `--sampling-rate` | -- | -- | Output sampling rate in Hz. Coda and deprecated Arcana identifiers: `8000`, `16000`, `22050`, `24000`, `44100`, `48000`, `96000`. Mist: `4000`–`44100` | | `--api-url` | -- | -- | API URL (default: `$RIME_API_URL` or `https://users.rime.ai/v1/rime-tts`) | ## Deprecated Arcana compatibility flags These flags remain for existing Arcana integrations. Do not use Arcana for new requests: [cloud Arcana requests are served by Coda from August 15, 2026](/docs/arcana-sunset). | Flag | Default | Description | | -------------- | ------- | ---------------------------- | | `--max-tokens` | `1200` | Max output tokens (200–5000) | ## mist/mistv2/mistv3 flags | Flag | Description | | ---------------------------- | ---------------------------------------- | | `--inline-time-scale-factor` | Comma-separated per-segment speed values | | `--pause-between-brackets` | Insert pause at bracketed markers | ## mist/mistv2 flags Only `mist` and `mistv2` support these flags; `mistv3` does not. | Flag | Description | | ------------------------------ | ----------------------------------------------------------------------------------- | | `--phonemize-between-brackets` | Phonemize text in brackets (see [Custom pronunciation](/docs/custom-pronunciation)) | | `--no-text-normalization` | Disable text normalization | ## Examples ```bash theme={null} # Play audio directly through speakers rime tts "Hello world" -s astra -m coda # Save to a WAV file rime tts "Hello world" -s astra -m coda -o output.wav # Pipe audio to stdout rime tts "Hello world" -s astra -m coda -o - > audio.wav # Use mistv3 (WAV by default) rime tts "Hello world" -s peak -m mistv3 # Use mistv2 (outputs MP3 by default) rime tts "Hello world" -s peak -m mistv2 # Synthesize in Spanish with Coda rime tts "Hola mundo" -s astra -m coda -l es # JSON output with timing metadata rime tts "Hello world" -s astra -m coda -o output.wav --json ``` ## Supported languages by model | Model | Languages | | ----------------------- | ----------------------------------------------------------------------------------------- | | `coda` | `eng`, `spa`, `fra`, `por`, `ger`, `jpn`, `ara`, `hin` (and ISO 639-1 equivalents) | | `mistv3` | `eng`, `fra`, `ger`, `spa` (and ISO 639-1 equivalents) | | `mistv2` / `mist` | `eng`, `fra`, `ger`, `spa` (and ISO 639-1 equivalents) | | `arcana` (deprecated) | `eng`, `spa`, `fra`, `por`, `ger`, `jpn`, `tam`, `sin`, `heb` (and ISO 639-1 equivalents) | | `arcanav2` (deprecated) | `eng`, `spa`, `ger`, `fra` (and ISO 639-1 equivalents) | # Troubleshooting Source: https://docs.rime.ai/cli-reference/troubleshooting Fix common issues with the Rime CLI. ## "API key not found" Run `rime login` or set the environment variable: ```bash theme={null} export RIME_CLI_API_KEY=your_key_here ``` ## "authentication failed: invalid API key" Verify your API key at [app.rime.ai/tokens](https://app.rime.ai/tokens). Then run `rime login` again. ## "mist and mistv2 models require --format mp3" The CLI uses a streaming endpoint for `mist` and `mistv2` that does not return WAV. Because the CLI writes only WAV or MP3, select MP3: ```bash theme={null} rime tts "Hello" -s cove -m mistv2 -f mp3 ``` ## No audio playback * Check your system audio output settings * Try saving to a file instead: `rime tts "Hello" -s astra -m coda -o output.wav` * Headless builds (e.g., Docker) require `-o FILE` since playback is disabled ## "command not found: rime" If you installed via the shell script, open a new terminal window or run: ```bash theme={null} source ~/.zshrc # or ~/.bashrc ``` # Abbreviations, acronyms, and initialisms Source: https://docs.rime.ai/docs/abbreviations How Rime pronounces abbreviations, acronyms, and initialisms, with controls for exceptions. Rime pronounces most common abbreviations, acronyms, and initialisms correctly out of the box. The patterns below show how to format input when you want to control pronunciation explicitly. For a tour of text normalization across all categories, see [Text normalization](/docs/text-normalization). For specific patterns Rime doesn't expand cleanly, see [Pre-normalizing text](/docs/pre-normalization). ## Abbreviations | Format | Example | Reads as | | :------------------ | :---------- | :----------- | | Title abbreviation | `Dr. Smith` | doctor smith | | Latin abbreviation | `e.g.` | for example | | Street abbreviation | `rd.` | road | | Saint abbreviation | `St. John` | saint john | Some abbreviations resolve from context. For example, `St.` reads as "saint" in `St. John` but "street" in `Main St.` See [Addresses](/docs/addresses) for street and state abbreviations in address context. ## Acronyms and initialisms Acronyms are pronounced as a single word. For example, `NASA` reads as "Nasa". Initialisms are pronounced as a series of letters, so `DNA` reads as "D N A". By default, Rime pronounces a series of capital letters as an acronym. Common initialisms such as `DNA`, `ID`, `USA`, `FBI`, and `CIA` are pronounced as a series of letters automatically. To force initialism pronunciation reliably, **use lowercase letters with a period and space after each**: | Format | Example | Reads as | | :---------------------------------- | :--------- | :------- | | Capitalized acronym | `NASA` | Nasa | | Capitalized initialism (recognized) | `DNA` | D N A | | Lowercase + dotted | `d. n. a.` | D N A | | Lowercase + dotted | `u. p. s.` | U P S | | Lowercase + dotted | `g. p. a.` | G P A | You can also specify a custom pronunciation for any acronym or initialism using Rime's [custom pronunciations](/docs/custom-pronunciation) feature. ## Known gaps Context-dependent abbreviations like `Dr.`, `Mr.`, and `St.` rely on surrounding words to resolve and may not always read the way you expect. For workarounds and a drop-in prompt template, see [Pre-normalizing text](/docs/pre-normalization). ## Related * [Custom pronunciation](/docs/custom-pronunciation) for defining how a specific term should sound * [Spell function](/docs/spell) for forced letter-by-letter reading of unrecognized acronyms (`spell(NPI)`) * [Addresses, URLs, and emails](/docs/addresses) for street and state abbreviations in address context # Addresses, URLs, and emails Source: https://docs.rime.ai/docs/addresses How Rime automatically expands street addresses, URLs, and email addresses into spoken form. Rime expands addresses, URLs, and email addresses into their spoken form automatically. Schemes, `www.` prefixes, paths, hyphens in domains, and common TLDs are all handled. For a tour of text normalization across all categories, see [Text normalization](/docs/text-normalization). For specific patterns Rime doesn't expand cleanly, see [Pre-normalizing text](/docs/pre-normalization). ## Addresses Rime typically pronounces state name abbreviations correctly in the context of an address, but writing out the full state name (e.g., "Massachusetts" instead of "MA") gives more consistent results. Common street abbreviations like `Rd.` and `St.` are pronounced correctly. | Format | Example | Reads as | | :------------------------------------- | :--------------------------------------------- | :------------------------------------------------------------------------- | | Full street + state name | `529 Main Street, Boston, Massachusetts 02129` | five twenty-nine main street, boston, massachusetts, zero two one two nine | | Abbreviated street + abbreviated state | `529 Main St., Boston, MA 02129` | five twenty-nine main street, boston, massachusetts, zero two one two nine | | Mixed | `529 Main St, Boston, MA 02129` | five twenty-nine main street, boston, massachusetts, zero two one two nine | ## URLs Schemes, `www.` prefixes, paths, and hyphens in domains are handled. Common TLDs (`.com`, `.org`, `.io`, `.ai`, etc.) are read letter-by-letter. | Format | Example | Reads as | | :------------------------- | :---------------------------- | :----------------------------------------------- | | Bare `www.` URL | `www.example.com` | double-u double-u double-u dot example dot com | | HTTPS URL | `https://app.rime.ai` | h t t p s colon slash slash app dot rime dot a i | | URL with path | `www.shop.com/archive` | www dot shop dot com slash archive | | URL with hyphenated domain | `https://worldprime.io/about` | HTTPS world prime dot i o slash about | ## Emails | Format | Example | Reads as | | :---------------- | :-------------------- | :--------------------------------------- | | Standard email | `name@example.com` | name at example dot com | | Email with digits | `cloud799@icloud.com` | cloud seven nine nine at i cloud dot com | Rime's custom segmentation model handles email addresses. It breaks up compound words and handles punctuation and most top-level domains. If you hear something off, contact [Rime support](mailto:support@rime.ai). ## Known gaps Internationalized domain names (non-ASCII characters in URLs) aren't supported. For the full list of normalization gaps and how to handle them, see [Pre-normalizing text](/docs/pre-normalization). ## Related * [Numbers, currency, and measurements](/docs/numbers) for phone numbers and other numeric formats * [Spell function](/docs/spell) for forced letter-by-letter reading of unusual email addresses or vanity URLs # API authentication Source: https://docs.rime.ai/docs/api-authentication How to authenticate with the Rime TTS API using a bearer token. Every request to the Rime API requires a **bearer token** in the `Authorization` header. ## Get an API key An API key can synthesize speech against your account. Keep it on the server and treat it like a password. 1. Sign in to the [Rime dashboard](https://app.rime.ai). 2. In the Rime dashboard, open [**API Tokens**](https://app.rime.ai/tokens). 3. Create a token and copy its value. ## Use the token This request authenticates with a bearer token and returns MP3 audio: ```bash theme={null} curl --request POST \ --url https://users.rime.ai/v1/rime-tts \ --header 'Authorization: Bearer YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --header 'Accept: audio/mpeg' \ --data '{"speaker":"astra","text":"hello","modelId":"coda","lang":"en"}' ``` Use the same header for the HTTP, WebSocket, metadata, and utility endpoints. ## CLI authentication The `rime` CLI manages the key locally. Run [`rime login`](/cli-reference/rime-auth) once, and the CLI stores the key at `~/.rime/rime.toml`. You can also set it with the `RIME_CLI_API_KEY` environment variable. ## On-prem authentication The on-prem API service accepts the same `Authorization: Bearer …` header. You can also configure `RIME_API_KEY` for the deployment so callers don't need to send the header. See [the on-prem quickstart](/docs/on-prem/quickstart) for details. ## Common auth errors If your request fails authentication, the API returns `401 Unauthorized` with a short plain-text body explaining why: | Status | Body | Cause | | :----- | :---------------- | :----------------------------------------------------------------------- | | `401` | `missing headers` | No `Authorization` header was sent. | | `401` | `invalid api key` | The token is not recognized, or it was sent without the `Bearer` scheme. | Always send the header as `Authorization: Bearer ` (capital `B`). The token alone, without `Bearer`, is rejected. ## Related * [Quickstart: TTS in five minutes](/docs/quickstart-five-minute) * [API reference index](/docs/api-reference) * [CLI authentication commands](/cli-reference/rime-auth) # API cheat sheet Source: https://docs.rime.ai/docs/api-cheat-sheet Base URLs, bearer authentication, and runnable examples for Rime's HTTP, WebSocket, voice, vocabulary, and text-normalization endpoints. Create a key on the [API Tokens page](https://app.rime.ai/tokens) before running the authenticated examples below. ## Hosts and authentication | What | Where | | ------------------------------------------------------------- | -------------------------- | | REST API (TTS, voices, coverage) | `https://users.rime.ai` | | WebSocket API | `wss://users-ws.rime.ai` | | Text normalization | `https://optimize.rime.ai` | | Docs (this site, plus `/llms.txt` and per-page `.md` exports) | `https://docs.rime.ai` | * Send TTS requests to `users.rime.ai`, not `api.rime.ai`. The latter serves internal infrastructure and returns `404` for TTS requests. * Authenticate with `Authorization: Bearer YOUR_API_KEY`. On WebSocket connections, send the same value as a connection header. * Keep the key on a server. Browser `WebSocket` objects cannot set the required header, so browser applications need a server-side bridge. * Rime does not publish an npm or PyPI SDK. Similarly named registry packages are unrelated third-party projects. ## Synthesize speech (HTTP) `POST /v1/rime-tts` returns audio bytes in the format named by your `Accept` header (`audio/mpeg`, `audio/wav`, `audio/webm;codecs=opus`, `audio/ogg;codecs=opus`, `audio/L16`, `audio/PCMU`): ```bash theme={null} curl -X POST https://users.rime.ai/v1/rime-tts \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -H 'Accept: audio/mpeg' \ --output hello.mp3 \ -d '{"text": "Hello from Rime.", "speaker": "astra", "modelId": "coda"}' ``` Full parameters and streaming variants: [Coda HTTP reference](/api-reference/coda/http) · [Streaming guide](/docs/streaming) ## Stream speech (WebSocket `/ws3`) Synthesis arguments go in the query string; auth goes in the connection header. Send `{"text": ...}` messages (buffered by sentence by default) and operations (`{"operation": "flush" | "clear" | "eos"}`); receive JSON events: `chunk` (base64 audio), `timestamps` (word-level), `done`, `error`. ```python theme={null} import asyncio, base64, json, os import websockets # pip install websockets async def main(): url = "wss://users-ws.rime.ai/ws3?speaker=astra&modelId=coda&audioFormat=mp3" headers = {"Authorization": f"Bearer {os.environ['RIME_API_KEY']}"} async with websockets.connect(url, additional_headers=headers) as ws: await ws.send(json.dumps({"text": "Hello from Rime over WebSockets."})) await ws.send(json.dumps({"operation": "eos"})) # synthesize what's buffered, then close audio = b"" async for raw in ws: event = json.loads(raw) if event["type"] == "chunk": audio += base64.b64decode(event["data"]) elif event["type"] == "timestamps": print("words:", event["word_timestamps"]["words"]) elif event["type"] == "done": break with open("output.mp3", "wb") as f: f.write(audio) print(f"saved {len(audio)} bytes to output.mp3") asyncio.run(main()) ``` Set `modelId` explicitly on `/ws3`. Without it, requests are served by the **Mist v3** backend, and speakers outside the Mist v3 catalog fail with a "Speaker not found" error. Message schemas: [Coda WebSocket reference](/api-reference/coda/websockets-json) · Buffering control: [Segmentation](/docs/websockets-segment) · Web-app bridge pattern: [Next.js voice-agent guide](/docs/voice-agent-nextjs#3-stream-over-websockets-when-latency-matters) ## List voices Both voice endpoints are public; no API key required. ```bash theme={null} # Voice names, keyed by modelId then ISO 639-2 language code curl https://users.rime.ai/data/voices/all-v2.json # Full metadata per voice (gender, age, dialect, language, flagship flag, …) curl https://users.rime.ai/data/voices/voice_details.json ``` Choosing a voice: [Voices guide](/docs/voices) · Reference: [List All Voices](/api-reference/data/voices-v2) · [List Voice Details](/api-reference/data/voice-details) ## Check vocabulary coverage (`/oov`) Returns the input words that are **not** in Rime's pronunciation dictionary: ```bash theme={null} curl -X POST https://users.rime.ai/oov \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"text": "hello kubectl blorbify"}' # → ["kubectl","blorbify"] ``` Out-of-dictionary words still get a best-effort pronunciation; to control them, see [Custom pronunciation](/docs/custom-pronunciation). Reference: [Vocabulary Coverage](/api-reference/other/oov) ## Normalize text (`/textnorm`) Preview exactly how numbers, dates, and phone numbers will be spoken. Note the host: `optimize.rime.ai`. ```bash theme={null} curl -X POST https://optimize.rime.ai/textnorm \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"text": "Call 1-800-444-4141 on 3/4/2026"}' # → {"normalized":"Call one, eight hundred, four four four, four one four one on march fourth twenty twenty six"} ``` Guide: [Text normalization](/docs/text-normalization) · Reference: [Text Normalization](/api-reference/other/textnorm) ## Common parameters | Parameter | Values | Notes | | ------------------ | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | `speaker` | See [voices](/docs/voices) | Required. Must match the model and language. | | `modelId` | `coda` (flagship), `mistv3` | Set it explicitly. Without one, `/ws3` serves only the Mist v3 voice catalog. | | `text` | string | Up to 1,000 characters per request (HTTP returns `400` "text is too long" beyond that). | | `lang` | `en`/`eng`, `es`/`spa`, `fr`/`fra`, `pt`/`por`, `de`/`ger`, `ja`/`jpn`, `ar`/`ara`, `hi`/`hin` | Must match the speaker's language. | | `audioFormat` (WS) | `mp3`, `mulaw`, `pcm` | HTTP uses the `Accept` header instead. | | `segment` (WS) | `bySentence` (default), `immediate`, `never` | When synthesis triggers; see [Segmentation](/docs/websockets-segment). | | `samplingRate` | `8000`–`96000`, default `24000` | Values above 24000 are upsampling. | ## Where to go deeper * [API reference index](/docs/api-reference): every endpoint across every model * [WebSocket API overview](/docs/websockets): endpoint comparison, timestamps, interruption handling * [Build a voice agent](/docs/voice-agent-nextjs): complete apps in Next.js, Vite, Express, plain Node, and FastAPI * [Rime CLI](/docs/quickstart-cli) and the [hosted MCP server](/docs/mcp): tooling around this same API # API reference index Source: https://docs.rime.ai/docs/api-reference Index of Rime's TTS HTTP, WebSocket, and metadata endpoints across all supported models. Send TTS requests to `https://users.rime.ai/v1/rime-tts` and authenticate with a bearer token in the `Authorization` header. See [API authentication](/docs/api-authentication). Most clients should start with **Coda**, Rime's flagship model: * [Coda: Streaming HTTP](/api-reference/coda/http) * [Coda: WebSockets (`/ws`)](/api-reference/coda/websockets) * [Coda: WebSockets JSON (`/ws3`)](/api-reference/coda/websockets-json) For the cross-model overview of when to use each WebSocket endpoint, see [WebSocket API Overview](/docs/websockets). **Cloud Arcana requests switch to Coda on August 15, 2026 at 12:00 UTC.** New cloud integrations should use Coda or Mist v3. The Arcana references below remain available for migrations before the cutoff. See the [Arcana migration guide](/docs/arcana-sunset). ## TTS endpoints by model | Model | Streaming HTTP | WebSocket `/ws` | WebSocket JSON | | ----------------------- | --------------------------------------------------------------------- | --------------------------------------- | --------------------------------------------- | | **Coda** (flagship) | [HTTP](/api-reference/coda/http) | [/ws](/api-reference/coda/websockets) | [/ws3](/api-reference/coda/websockets-json) | | **Mist v3** | [HTTP](/api-reference/mistv3/http) | [/ws](/api-reference/mistv3/websockets) | [/ws3](/api-reference/mistv3/websockets-json) | | **Mist v2** | [HTTP](/api-reference/mistv2/http) · [SSE](/api-reference/mistv2/sse) | [/ws](/api-reference/mistv2/websockets) | [/ws2](/api-reference/mistv2/websockets-json) | | **Arcana** (deprecated) | [HTTP](/api-reference/arcana/http) | [/ws](/api-reference/arcana/websockets) | [/ws3](/api-reference/arcana/websockets-json) | Mist v2 also exposes non-streaming JSON-wrapped formats: [MP3](/api-reference/mistv2/json-mp3), [WAV](/api-reference/mistv2/json-wav), [Opus/OGG](/api-reference/mistv2/json-ogg), [G.711 μ-law](/api-reference/mistv2/json-mulaw). ## Metadata endpoints * [List All Voices](/api-reference/data/voices-v2): `GET /data/voices/all-v2.json` * [List Voice Details](/api-reference/data/voice-details): `GET /data/voices/voice_details.json` ## Utility endpoints * [Coverage (out-of-vocabulary check)](/api-reference/other/oov): `POST /oov` * [Text Normalization](/api-reference/other/textnorm): `POST /textnorm` ## Related * [Quickstart: TTS in five minutes](/docs/quickstart-five-minute) * [Models](/docs/models): comparing Coda and Mist * [Voices](/docs/voices): voice lineup and language support * [Latency tuning](/docs/latency) * [Changelog](/docs/changelog) # Arcana sunset Source: https://docs.rime.ai/docs/arcana-sunset Cloud Arcana requests switch to Coda on August 15, 2026 at 12:00 UTC. What changes and which model IDs are affected. **Cloud Arcana requests switch to Coda on August 15, 2026 at 12:00 UTC.** Migrate before then so you can test the change on your own schedule rather than discovering it in production. Plan your cutover against 12:00 UTC rather than against a local calendar date. If you operate outside the Americas, the switch lands in the middle of your working day on August 15, not at the end of it. This cutoff applies to the cloud API. Existing Arcana on-prem images remain available and are not automatically routed to Coda. ## Does this affect you You are affected if any cloud request, config file, or environment variable sets `modelId` to `arcana`, `arcanav2`, or `arcanav3`. You are **not** affected by omitting `modelId`. Requests without it are served by Mist v3, which is unchanged. To check your own usage, search your code and configuration for those three strings, and repeat the search for every deployed environment rather than only your local checkout. There is no response header naming the model that served a request, so confirm by inventory and configuration review, not by inspecting a response. On-prem Arcana deployments are not part of this cloud cutover. See the [on-prem quickstart](/docs/on-prem/quickstart#tts-service) for the available images and languages. ## Where cloud traffic goes | Arcana language | After August 15 | | :-------------------------------------------------------------------- | :----------------------------------------- | | English, Spanish, French, German, Japanese, Portuguese, Arabic, Hindi | Served by Coda. Change `modelId` to `coda` | | Sinhala | Remains on Arcana, on-prem only | ## What changes when cloud requests switch to Coda The API contract is unchanged, so `modelId: coda` is the only edit most integrations need. These differences are not errors and will not appear as failures: * Your speaker may not exist on Coda, since voice availability differs per model. Check yours in the [voice catalog](/docs/voices) before switching * Word timestamps cover English and Spanish only. If you rely on them for interruption handling in another language, no `timestamps` event arrives and no error is raised * Audio will not be identical, because Coda is a different model, so prosody and pacing differ even for a speaker present on both ## After the cutoff If you have not migrated, cloud requests naming an Arcana model continue to succeed but are served by Coda. You will not receive an error. The audible difference is the signal that migration happened without you. ## Get help If you have any questions or concerns about migrating, contact [support@rime.ai](mailto:support@rime.ai) before August 15. Include your account, the model IDs you use, and the languages you serve, and someone will work through it with you. # Baseten Source: https://docs.rime.ai/docs/baseten Deploy Rime TTS on Baseten's serverless GPU infrastructure. [Baseten](https://www.baseten.co/) is a platform for deploying and serving AI models on autoscaling GPU infrastructure. Rime's text-to-speech engine images run on Baseten as single-container deployments: the engine validates its own license and serves TTS directly, with no separate router. ### Get started Ready-to-use deploy configs for Rime's models live in the [`rimelabs/rime-baseten-deploy`](https://github.com/rimelabs/rime-baseten-deploy) repository. Each model directory contains a Baseten/[Truss](https://truss.baseten.co/) `config.yaml` plus a README with full deploy, secrets, and invocation steps. | Model | Directory | | ---------------------------------------- | ----------------------------------------------------------------------------------------- | | Rime Coda v1: flagship expressive TTS | [`rime-coda-v1/`](https://github.com/rimelabs/rime-baseten-deploy/tree/main/rime-coda-v1) | | Rime Mist v3: low-latency conversational | [`rime-mist-v3/`](https://github.com/rimelabs/rime-baseten-deploy/tree/main/rime-mist-v3) | ## Prerequisites Before cloning the deployment repository, contact [help@rime.ai](mailto:help@rime.ai) for engine-image and license access. Your Baseten workspace needs these secrets: * `gcp_rime_service_account` * `rime_license` * `rime_api_key` To deploy: 1. Clone the repo and `cd` into the model directory you want. 2. Set the three required secrets in your Baseten workspace. The per-model README describes each value. 3. Push the config with the [Truss CLI](https://truss.baseten.co/): ```bash theme={null} truss push . ``` 4. Set the autoscaling concurrency target (each replica handles \~10 concurrent requests before a new one is added). See the model README for the exact Management API call. ### Invoke Once deployed, send inference requests to your model's sync endpoint. The Rime API key is baked in via the `rime_api_key` secret, so callers authenticate to Baseten only: ```python theme={null} import requests resp = requests.post( "https://model-.api.baseten.co/environments/production/sync", headers={ "Authorization": f"Api-Key {BASETEN_API_KEY}", "Accept": "audio/webm;codecs=opus", # or audio/pcm, audio/mpeg }, json={ "text": "Natural-sounding, accurately-pronouncing AI TTS built for high-stakes enterprise conversations.", "speaker": "luna", "lang": "en", }, ) resp.raise_for_status() with open("output.webm", "wb") as f: f.write(resp.content) ``` For full setup instructions, including secrets and autoscaling, see the [`rime-baseten-deploy`](https://github.com/rimelabs/rime-baseten-deploy) README for your chosen model. # Cerebrium Source: https://docs.rime.ai/docs/cerebrium Deploy Rime TTS on Cerebrium's serverless infrastructure. Deploy Rime TTS on [Cerebrium](https://www.cerebrium.ai/) with a Rime API key and Cerebrium CLI 1.39.0 or later. The deployment exposes REST and WebSocket interfaces and scales according to the concurrency and replica settings in `cerebrium.toml`. ### Get started 1. Create a Rime account and obtain your API key. 2. Create a secret in Cerebrium named `RIME_API_KEY` with your Rime key. 3. Initialize your app with the Cerebrium CLI (v1.39.0 or higher): ```bash theme={null} cerebrium init rime ``` 4. Define your deployment using a `cerebrium.toml` file with the `[cerebrium.runtime.rime]` configuration. Specify your compute resources (e.g., AMPERE\_A10 GPU, memory, CPU), scaling parameters, and region (e.g., `us-east-1`). See [Cerebrium's documentation](https://docs.cerebrium.ai/cerebrium/partner-services/rime#rime) for full implementation details. 5. Deploy with: ```bash theme={null} cerebrium deploy ``` Once deployed, you can send real-time TTS inference requests using either: * REST API, with an endpoint like: ```bash theme={null} https://api.cortex.cerebrium.ai/v4//rime ``` Include your RIME API key in the Authorization header and specify your desired speaker, model, and text. * WebSocket interface for streaming audio The Cerebrium container authenticates to the Rime API with the `RIME_API_KEY` secret, and Cerebrium scales your containers automatically based on the concurrency and replica settings defined in the TOML file. For full setup instructions, see the [Cerebrium documentation](https://docs.cerebrium.ai/cerebrium/partner-services/rime#rime). # Changelog Source: https://docs.rime.ai/docs/changelog Release notes for Rime's TTS API and on-prem images. ## Rime API changelog Subscribe to the [RSS feed](https://docs.rime.ai/docs/changelog/rss.xml) to get notified of new releases. * The [language matrix](/docs/voices#languages) now lists support per model. * Coda serves English, Arabic, French, German, Hindi, Japanese, Portuguese, and Spanish. * Mist v3 serves English, French, German, and Spanish. * The `lang` parameter tables in the [Coda API reference](/api-reference/coda/http) now include Arabic and Hindi. * **Cloud Arcana requests will switch to Coda on August 15, 2026.** * On August 15, cloud Arcana traffic will route to [Coda](/docs/models#coda). Migrate by changing `modelId: arcana` to `modelId: coda`; the API contract is unchanged. Sinhala remains available on Arcana. * **On-prem:** existing Arcana images remain available to pull and run, but will not receive updates or support (including vulnerability patches and text-normalization fixes) after August 15, 2026. * We recommend migrating before August 15 so you can test voices and validate output on your own timeline. Questions? Contact [support@rime.ai](mailto:support@rime.ai). * Rime now hosts a first-party MCP (Model Context Protocol) server at [mcp.rime.ai](https://mcp.rime.ai): * Connect Claude, OpenAI Codex, your IDE, or any MCP-compatible client to browse the voice catalog, check dictionary coverage, preview text normalization, generate speech samples, and scaffold Pipecat or LiveKit integration code. * Catalog and integration tools work without an API key; synthesis and linguistics tools authenticate with your existing Rime API key, sent per request. * See the [MCP quickstart](/docs/mcp) to get connected, and the [MCP server reference](/mcp-reference/overview) for tool-by-tool documentation. * The Speech QA dashboard has been retired from the Rime web app. * Pronunciation features remain fully supported via the API: check dictionary coverage with the [Coverage API](/api-reference/other/oov) and specify custom pronunciations inline with the [Rime phonetic alphabet](/platform/rime-phonetic-alphabet) and `phonemizeBetweenBrackets` (Mist v1/v2). * To request a pronunciation fix or dictionary addition, reach out to your account manager via Slack or email, or contact [sales@rime.ai](mailto:sales@rime.ai). * The `saveOovs` parameter on Mist v1/v2 endpoints remains supported for backward compatibility, but has been removed from the API reference along with the dashboard it reported to. * Newly documented: the [Phonemize API](/api-reference/other/phonemize); post a recording of a word and get back a phonetic string in the Rime phonetic alphabet. * See [Pronunciation control](/platform/pronunciation-control) for an overview of all the ways to control pronunciation. * **Coda** is now available via `modelId: coda`: * New flagship TTS model; sophisticated LLM backbone paired with a dedicated speech inference engine, trained on conversational full-duplex data. * Surpasses prior Rime models and competitor offerings in human-led voice-quality evaluations across naturalness, prosody, and artifact-free output. * Sub-100ms model latency on the GPU engine (self-hosted or on-prem); cloud API users add roughly 25–50ms network round-trip from most of the continental US. See [Regional endpoints](/docs/regional-endpoints). * Multilingual support across English, French, German, Japanese, Portuguese, and Spanish. * Word-level timestamps over the JSON websocket endpoint for text-audio alignment and interruption handling. * Available via the cloud API and on-premises at launch. * **Recommended successor to Arcana** for all existing Arcana traffic; swap `modelId: arcana` for `modelId: coda`. * See the [Coda API reference](/api-reference/coda/http) for details. * API on-prem image `20260424`: * New environment variables for authentication configuration: * `RIME_API_KEY`: pre-configure the API key at the deployment level so callers don't need to include it in each request. Can also be mounted as a secret file at `/secrets/rime_api_key`. * `API_KEY_HEADER`: specify an alternate header name for platforms that intercept the `Authorization` header. * `PLATFORM_API_KEY`: supply a platform API key for authenticated inter-container requests. Can also be mounted as a secret file at `/secrets/platform_api_key`. * Arcana V2, Arcana V3 and Mist V3 release `20260420`. * General performance improvements and bug fixes. * Arcana release `20260404`: * Improved and stabilized text normalization across all supported languages. * Upgrade to `20260404` is recommended. * Mist v3 release `20260404`: * Reached general availability. * General performance improvements across the inference stack for all models. * API on-prem image `20260407`: * Compatible with Mist v3. * Mist v3 is now available via `modelId: mistv3`: * TTFB well below 100ms: a major latency improvement over Mist v2 without sacrificing quality * Popular Mist v2 speakers available, plus 8 Arcana flagship speakers now available as Mist v3 voices * See the [full voice list](/api-reference/data/voices) * Arcana release `20260223`: * v3 (multilingual) * Supported languages: `de`, `en`, `es`, `fr`, `he`, `ja`, `pt`, `si`, `ta`. * General performance improvements and bug fixes. * API on-prem image `20260212`: * Exposes a new json websockets endpoint with WLT (equivalent to the cloud api's `ws3` endpoint) on port 8003 * Arcana v3 `lang` parameter: 2- and 3-letter ISO 639 codes that map to the same language are accepted and normalized (e.g. de, deu, or ger for German; fr, fra, or fre for French). Supported languages: | 639-1 | 639-2/639-3 | Language | | ----- | ----------- | ---------- | | de | deu, ger | German | | en | eng | English | | es | spa | Spanish | | fr | fra, fre | French | | he | heb | Hebrew | | ja | jpn | Japanese | | pt | por | Portuguese | Any valid ISO 639-1, 639-2, or 639-3 code that maps to one of these languages is accepted. * Regional endpoints available: * `wss://users-east-ws.rime.ai/ws*` offers all the websockets apis currently served served via `wss://users-ws.rime.ai/ws*` and may provide better latency for clients closer to `us-east-1`. * `https://users-east.rime.ai/v1/rime-tts` offers all the same API currently served via `https://users.rime.ai/v1/rime-tts`, and may provide better latency for clients closer to `us-east-1`. * Additionally `https://users-west.rime.ai/v1/rime-tts` offers all the apis currently served via `https://users.rime.ai/v1/rime-tts`, and may provide better latency for clients closer to `us-west-1`. * Arcana now supports JSON websockets with Word-Level-Timestamps: * `wss://users-ws.rime.ai/ws3` and `wss://users-east-ws.rime.ai/ws3` serve the JSON websockets api that now supports both `mist` and `arcana` model classes. * Arcana release `20260204` (Arcana v3): * Added support for languages: English (`lang=eng`), French (`lang=fra`), German (`lang=ger`), Hebrew (`lang=heb`), Japanese (`lang=jpn`), Portuguese (`lang=por`), Spanish (`lang=spa`). * Languages can be specified using either 2-character codes (`en`, `fr`, `de`, `he`, `ja`, `pt`, `es`) or 3-character codes (`eng`, `fra`, `ger`, `heb`, `jpn`, `por`, `spa`). * Arcana now supports the `spell()` function. You can use `spell()` to spell out sequences letter by letter or number by number with Arcana voices. See the [spell function documentation](/docs/spell) for examples. * Arcana release `20260131`: * General performance improvements and bug fixes. * Arcana release `20260124`: * Fixed speaker mapping for English Arcana. * General performance improvements and bug fixes. * API on-prem image `20260123`: * Exposes the binary websockets API on port 8002. This API is equivalent to the [cloud websockets API](/api-reference/endpoint/websockets). * Arcana release `20260122`: * `rime.engine.initial_latency` and `rime.engine.generated_audio_duration` have saner defaults and [can be tuned](/docs/on-prem/metrics). * Added `spell()` support. * General performance improvements and bug fixes. * Arcana release `20260115`: * Fixed an issue where there is static noise for some speakers at the end or in the middle of utterances. * A full set of ORCA headers are now returned for load balancing. * A `/statusz` endpoint is introduced for the model container that contains diagnostics information. * `/livez` now responds with `OK` as soon as the server starts up. * General performance improvements. * Added [Lovable integration guide](/docs/lovable) with template for building voice-enabled apps. * Added [Replit integration guide](/docs/replit) with template for building voice-enabled apps. * Arcana release `20251220`: * An ORCA header, `named_metrics.inference_concurrency_utilization`, is now returned in all HTTP responses. * Emojis are no longer read out. * General reliability updates. * Arcana release `20251213`: * Performance improvements for the English model. * Minimum requirements for NVIDIA drivers reduced to `525.60.13`. * General reliability updates. * API release `20251209`: * Exposes non-JSON WebSockets over port `8002`, allowing for Arcana over WebSockets. * Fixes an issue where `null` values were sent to the model for parameter keys not set by the user. * Arcana release `20251206`: * [OpenTelemetry metrics](/docs/on-prem/metrics#opentelemetry-metrics) are now available in the model images. * Quality and performance improvements. * Arcana release `20251121`: * Fixed an issue with μ-law encoding. * Arcana release `20251120`: * Fixed an issue with audio buffer underrun. * Arcana release `20251119`: * Fixed a startup issue in the `20251118` release. * Arcana release `20251118`: * General improvements. * Arcana release `20251110`: * Separate engine and data package containers for easier deployment. * General reliability improvements. * Mist on-prem model image `us-docker.pkg.dev/rime-labs/mist/v2/en:20251106` released. * Includes performance enhancements and minor fixes. * Mist on-prem model image `us-docker.pkg.dev/rime-labs/mist/v2/en:20251105` released. * Arcana on-prem model images tagged `20251101` release with language updates. * Arcana language update: additional language support and new voices. * Arcana on-prem model images tagged `20251027`: performance improvements. * Documentation on [performance tuning](/docs/on-prem/performance). * Arcana is now available via (non-json) websockets users.rime.ai/ws. * Arcana on-prem images with tag `20251014`: Fixed a bug related to sample rate. * Arcana on-prem images with tag `20251013`: General performance improvements. * Api on-prem image with tag `20251010`: Uses https instead of http in the external calls to rime.optimize.ai to acquire licenses and track usage. * ⚠️ When upgrading to this image you may have to update your firewall settings to account for the new URLs ([see docs](/docs/on-prem/quickstart#firewall-requirements)). * We have made breaking changes in voice details api ([https://users.rime.ai/data/voices/voice\_details.json](https://users.rime.ai/data/voices/voice_details.json)) * In the voice details API, the field `model_id` has been renamed to `modelId` and `name` have been renamed to `speaker` for better clarity. * In the voice details API, the field `region` has been renamed to `dialect` for better clarity. * The `language` field value has been changed from short codes (e.g., `eng`) to human-readable names (e.g., `english`). * A new field `lang` has been added to retain the short language code (e.g., `eng`). * Arcana on-prem images with tag `20250929`: quality improvements. * Arcana on-prem images with tag `20250927`: quality improvements. * Arcana on-prem English image with tag `20250925`: performance improvements and general model stability enhancements. * Added two new Australian flagship voices: * `eucalyptus` * `marlu` * Arcana on-prem images with tag `20250924`: performance improvements. New api onprem image `us-docker.pkg.dev/rime-labs/api/service:20250917` released. * api image now supports multiple model backends. * /health endpoint on the api image now reports model status. * Both `/ws` and `/ws2` support the query param `saveOovs`, allowing tts users to track which words in their text are out-of-vocabulary on the Speech QA dashboard. * Arcana on-prem images from `20250913` now provide better latency and can run on H100 MIG (`3g.40gb`). * Arcana on-prem images from `20250909` now provide `/livez` and `/readyz` endpoints for liveness and readiness checks. * Arcana on-prem images from `20250908` now use 16-bit little endian for PCM and WAV. * Arcana on-prem images from `20250908` now support G-711 μ-law as an audio codec. * Arcana on-prem images from `20250908` now support the `speedAlpha` option for time scaling. * `saveOovs` parameter added to all mistv2 tts endpoints, enabling users to have out-of-vocabulary words logged to their Speech QA dashboard for review and addition to the mist lexicon. * Added French and German language support via the `lang` parameter in WebSocket JSON APIs. The `/ws2` api now has full language parity with the `/ws` and http tts endpoints. * Added Spanish language support via the `lang: spa` parameter in WebSocket JSON APIs. * Enhanced text segmentation with new `segment` parameter: * Added `segment` query parameter with three modes: "immediate", "never", and "bySentence" (default) * Deprecated `immediate` boolean parameter (still supported for backward compatibility) * Improved control over text processing and synthesis timing * The `` command is now available on both the the websockets and websockets-json apis, allowing for immediate audio synthesis of all tokens in the buffer. * We've launched **Arcana**: a new model for expressive, natural voice synthesis. Available now with `modelId: arcana`. * The `lang` ID `spa-mx` has been added. Using this accesses the same spanish languages but uses `pesos` instead of `dolares` for currency. * New `lang: fra` has been added. We now have French voices available on the dashboard and via API. * The `spell()` function now works for Spanish. Try it out! "El nombre se escribe spell(Isabella)." * Fixed a bug where silence information is not processed properly when `pauseBetweenBrackets` is True * The url `demo-api.rime.ai` has been **deprecated**. Please use `demo.rime.ai` instead if you are using the demo API. # Custom pauses Source: https://docs.rime.ai/docs/custom-pauses Insert pauses of specific durations into Mist family synthesis using angle-bracket markers. Custom pauses are supported by **Mist**, **Mist v2**, and **Mist v3**. By default, Rime adds pauses based on sentence punctuation. To set a specific pause, insert its duration in milliseconds inside angle brackets. For example, `<750>` inserts a pause of 750 milliseconds (or .75 seconds). To hear the difference, compare the following: | Audio clip | Sentence | | ---------- | --------------------------------------- | |