curl --request POST \
--url https://coda.api.rime.ai/ \
--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!",
"speaker": "astra",
"lang": "en",
"samplingRate": 24000
}'
import requests
url = "https://coda.api.rime.ai/"
payload = {
"speaker": "astra",
"text": "Hello from Rime!",
"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)
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!","samplingRate":24000}'
};
fetch('https://coda.api.rime.ai/', 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
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://coda.api.rime.ai/",
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 \"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;
}
package main
import (
"io"
"net/http"
"os"
"strings"
)
func main() {
url := "https://coda.api.rime.ai/"
payload := strings.NewReader("{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\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)
}
HttpResponse<byte[]> response = Unirest.post("https://coda.api.rime.ai/")
.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 \"samplingRate\": 24000\n}")
.asBytes();
Files.write(Paths.get("output.webm"), response.getBody());
Coda API reference
Streaming HTTP
Coda streaming HTTP endpoint: synthesize speech with Rime’s flagship model and stream audio back.
curl --request POST \
--url https://coda.api.rime.ai/ \
--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!",
"speaker": "astra",
"lang": "en",
"samplingRate": 24000
}'
import requests
url = "https://coda.api.rime.ai/"
payload = {
"speaker": "astra",
"text": "Hello from Rime!",
"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)
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!","samplingRate":24000}'
};
fetch('https://coda.api.rime.ai/', 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
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://coda.api.rime.ai/",
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 \"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;
}
package main
import (
"io"
"net/http"
"os"
"strings"
)
func main() {
url := "https://coda.api.rime.ai/"
payload := strings.NewReader("{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\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)
}
HttpResponse<byte[]> response = Unirest.post("https://coda.api.rime.ai/")
.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 \"samplingRate\": 24000\n}")
.asBytes();
Files.write(Paths.get("output.webm"), response.getBody());
The Rime API authenticates every request with a bearer token in the
Authorization header: Authorization: Bearer YOUR_API_KEY. See API authentication for how to create a key.
The endpoint streams audio in the format you name in the Accept header. Always set it, because a request without Accept returns 400. A wildcard (*/*) returns WAV, and so does a type the API can’t stream.
Audio formats
Set theAccept 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. A chunk can end mid-sample, so keep whole samples. |
| G.711 μ-law | audio/PCMU | Headerless stream of audio bytes. |
Deprecated aliases
The API still accepts these for backward compatibility. Use the RFC types above in new code.| Deprecated | Use instead |
|---|---|
audio/mp3 | audio/mpeg |
audio/pcm | audio/L16 |
audio/x-mulaw | audio/PCMU |
Variable parameters
string
A Coda voice from the voice catalog. If you leave it out, Coda picks a voice at random for each request, which helps when you try out a language. Set it when every request needs the same voice.
string
required
The text you’d like spoken. The API accepts up to 1,000 characters per request.
string
default:"en"
If provided, the language must match the language spoken by the provided speaker. Pass a BCP 47 language tag:
The 3-letter ISO 639-2 codes that older integrations send (
| Tag | Language |
|---|---|
en | English |
es | Spanish |
fr | French |
pt | Portuguese |
de | German |
ja | Japanese |
ar | Arabic |
hi | Hindi |
it | Italian |
nl | Dutch |
eng, spa, fra, por, ger, jpn, ara, hin, ita, nld) remain accepted, and will stay accepted.See the voices documentation for which speakers support each language.object[]
Pronunciations for words and phrases in
text. Each entry is an object with a spelling and its X-SAMPA pronunciation, and a request can carry up to 500 entries. Coda accepts a lexicon when lang is en, de, es, fr, it, or pt, and returns 400 for other languages. See Phoneme control for the format and examples.number
default:"24000"
The sampling rate (Hz).
number
default:"1.0"
The time scaling factor. Accepted range is 0.4 to 2.5. Values outside this range are clamped without an error.Values above 1.0 slow the audio down, and values below 1.0 speed it up.
curl --request POST \
--url https://coda.api.rime.ai/ \
--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!",
"speaker": "astra",
"lang": "en",
"samplingRate": 24000
}'
import requests
url = "https://coda.api.rime.ai/"
payload = {
"speaker": "astra",
"text": "Hello from Rime!",
"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)
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!","samplingRate":24000}'
};
fetch('https://coda.api.rime.ai/', 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
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://coda.api.rime.ai/",
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 \"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;
}
package main
import (
"io"
"net/http"
"os"
"strings"
)
func main() {
url := "https://coda.api.rime.ai/"
payload := strings.NewReader("{\n \"speaker\": \"astra\",\n \"text\": \"Hello from Rime!\",\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)
}
HttpResponse<byte[]> response = Unirest.post("https://coda.api.rime.ai/")
.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 \"samplingRate\": 24000\n}")
.asBytes();
Files.write(Paths.get("output.webm"), response.getBody());

