Skip to main content
Every video — whether it’s one or thousands — is generated the same way: call this endpoint with a list of rows, one object per video (up to 20,000 per request). For a single video, pass a rows list with one item. Use it for a single generation triggered by a user action in your own app, or with a list of people or items — customers, leads, students — to generate one personalized video per row, all from the same template.

Why rows, not a CSV

Generation takes rows — a JSON array of objects — directly in the request body. There’s no CSV to format and no file to host anywhere first: if your data already lives in a database, spreadsheet export, or CRM, you serialize it straight into the request.
Each row’s keys should match the variable names from Get template schema. A row missing a key just leaves that one variable blank in that row’s video — the rest of the batch is unaffected.
Generating just one video? Send rows with a single item — batch_name is optional either way.

Correlating results back to your own data

Add an external_id to any row — your own identifier (a user ID, order ID, anything) — and it comes back unchanged in the CSV export once the batch is done, or immediately via Get single video status while it’s still processing. This is the reliable way to match a result to the input that produced it, since it doesn’t depend on remembering the original order you sent rows in:
external_id is a reserved key — it’s stripped out before the rest of the row is used to fill in the template’s variables, so it never conflicts with a variable of the same name.

Submitting a batch

Response
The template’s scenes are snapshotted at submission time — the whole batch renders consistently against that snapshot even if the template is edited in the editor while the batch is still processing.

Tracking progress

Response — while processing
summary is the headline most integrations poll for while a batch is still running. This endpoint doesn’t return per-row detail — to check on a specific row before the batch finishes, use Get single video status. Once status is done, csv_ready flips to true — at that point, download every row in one file via Download CSV export:
Configure a webhook to receive a bulk_job.completed event when the whole batch finishes — its payload includes the export’s path directly, so you don’t need to poll status first just to check csv_ready.

Cost

A batch costs template.estimated_credits × row_count, deducted upfront when the batch is accepted. If the workspace doesn’t have enough balance, the whole batch is rejected with 402 before anything is created — no partial batches.