YouTube narration TTS API: scripts to mastered voiceover — Audra
A faceless YouTube channel is a content machine: script on Sunday, render Monday, edit Tuesday, publish Thursday — every week. What breaks channels is not writing, it is narration cost and voice drift. Batch TTS turns the voice track into a fixed line item.
This post is the voiceover pipeline for faceless-channel operators: weekly cadence, script sizing at real channel numbers, the loudness you need for YouTube, and per-video cost on Essential's $25/1M prepaid rate.
The persona: a faceless channel, one 10-minute video per week
A 10-minute video is about 1,400 words of script — call it 7,500 characters, a single sync POST. Channels running explainers, listicles, or documentary-style content at 2–3 videos a week sit around 25,000 characters weekly, still trivially inside the 50k sync limit. At this scale you never write chunking code; you write a render script.
One request per video section
Send the full script to POST /v2/speech and you get back a single mastered MP3: 128 kbps, −16 LUFS. That lands where YouTube normalizes anyway, so what you hear in review is what viewers hear. Editors drop the file straight onto the timeline.
curl
curl https://audratalks.com/v2/speech \
-H "Authorization: Bearer sk-audra-..." \
-H "Content-Type: application/json" \
-d '{"model":"audra-essential","voice":"june","text":"In 1961, a cartographer made a mistake...","format":"mp3"}' \
--output narration.mp3
Python
import requests
resp = requests.post(
"https://audratalks.com/v2/speech",
headers={"Authorization": "Bearer sk-audra-..."},
json={"model": "audra-essential", "voice": "june", "text": script, "format": "mp3"},
timeout=3600,
)
resp.raise_for_status()
open("narration.mp3", "wb").write(resp.content)
JavaScript
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: "june", text: script, format: "mp3" }),
});
if (!res.ok) throw new Error(await res.text());
await writeFile("narration.mp3", Buffer.from(await res.arrayBuffer()));
If your videos run sections with b-roll between them, render per-section instead — intro, segment 1, segment 2, outro — so the editor can move sections without re-cutting audio. Per-section requests also localize failures: one bad render is one redo, not a whole video.
The weekly cadence that works
Batch all sections the same day. A 3-video week is 3–9 requests; render them sequentially, tag each file with video ID and section, and hand the folder to the editor. A QA-listen of the first 30 seconds per file catches what matters — the API already gates silence and truncation before billing you.
Voice: the channel is the voice
Audience retention is identity. Pick one Essential slug and freeze it in the render script as a constant — changing it mid-catalog makes episode 41 sound like a different channel. Because voices are catalog presets rather than clones, the slug renders identically for the life of the channel. Blend if you want a unique timbre: june(2)+wren(1) mixes two presets at fixed weights.
Per-video cost, at faceless-channel numbers
A 7,500-character script at $25/1M costs $0.19 per video on Essential. A 3-video week is about $0.56; a 52-week, one-video-per-week channel narrates for roughly $10 a year. Doubling to long-form 20-minute scripts still keeps you under $0.40 per video. Budget it once on /calc and stop thinking about it.
Watch-outs for YouTube specifically
- Ad reads need different energy than body narration — render them as separate requests, or step up to audra-pro (2.0x) for premium commercial reads.
- Numbers and years: '1961' and '19 thousand' read differently; sample a stats-heavy script before batch-rendering the whole thing.
- Trial credits are 25k chars and evaluation-only — published videos require a paid pack, which also sets commercial rights (send X-Audra-Commercial-Use: true on production renders).
Show-pipeline loudness detail lives in the podcast post; multi-speaker formats in the Conversations post. Voice previews: /voices.