IVR prompt batch TTS: render phone trees as files — Audra
An IVR tree is the most static audio workload in existence: 'Press 1 for sales' was recorded in 2019 and has played a million times since. Yet every reorganization means a re-record of a human reading forty 5-second prompts into a mic. Batch TTS makes prompt refresh a config change, not a studio session.
This post is the IVR prompt pipeline: batch-rendering a prompt catalog, file format choices for telephony platforms, numbering and versioning, and what a full prompt tree costs on Essential at $25/1M prepaid.
The persona: a 40-prompt phone tree
A mid-size IVR deployment is 30–60 prompts: greetings, menus, hold messages, error messages, after-hours notices, voicemail instructions. Each is 3–10 seconds of speech, 100–300 characters. The entire catalog is maybe 8,000 characters — one afternoon of API calls, forever.
Render the catalog as a manifest
Keep prompts in a manifest (YAML or JSON) keyed by prompt ID, not filenames in a folder. Render each entry, write output as the prompt ID plus version, and upload to your telephony platform in one pass.
curl
curl https://audratalks.com/v2/speech \
-H "Authorization: Bearer sk-audra-..." \
-H "Content-Type: application/json" \
-d '{"model":"audra-essential","voice":"ellis","text":"Thank you for calling Northwind Support. For billing, press one. For technical help, press two.","format":"wav"}' \
--output prompt-menu-main-v4.wav
Python
import requests
PROMPTS = {
"menu-main": "Thank you for calling Northwind Support. For billing, press one. For technical help, press two.",
"hold": "Your call is important to us. Please stay on the line.",
# ... 38 more, from the manifest
}
for pid, text in PROMPTS.items():
resp = requests.post(
"https://audratalks.com/v2/speech",
headers={"Authorization": "Bearer sk-audra-..."},
json={"model": "audra-essential", "voice": "ellis", "text": text, "format": "wav"},
timeout=600,
)
resp.raise_for_status()
open(f"{pid}-v4.wav", "wb").write(resp.content)
JavaScript
const prompts = {
"menu-main": "Thank you for calling Northwind Support. For billing, press one. For technical help, press two.",
"hold": "Your call is important to us. Please stay on the line.",
// ...38 more, from the manifest
};
for (const [pid, text] of Object.entries(prompts)) {
const res = await fetch("https://audratalks.com/v2/speech", {
method: "POST",
headers: { Authorization: "Bearer sk-audra-...", "Content-Type": "application/json" },
body: JSON.stringify({ model: "audra-essential", voice: "ellis", text, format: "wav" }),
});
if (!res.ok) throw new Error(`${pid}: ${await res.text()}`);
await writeFile(`${pid}-v4.wav`, Buffer.from(await res.arrayBuffer()));
}
WAV, not MP3, for telephony
Prompt files are small and telephony platforms transcode to their own telephony codec (often 8 kHz mono) anyway. Request wav — the format post covers the full tradeoff, but the short version: MP3's lossy compression plus a second lossy transcode compounds artifacts, and at 5 seconds per file the size penalty of WAV is irrelevant.
The one thing IVR builders get wrong: reading style
- Write prompts for the ear: 'press one', digits spelled out, no parentheticals or slashes that only parse visually.
- Menu prompts need deliberate pacing — insert <break time="400ms"/> between options so callers can follow. The SSML breaks post has the syntax.
- Say-as: <say-as interpret-as="characters">ABC</say-as> forces letter-by-letter reading for account codes and extensions.
- One voice for the entire tree; a tree that changes voice between menus sounds broken.
Voice: clarity over personality
IVR voices are chosen for intelligibility at 8 kHz through a phone speaker. ellis (en-gb) and grant are the usual picks. Audra outputs −16 LUFS, so all prompts land at consistent loudness — no more 'the hold message is quieter than the menu'.
Cost: effectively zero
A 40-prompt catalog is ~8,000 characters: $0.20 to render the entire tree on Essential, once. Re-rendering the full catalog after every reorganization still costs twenty cents. The 25k trial characters cover initial evaluation; production deployment needs a paid pack (commercial rights on, send X-Audra-Commercial-Use: true).
What IVR is not: realtime speech synthesis during a live call — Audra is a batch file factory, not a telephony stack. Prompt files are generated ahead of time; dynamic content (names, balances) is spoken by your existing telephony TTS or pre-rendered in batches. SSML pacing detail: the SSML breaks post.