Skip to main content

Export Video

POST /v1/videos/:id/export

Start an asynchronous export job. Produces a final video with subtitles and an SRT file.

Prerequisites

The video must be analyzed first. Exporting a draft video returns an error.

Path parameters

ParameterTypeRequiredDescription
idstringYesVideo ID

Request body

Every field is optional. Anything you leave out falls back to the video's own settings, then to your Brand Kit - so an empty body renders the same way the app would.

ParameterTypeDescription
languagestringSubtitle language (see codes)
ratiostring16:9, 9:16, 1:1, 4:5, or 4:3
watermarkfalse | objectfalse removes it. Object accepts imageUrl, position, size, opacity.
captionsfalse | objectfalse burns none. Object accepts mode, position, positionPercent.
musicfalse | objectfalse renders silent. Object accepts url, volume, duckVolume, fadeDuration, playInScenes.
openingSceneUrlstring | nullnull drops an inherited opening scene
closingSceneUrlstring | nullnull drops an inherited closing scene
zoomsbooleanfalse disables the zoom track for this render
elementsbooleanfalse disables overlay elements for this render
reframebooleanReframe the source for the target ratio instead of letterboxing it
slidesarraySlides to render alongside the footage; replaces the stored deck
avatarSettingsfalse | objectfalse renders without a presenter. Object accepts avatarId, voiceId, layout, sizePercent, shape, backgroundColor, zoom, offsetY.

reframe only matters when ratio changes the shape of the frame: instead of letterboxing, the source is cover-fitted and panned to follow the action. Find an avatarId with List AI Avatars.

Precedence

Request > video > Brand Kit. These overrides apply to one render only - they don't change the stored video or your Brand Kit, so the next export without them behaves as before.

Caption styling (fonts, colors, background) isn't settable here on purpose. It lives in the Brand Kit so every export stays on-brand; captions only controls whether they're burned in and where.

captions.position takes top, middle, bottom or custom. With custom, positionPercent places the caption anywhere between 0 (as high as it goes) and 100 (as low as it goes):

curl -X POST https://api.vidocu.ai/v1/videos/vid_abc123/export \
-H "Authorization: Bearer vdo_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"captions": {"position": "custom", "positionPercent": 70}}'

Both ends of the scale sit against a safe margin, and the caption is anchored by its own edge rather than its centre, so 0 and 100 keep the whole caption on screen no matter how many lines it runs to. Values outside 0-100 are clamped.

Rendering one video several ways

# Vertical cut for social, no watermark, no music
curl -X POST https://api.vidocu.ai/v1/videos/vid_abc123/export \
-H "Authorization: Bearer vdo_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"ratio": "9:16", "watermark": false, "music": false}'

Each call returns its own jobId. Note that a second export of the same video while one is still running returns the in-progress job rather than starting a new render, so wait for the first to finish before requesting a different cut.

Example

curl -X POST https://api.vidocu.ai/v1/videos/vid_.../export \
-H "Authorization: Bearer vdo_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"language": "en"
}'

Response 202 Accepted

{
"jobId": "export_1708300000000_abc1234",
"status": "pending"
}

If an export is already running for this video:

Response 200 OK (existing job)

{
"jobId": "export_1708300000000_abc1234",
"status": "processing",
"message": "Export already in progress"
}

Polling for completion

Use the Jobs endpoint to check progress:

curl https://api.vidocu.ai/v1/jobs/export_... \
-H "Authorization: Bearer vdo_live_your_key_here"

Or listen for the export.completed or export.failed webhook events.

Once complete, the exported files are available on the video object via exportedVideoUrl, exportedSrtUrl, and exportedVoiceoverUrl (combined voiceover MP3, if voiceover was generated).

Errors

StatusCodeCause
400validation_errorVideo must be analyzed before exporting, or invalid body
401authentication_errorInvalid or missing API key
404not_foundVideo not found