New: AI voiceover + auto-captions - script to captioned video in one API call. Read the announcement

AI Voiceover

A script goes in. A narrated video comes out.

Narration is a replacement value, not a production step. Put a tts object where you would put a URL and Renderly generates the voice, drops it into the template's narration slot, and renders - in the same API call. No microphone, no quiet room, no second pass.

Rendered by Renderly. 31 seconds, 77 words, voice jordan. Nothing was recorded.

This is the entire script

Every word you hear in the video above came from this text. It is about 450 characters, which costs half a credit to narrate.

Just listed in Montauk: twenty-seven Dune Crest Road. Tucked where the dunes meet the door, this is coastal living at its finest. Inside - sun-drenched spaces, walls of glass, a chef's kitchen in white oak, and a wrap-around deck over the water. Four bedrooms. Three baths. Thirty-two hundred square feet. And open sand, just a two-minute walk away. Offered at three million, four hundred ninety-five thousand. Book your private tour with Salt and Cedar today.

Note the price is spelled out. Text-to-speech reads $3,495,000 unreliably, so the script says "three million, four hundred ninety-five thousand" while the on-screen text keeps the numerals. A number-to-words helper is the one piece of glue worth writing, and it is the difference between narrated and obviously a robot reading a database.

Narration is a variable

Most pipelines treat voice as a separate stage: generate an mp3 somewhere, upload it, reference the URL, then render. Three systems and a file to keep track of, per video.

In Renderly the template has a sound overlay marked isDynamic and named narration, shipped with an empty src. One request fills it. Send a URL and it plays that; send a tts object and Renderly writes the audio first.

If the generated audio runs longer than the composition, the overlay and the composition stretch to its measured length, and billing follows the real duration. A script that overruns produces a longer video rather than a truncated one.

POST /api/v1/renders
{
  "projectId": "your_project_id",
  "replacements": {
    "listing_address": "27 Dune Crest Road",
    "city_location": "Montauk, New York",
    "price": "$3,495,000",
    "narration": {
      "tts": {
        "text": "Just listed in Montauk: twenty-seven Dune Crest Road...",
        "voice": "jordan"
      }
    }
  }
}

The same shape works with inputProps instead of projectId.

Twelve curated voices, one line each

Every sample below reads the same sentence from the script, so what you are hearing is the voice and nothing else. Set speed between 0.5x and 4x when a read needs pacing rather than a different voice.

"Tucked where the dunes meet the door, this is coastal living at its finest."

Six of the twelve curated voices shown. The full curated set is claudette, emily, geffenv1, henry, hugh_32, jacob, jordan, julie, monica, nick, phil, ruby, and any voice id from Speechify's 992-voice catalogue across 36 locales also works.

Captions that cannot drift

Add one more replacement and the same call also burns in word-synced captions, transcribed from the narration generated in that request. Because the source is the voiceover, sync is not a hope - the captions cannot drift from audio they were transcribed out of.

We checked it end to end: the finished video went back through the captions engine and the transcript came back verbatim, with the spoken price formatted to $3,495,000. Script to speech to text and back, including the number formatting.

How auto-captions work

Narration and captions, one request
{
  "replacements": {
    "narration": { "tts": { "text": "...", "voice": "jordan" } },
    "subtitles": { "transcribe": { "source": "narration" } }
  }
}

At most three AI replacement values per render.

What it costs

0.5 credits
per started 1,000 characters
4,096
characters per request
Refunded
automatically if it fails

Voiceover draws on the same credit balance as rendering, so there is no second wallet to top up. Every operation is logged as an AI job you can inspect. See pricing for render rates.

AI voiceover questions

How does AI voiceover pricing work?
Voiceover costs 0.5 credits per started 1,000 characters, on the same credit balance as rendering. The 77-word script above is roughly 450 characters, so it costs 0.5 credits. Credits are deducted when the operation runs and refunded automatically if it fails.
Which voices are available?
Twelve curated voices: claudette, emily, geffenv1, henry, hugh_32, jacob, jordan, julie, monica, nick, phil and ruby. Any voice id from Speechify's full catalogue of 992 voices across 36 locales also works. You can also set speed between 0.5x and 4x for pacing. Six of the twelve are sampled on this page reading the same line, so the comparison is like for like.
What if the narration is longer than the video?
The narration overlay and the composition stretch to the audio's measured length automatically, and billing reflects the real duration. As a rule of thumb, budget about 2.5 words per second - a 31-second video holds roughly 77 words.
Do I need to record placeholder audio in the template?
No. The narration slot is a sound overlay marked isDynamic with an empty src. It ships silent and stays empty until a render request fills it with a tts value or an audio URL. A render with no narration replacement simply plays the music bed alone.
Can I generate the audio separately from the render?
Yes. POST /api/v1/ai/voiceover takes text and returns an mp3 in your media library with its measured duration and a mediaAssetId, which is useful when you want to pre-generate, listen and reuse. The declarative route puts the same tts object inside a render's replacements so it happens in one call.
How long can a script be?
Up to 4,096 characters per request, and at most three AI replacement values per render. For longer narration, generate the audio with the standalone endpoint and pass the resulting URL as the sound overlay's src.

Narrate your first video today

Start free - no credit card required.