How do I automate a daily morning briefing audio with a TTS API?
A daily briefing of 2,200 characters is one TTS job: 11 cents a day, $3.30 for 30 days on Sume, plus a 1-cent concat if you add a music sting.

Automate a daily briefing by writing the script in your own scheduler, sending it to one asynchronous TTS job per day with the date in the idempotency key, and publishing the finished file. A five-item briefing of about 2,200 characters is about three minutes of speech and costs $0.11 per day on Sume, $3.30 for a 30-day month. Adding a music sting and joining it takes one Timeline audio concat at a flat $0.01, so a branded briefing is $0.12 a day.
Sume does not schedule anything or write the script; it turns text into an audio file when you ask. That split is the useful part: the schedule, the sources and the editorial judgment stay in your system, and the paid call is one small, predictable job.
Size the script in characters
Cartesia's pricing page says one minute of Sonic audio is 750 to 800 credits at one credit per character, and Sume TTS 1.0 meters one credit per character. A three-minute briefing is therefore 2,250 characters at the slow end and 2,400 at the fast end. Plan five items of about 400 characters each, plus a 100-character greeting and a 100-character sign-off, and you land near 2,200.
At $0.0475 per 1,000 characters that is $0.1045, rounded up by the catalog to $0.11. The charge is per job and per character sent, so the length of the listen is your cost control: add an item and you can see exactly what it adds, about 2 cents per 400 characters.
One job per day, safe to retry
A scheduler will sometimes fire twice or retry after a timeout. Put the date in the Idempotency-Key header so a repeat returns the same job instead of a second paid one. The script below submits the job and prints its id; in production, add a poll on /v1/jobs/{id}/status until terminal is true, or pass mode: "webhook" with a webhook_url and let the signed callback tell you the file is ready.
const day = new Date().toISOString().slice(0, 10);
const script = process.argv[2];
const res = await fetch("https://api.sume.com/v1/tts-1.0/generate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SUME_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": `briefing-${day}`,
},
body: JSON.stringify({
transcript: script,
voice: { id: process.env.VOICE_ID },
language: "en",
generation_config: { speed: 1.05 },
mode: "async",
}),
});
const out = await res.json();
console.log(day, (out.data ?? out).request_id);Add a sting without paying every day
Make the intro sting once. A Music Router prompt for a short, instrumental sting costs $0.125 for one generation, and you reuse the file every day. The Timeline audio concat joins up to 20 parts with no re-synthesis and no silence at the seams, so the daily file is the sting plus the day's voice for $0.01. Use wav for the voice if you will join it; mp3 adds encoder padding at each edge.
If you want the sting under the first sentence rather than before it, use a Timeline render with the voice as the spine and the sting as the soundtrack, but that produces an MP4 at $0.10 per started output minute, which is overkill for a podcast feed.
What a month costs, by pace
| Service | Rate per 1M characters | One day | 30 days |
|---|---|---|---|
| Sume TTS 1.0 | $47.50 | $0.11 | $3.30 |
| Sume TTS 1.0 plus sting concat | $47.50 | $0.12 | $3.60 |
| MAI-Voice-2.1 | $22 | $0.048 | $1.45 |
| ElevenLabs Flash / Turbo | $40 | $0.088 | $2.64 |
| ElevenLabs v3 | $80 | $0.176 | $5.28 |
Failure handling that keeps the feed on time
Because the cost per day is only a few cents, the engineering effort goes into reliability, not savings. The vendor with the lowest rate saves you cents a month at this volume; a missed feed costs more than that in trust. Log the job id, the character count and the date for every briefing, so a listener complaint can be traced to one job and its text, and so your monthly total is a sum you can check against the invoice.
- Submit the job well before the publish time; queued is a normal accepted state, and a job can wait behind your workspace's concurrency limit.
- If the job fails, the public error is on the job record; fix the cause and resubmit with a new key suffix such as
-retry1, because the old key would return the old job. - Keep yesterday's file as a fallback and publish it with a note if the new one is late.
- Confirm the live rate in
GET /v1/catalogbefore you budget a month, and test with a single real job.
Sources
Related posts
More in Use cases
- How do I make AI announcer intros for conference speakers?
Ten 25-second speaker intros with one shared sting cost about 43 cents on Sume: 2 cents of TTS and a 1-cent join each, plus a $0.125 track made once.
- How do I make a safety briefing audio in three languages with TTS?
One 1,800-character briefing in English, Spanish and Polish is three TTS jobs: 9 cents each, 27 cents in all on Sume. Set language on every job and review it.
- How do I narrate a family history video with AI voice and photos?
Narrate a family history from old photos: 1,800 characters of script is $0.09 on Sume TTS, plus a $0.125 music bed and a $0.30 Timeline render.
- What does a first-time home buyer video series cost with an avatar?
Six 30-second avatar tips cost $33.12 at standard, $44.10 at plus or $99.00 at max on Sume, plus $0.95 once for the avatar. Rates and script limits.
Written by Sume