Skip to content
Catalog

cn8/podcast

Two-stage podcast generation built around a single principle: rendering 5–15 minutes of speech is

Learn more about AI Podcast
Audio & Voiceasync (job)Instant previewaudiovoicepodcast

Plan your episode

The AI writes a full multi-speaker script first — planning is free, you only pay when you render audio.

Jhost
Jguest

Overview

Two-stage podcast generation built around a single principle: rendering 5–15 minutes of speech is expensive, so you should be able to look at it before paying for it. Stage 1 (plan) is an async LLM job that ingests a prompt and/or txt/pdf/docx documents, assigns a consistent voice_mapping for each speaker (gender × style → voice_id), and emits a fully turn-by-turn script — every line carries both transcript_text (what's shown on screen) and tts_text (the same content but phoneticised so the TTS engine pronounces foreign brand names, acronyms, numbers and dates correctly). You review the plan, optionally edit any transcript line, then submit Stage 2 (synthesize) which re-phoneticises only the lines you touched, renders every turn in parallel, stitches the segments with tone-aware gaps and a soft ambient bed, and returns a presigned URL to the finished audio. Both stages run as async jobs (poll /v2/jobs/{id} or attach a webhook). Only the synthesise stage is billed — per second of generated audio.

Key capabilities

Plan, then synthesize

Stage 1 returns a reviewable script + voice_mapping for a flat 10 credits. Edit any line in your UI, mark it transcript_dirty=true, and Stage 2 renders the final MP3 — billed per second.

1–3 speakers, 12 languages

Exactly one host plus 0–2 guests. Per-language voice catalog covers 12 languages × 12 voices (4 styles × 2 genders + 4 backups for when speakers share a style).

Source from prompt and/or documents

Free-text prompt and/or txt/pdf/docx URLs (uploaded via upload-media). At least one source is required.

Async, polled or webhooked

Both stages are async jobs (poll /v2/jobs/{id} or attach a webhook). Failed jobs are never billed.

When to use it

Course recap episodes

Feed a chapter PDF and a one-line prompt; get a 5–9 minute educational interview between a host and a subject expert.

Internal release-notes podcast

Three-voice panel walking through a release: PM frames the topic, two engineers dig into trade-offs and disagree on details.

Marketing explainer

Promotional tone, host pitches, guest endorses — short 2–4 minute episode rendered in a single language.

Audio accessibility for documents

Convert long-form articles or whitepapers into a narrative or self-interview podcast for listeners who don't have time to read.

Multi-perspective debates

purpose=debate with two guests; the LLM picks pro/con stances grounded in the source material and lets them challenge each other directly.

Input & output

input

Plan: source (prompt and/or document_urls) + tone + purpose + speakers (1–3) + length + language. Synthesize: the (possibly edited) PodcastPlan returned by Stage 1, plus tone for ambient bed.

JSON bodydocument URLs (txt / pdf / docx via upload-media media_type=document)

output

Plan: PodcastPlan = voice_mapping + script (transcript_text + tts_text + emotion per turn) + meta. Synthesize: presigned MP3 URL + duration_seconds + per-segment timeline.

JSON (PodcastPlan)S3 MP3 (presigned GET URL)

Guides & tips

Why two stages?

Rendering a multi-speaker podcast is slow and irreversible-feeling: minutes of audio and a meaningful credit charge. Stage 1 (plan) gives you a complete, editable preview for 10 credits. Stage 2 (synthesize) is the only step that calls the TTS provider and incurs cost. Edit lines in the plan as many times as you like — until you submit synthesize, nothing is billed.

Editing the script and the transcript_dirty flag

Every script turn has two strings:

  • transcript_text — what's shown on screen / read by humans (natural spelling).
  • tts_text — the same line phoneticised for the TTS engine (foreign words and acronyms

respelled in the target language, numbers spelled out).

When the user edits transcript_text in your UI, set transcript_dirty=true on that turn before sending the plan to core-podcast-synthesize. tts_text is then regenerated from the new transcript_text before speech is generated. To override pronunciation by hand, edit BOTH fields and leave transcript_dirty=false — your tts_text is used verbatim.

Polling vs webhooks

Both core-podcast-plan and core-podcast-synthesize are async. After submission you get a 202 + job.id. From your application, poll GET /v2/jobs/{job_id} every few seconds until status is "completed" or "failed". Or attach a webhook to the API key + service via PUT /v1/api-keys/{key_id}/webhook-mappings — your URL is called when the job finishes, with the same result_data shape you'd get from polling.

Specs

Latency
Plan ~10–30s (LLM scripting + document ingest); synthesise ~5–15s for short, ~1–3 min for long episodes (parallel TTS + stitching). Both async — poll /v2/jobs/{id} or use a webhook.
Async
true
Rate Limit
100 req/s per API key — applied to plan and synthesize submission.
Max Input
Up to 3 speakers; 50 MB per source document; ~2000 words target for a long episode.

Schema

Request body

tonerequiredstring

Selects the ambient bed (friendly→warm_room, formal→studio_silence, playful→light_room, serious→low_room, inspirational→soft_pad).

enum: friendly, formal, playful, serious, inspirational

planrequiredPodcastPlan

The full PodcastPlan returned by core-podcast-plan, optionally with edited script turns. voice_mapping must NOT be dropped — each script.speaker must match a voice_mapping.display_name.

voice_mappingrequiredarray<VoiceAssignment>

Carry the mapping through verbatim. It is used to look up voice_id per speaker during synthesis.

scriptrequiredarray<ScriptTurn>

Edit transcript_text freely; set transcript_dirty=true on edited turns to trigger automatic tts_text regeneration. Or edit BOTH transcript_text and tts_text and leave transcript_dirty=false.

metarequiredPlanMeta

Carry through; not used by synthesis but required by the plan schema.

Response

result_data.data.s3_urlstring

Presigned GET URL to the rendered MP3 (TTL = 24h by default).

result_data.data.s3_object_urlstring

Object URL (no signature). Useful as a stable reference; re-presign through your own bucket if you need long-term access.

result_data.data.duration_secondsnumber

Final mixed duration. Drives billing — cost = duration_seconds × $0.05.

result_data.data.segmentsarray<object>

Per-turn timeline: speaker, text, start_ms, end_ms, voice_id, emotion.

units_consumednumber

Same as duration_seconds (the billing field).

Pricing

Voices are free and the plan is a flat 10 credits; synthesis is billed by duration of the generated audio.

ServiceUnitPrice
List Podcast VoicesitemFree
Plan Podcast Scriptitem10 credits
Synthesize Podcastsecond$0.05/second

A 5-minute episode (~300 s) costs 1,500 credits ($15.00) in synthesis.

Editing the plan in your own UI is free; re-running core-podcast-plan costs 10 credits each time.

Document upload via upload-media is free.

FAQ

Related models