curl --request POST \
--url https://api.opper.ai/v3/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>"
}
'import requests
url = "https://api.opper.ai/v3/videos"
payload = {
"model": "<string>",
"prompt": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({model: '<string>', prompt: '<string>'})
};
fetch('https://api.opper.ai/v3/videos', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"id": "<string>",
"status_url": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"meta": {}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"meta": {}
}Generate a video
Submit a deterministic video-generation job. Returns immediately with a generation id and a status URL to poll; the video is produced asynchronously. model (an id from GET /v3/videos/models) and prompt are required. seconds, resolution and aspect_ratio are normalized across providers; everything in parameters is forwarded verbatim, and each model lists the keys it takes in params.video.parameters. image/last_image/video/reference_images/reference_videos/reference_audios/audio accept an http(s) URL, a data-URI, or a file_<id> (resolved per provider), and each needs the matching capability on the model (see GET /v3/videos/models), else 400. Set store: true to also save the output to /v3/files and get a reusable file_id on the status poll; nothing is stored otherwise. Poll the returned status_url (GET /v3/artifacts//status) for a presigned download URL when complete, or set callback_url to get a signed webhook when the job ends (see GET /v3/webhooks/secret).
curl --request POST \
--url https://api.opper.ai/v3/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>"
}
'import requests
url = "https://api.opper.ai/v3/videos"
payload = {
"model": "<string>",
"prompt": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({model: '<string>', prompt: '<string>'})
};
fetch('https://api.opper.ai/v3/videos', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"id": "<string>",
"status_url": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"meta": {}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"meta": {}
}202 with an id and a status_url. Poll GET /v3/artifacts/{id}/status until completed, then download from the presigned url. See the Video guide for the end-to-end flow, reference image/video inputs, and per-provider parameters.Authorizations
Body
HTTPS URL that receives a signed video.completed or video.failed webhook when the job ends, so you do not have to poll. Rules, each answered with a 400 that names it: https only, port 443 (or none), no user:password@, no #fragment, at most 2048 characters, and a host that is a public IP address or a public name resolving only to public addresses (no localhost, private, link-local, metadata or internal names). Verify the signature with the project's secret from GET /v3/webhooks/secret; see the jobCompleted webhook for the payload, headers and retries.
Retries of the provider's create call on the same endpoint when the provider rejects it before doing any work (HTTP 429 or a gateway 502/503/504 with no result, or a connection that never reached it). A job that is already rendering is never submitted again. Only the successful attempt is billed. Default 2 / max 3; 0 turns retries off.
0 <= x <= 3Audio clips the video follows (voice, music, sound effects), cited in the prompt as audio 1, 2 and so on: URL, data-URI or file_<id>, wav or mp3, at most 10. Needs the reference_audio capability. Seedance 2.5 takes up to 10 clips of 2 to 30 s (30 s in all), Seedance 2.0 up to 3 of 2 to 15 s and needs a reference image or video next to them, as does Seedance 2.5 on fal. Not with image or last_image: put the image in reference_images.