Text to speech API
Turn text into natural MP3, WAV or OGG audio from your own app, website or script. The API uses the same voices and languages as the site.
API access comes with Pro and Enterprise. Conversions count against your plan's characters, the same as conversions on the site: Pro allows 100,000 characters per request and 3,000,000 a month.
Create an account then upgrade to Pro for API access.
Authentication
Make a key under API keys on your account page and send it with every request:
Authorization: Bearer sk_your_key_here
If your tool can't set that header, send X-API-Key: sk_your_key_here instead.
Keep keys on your server. Don't put them in web pages or apps that other people can download, because anyone with the key can use your characters. If a key leaks, delete it on your account page and make a new one.
Convert text to speech
POST https://www.ttsmp3.ca/api/v1/speech
Content-Type: application/json
{
"text": "Hello! This is a test of the TTSMP3 API.",
"lang": "english",
"voice": "af_heart",
"format": "mp3"
}
| Field | What it does |
|---|---|
text | Required. The text to read. |
lang | Language id from GET /languages. Default english. |
voice | Voice id from GET /voices. Default: the language's first (best) voice. |
format | mp3 (default), wav or ogg. |
style | One of neutral, happy, excited, calm, sad, angry, serious. Default neutral. |
speed | 0.5 to 2.0. Default 1.0. |
pitch | 0 to 99. Default 50. |
pause | Extra pause between sentences in seconds, 0 to 2. Default 0.2. |
wait | Optional. For long text, wait up to this many seconds (at most 120) for the audio before answering. |
Short text is converted right away and the answer has status done (HTTP 200):
{
"id": "3f9c0d2e8a4b4c6f9e1d2a3b4c5d6e7f",
"status": "done",
"chars": 41,
"audio_url": "https://www.ttsmp3.ca/audio/…mp3",
"download_url": "https://www.ttsmp3.ca/audio/…mp3?download=1"
}
Long text is queued and the answer has status queued or working (HTTP 202). Check it every few seconds until it is done or failed:
GET https://www.ttsmp3.ca/api/v1/speech/{id}
Or fetch the audio file itself, which redirects to the file once it is ready:
GET https://www.ttsmp3.ca/api/v1/speech/{id}/audio
Audio files are kept for a few days. Download them if you need them longer.
Languages, voices and usage
GET https://www.ttsmp3.ca/api/v1/languages GET https://www.ttsmp3.ca/api/v1/voices?lang=english GET https://www.ttsmp3.ca/api/v1/usage
/usage shows your plan, its limits and the characters used this month.
Examples
curl
curl -X POST https://www.ttsmp3.ca/api/v1/speech \
-H "Authorization: Bearer $TTSMP3_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Hello from the API","lang":"english","wait":60}'
PHP
$ch = curl_init('https://www.ttsmp3.ca/api/v1/speech');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('TTSMP3_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['text' => 'Hello from PHP', 'lang' => 'english', 'wait' => 60]),
]);
$job = json_decode(curl_exec($ch), true);
if (($job['status'] ?? '') === 'done') {
file_put_contents('hello.mp3', file_get_contents($job['audio_url']));
}
Python
import os, time, requests
API = "https://www.ttsmp3.ca/api/v1"
H = {"Authorization": "Bearer " + os.environ["TTSMP3_KEY"]}
job = requests.post(API + "/speech", headers=H, json={"text": "Hello from Python", "lang": "english"}).json()
while job.get("status") in ("queued", "working"):
time.sleep(3)
job = requests.get(API + "/speech/" + job["id"], headers=H).json()
if job.get("status") == "done":
open("hello.mp3", "wb").write(requests.get(job["audio_url"]).content)
else:
print(job.get("error"))
JavaScript (Node.js 18+)
const API = "https://www.ttsmp3.ca/api/v1";
const headers = { Authorization: `Bearer ${process.env.TTSMP3_KEY}`, "Content-Type": "application/json" };
const job = await (await fetch(`${API}/speech`, {
method: "POST", headers,
body: JSON.stringify({ text: "Hello from Node", lang: "english", wait: 60 }),
})).json();
console.log(job.audio_url ?? job);
Errors
Errors come back as JSON with an error message, for example {"error": "Choose a voice from the list."}.
| Status | Meaning |
|---|---|
| 401 | The API key is missing or wrong. |
| 402 | The text is longer than your plan allows, or this month's characters are used up. |
| 403 | The account isn't on Pro or Enterprise, or is suspended. |
| 404 | Unknown endpoint, language or conversion id. |
| 422 | Something in the request is wrong, such as an unknown voice or format. |
| 429 | Too many requests (60 a minute per key), or a long conversion is already in progress. |
Questions or need higher limits? Contact us about Enterprise.