Video generation

Generate videos from text and media inputs with async jobs

Video generation runs as an async job: submit a prompt and any media, poll until the job completes, then download the MP4.

1. Submit

curl https://api-gateway.merge.dev/v1/videos \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax/minimax-h3",
"prompt": "a red ball rolling on grass",
"seconds": 4,
"size": "768P"
}'

The response is 202 Accepted with a job whose status is queued.

To start from media, add public URLs in the fields the route expects; capabilities.input in the model catalog shows what it accepts. Gateway forwards extra fields unchanged, so field names, file limits, and rejections come from the vendor.

{
"model": "bytedance/seedance-2.5-reference-to-video",
"prompt": "@Image1 walks along the beach in the style of @Video1, scored by @Audio1",
"image_urls": ["https://cdn.acme.com/mascot.png"],
"video_urls": ["https://cdn.acme.com/style-ref.mp4"],
"audio_urls": ["https://cdn.acme.com/theme.mp3"],
"seconds": 8
}

2. Poll

cURL
curl https://api-gateway.merge.dev/v1/videos/vid_XXXX \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY"

Poll until status is completed, usually one to a few minutes. The completed job carries the settled cost; a failed job carries the vendor error and bills nothing.

3. Download

cURL
curl https://api-gateway.merge.dev/v1/videos/vid_XXXX/content \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY" \
-o video.mp4

The body is the raw MP4, or a JSON error if the job hasn’t completed.

Gateway keeps a job record for 24 hours after its last update, after which the job ID returns 404 video_job_not_found. Download the video soon after it completes.

List and delete

cURL
curl "https://api-gateway.merge.dev/v1/videos?limit=20" \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY"
curl -X DELETE https://api-gateway.merge.dev/v1/videos/vid_XXXX \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY"

GET /v1/videos lists jobs from the last 24 hours, newest first. Pass the previous page’s last_id as after for the next page, and order=asc for oldest first. Entries show each job’s status from its last poll. DELETE /v1/videos/{video_id} removes a finished job; one still rendering returns 409 video_not_deletable. Usage and billing history are kept. The OpenAI SDK’s client.videos.list() and client.videos.delete() work against these endpoints; remix isn’t supported.

Reference

FieldNotes
modelRequired. A canonical model ID, since @alias/... returns 400 alias_not_supported.
promptRequired
secondsClip length, within the model’s limits
sizeOutput resolution. Use a key from output_per_second_by_resolution, such as 768P on minimax/minimax-h3, or WIDTHxHEIGHT.
vendorPin the execution vendor
customerCustomer UUID to scope the key, budget, and usage to

The job object has id, object, status, model, seconds, size, created_at, progress, error, and cost. Any key in your organization can read a job.

Video bills per output second at the served resolution’s rate in output_per_second_by_resolution, settled on the first poll or download that sees the job completed. Input media doesn’t change the rate. generate_audio isn’t forwarded, and the route bills at its with-audio rate. Customer budgets are checked at submit against the requested duration and tier.

Next steps