Generate Voiceover
POST /v1/videos/:id/voiceover
Start an asynchronous voiceover generation job using AI text-to-speech.
Voiceover draws 1 video minute per video minute from your monthly allowance. See Plans & Limits.
Prerequisites
The video must have subtitles (run analysis first).
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Video ID |
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
voiceId | string | Yes | Voice to speak with - find one with List Voices |
language | string | No | Language code (see codes) |
sentencePauseSeconds | number | No | Pause between sentences, 0-3 seconds |
applyPronunciations | boolean | No | Apply Brand Kit pronunciation overrides. Defaults to true. |
model | string | No | auto (default), eleven_multilingual_v2, or eleven_v3 |
speed | number | No | Playback speed, 0.7-1.3 |
stability | number | No | Voice consistency, 0-1. Lower is more expressive. |
If your Brand Kit defines how a product name is said, that applies here automatically - the same as
everywhere else in Vidocu. Set applyPronunciations: false only when you want the raw text spoken.
sentencePauseSeconds is capped at 3: the voice engine becomes unstable with longer breaks.
model: auto picks per language - anything the multilingual model can't speak routes to eleven_v3
automatically. Pin one only if you have a reason to override that.
stability on eleven_v3 only accepts 0, 0.5 or 1, so your value is snapped to the nearest of
those. Pass one number and it works on either model.
Loudness matching gain-matches a regenerated clip against the one it replaces. It only applies when replacing a single line, and this endpoint generates the whole video's narration in one pass - there's no reference clip to match against.
Keeping the original voice isn't a voiceover option - it's an audio-cleanup operation, where filler words become trims and the speaker's own audio is kept. It belongs to the audio cleanup tool.
Example
curl -X POST https://api.vidocu.ai/v1/videos/vid_.../voiceover \
-H "Authorization: Bearer vdo_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"voiceId": "EXAVITQu4vr4xnSDxMaL",
"language": "en"
}'
Response 202 Accepted
{
"jobId": "tool_1708300000000_abc1234",
"status": "pending"
}
Polling for completion
Use the Jobs endpoint to check progress, or listen for the voiceover.generated webhook event.
Errors
| Status | Code | Cause |
|---|---|---|
| 400 | validation_error | Video must have subtitles, or missing voiceId |
| 401 | authentication_error | Invalid or missing API key |
| 403 | limit_exceeded | No API access (Business+ required), or video minutes exhausted |
| 404 | not_found | Video not found |
| 423 | locked | The video is locked - unlock it in the Vidocu app before you regenerate its voiceover |
A locked video's content is frozen through its approval cycle, so this endpoint returns 423 Locked. Check locked on GET /v1/videos/:id first. Exporting a locked video still works.