Iodine turns text into lifelike speech over a simple HTTP API. Audio streams back while it's being generated, so playback can start almost immediately, and you pay only for the minutes of audio you get.
- Base URL:
https://api.iodine.dev - Authentication: an API key in the
Authorizationheader - Output: 24 kHz mono 16-bit audio, as WAV or raw PCM
- Price: $0.0075 per minute of speech generated, $0.00015 per minute transcribed, from prepaid credit
Models
| Model | What it's for |
|---|---|
v1 | The production model: fast, natural and steady. Voices ava, katie, sophie. |
v2 | The expressive model: six languages, emotion and delivery cues, and cloned voices. Voices mia, chloe, zander, ethan. |
You choose a model with the model field, or leave it out and Iodine uses the model that has the voice you asked for. See Voices.
Quickstart
1. Get an API key
Sign in to the console, add credit under Billing, then create a key under API keys. Keys look like io_live_… and are shown once, so store yours somewhere safe. Keep it on your server: anyone with the key can spend your credit.
export IODINE_API_KEY="io_live_..."2. Make a request
curl https://api.iodine.dev/v1/tts \
-H "Authorization: Bearer $IODINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Hello from Iodine.", "voice": "katie"}' \
--output hello.wavThat's it: hello.wav holds the speech.
Python
import os
import requests
resp = requests.post(
"https://api.iodine.dev/v1/tts",
headers={"Authorization": f"Bearer {os.environ['IODINE_API_KEY']}"},
json={"text": "Hello from Iodine.", "voice": "katie"},
stream=True,
)
resp.raise_for_status()
with open("hello.wav", "wb") as f:
for chunk in resp.iter_content(chunk_size=None):
f.write(chunk)JavaScript (Node 18+)
import { writeFile } from "node:fs/promises";
const resp = await fetch("https://api.iodine.dev/v1/tts", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.IODINE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ text: "Hello from Iodine.", voice: "katie" }),
});
if (!resp.ok) throw new Error((await resp.json()).error.message);
await writeFile("hello.wav", Buffer.from(await resp.arrayBuffer()));Next steps
- Text to speech: every request option, streaming and the audio formats.
- Emotion and delivery: direct a
v2voice with{happy},{sighs},{whisper}…{/whisper}. - Realtime: a WebSocket for voice agents that speaks text as an LLM writes it.
- Voices: list voices and clone your own.
- Speech to text: transcribe recordings, OpenAI-compatible.
- Errors and limits: what can go wrong and how to handle it.
- Billing and data: credits, pricing and Zero Data Retention.