≡ All docs

Model API / Video Generation

Video Generation

Updated: 2026-09-19

Overview

Generate video asynchronously from a text prompt (or a first-frame image). Because generation takes a while, it is a two-step, submit-then-poll flow: POST to submit a task and get a task_id, then poll by task_id until the status becomes completed.

POST/video/generations

Request Parameters

ParameterTypeRequiredDescription
modelstringRequiredVideo model ID, e.g. doubao-seedance-2-0-260128, doubao-seedance-1-0-pro-250528
promptstringRequiredVideo prompt, in English or Chinese
imagestringOptionalFirst-frame image URL or Base64 for image-to-video; omit for text-to-video
durationintegerOptionalVideo duration in seconds, e.g. 5; pass -1 to let the model pick the duration. Exact range depends on the model
resolutionstringOptionalOutput resolution: 480p / 720p / 1080p / 4k. Omit to use the model default
ratiostringOptionalAspect ratio: 16:9 / 9:16 / 1:1 / 3:4 / 4:3 / 21:9 / adaptive (default adaptive, chosen from the prompt)
generate_audiobooleanOptionalWhether to generate synchronized audio (speech / sound effects / background music). Defaults to true
contentarrayOptionalMultimodal input array of { type: text | image_url | video_url | audio_url }. Use it for video / audio references; plain text-to-video only needs prompt
seed / watermark / camera_fixed-OptionalRemaining official generation params are forwarded as-is, with the same field names as Doubao

Submit a Task

On success the API returns a task object with status queued. Record the id (the task_id) for the follow-up query.

curl -X POST "https://www.starunion.net/v1/video/generations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedance-2-0-260128",
"prompt": "A silver wolf running across a moonlit snowfield, cinematic shot",
"duration": 5,
"resolution": "1080p",
"ratio": "16:9",
"generate_audio": true
}'
JSON
{
"id": "video_7xN3f2k...",
"task_id": "video_7xN3f2k...",
"object": "video",
"model": "doubao-seedance-2-0-260128",
"status": "queued",
"progress": 0,
"created_at": 1708502400
}

Fetch the Result

GET/video/generations/{task_id}

Poll the task status with the task_id from the submit step. The status moves through queued → in_progress → completed (or failed). Poll every 5–10 seconds; once completed, the video URL is in metadata.url.

curl "https://www.starunion.net/v1/video/generations/video_7xN3f2k..." \
-H "Authorization: Bearer YOUR_API_KEY"
JSON
{
"id": "video_7xN3f2k...",
"task_id": "video_7xN3f2k...",
"object": "video",
"model": "doubao-seedance-2-0-260128",
"status": "completed",
"progress": 100,
"created_at": 1708502400,
"completed_at": 1708502460,
"metadata": {
"url": "https://cdn.starunion.net/videos/abc123.mp4"
}
}

OpenAI-compatible Endpoints

Besides /video/generations above, the platform exposes a set of endpoints shaped exactly like the OpenAI Videos API: create, retrieve, download and remix. Both sets share the same models, channels and billing; only the response shape differs — this set always returns an OpenAI video object (object is always video), so the data structures of the OpenAI SDK can be reused as-is.

  • POST /videos — create a generation task
  • GET /videos/{id} — retrieve task status and result
  • GET /videos/{id}/content — download the video file
  • POST /videos/{id}/remix — regenerate from an existing task
Task IDs are interchangeable between the two sets: an id returned by POST /videos can also be polled via GET /video/generations/{id}. The response shapes differ though, so stick to one set within a single integration.

Create a Video (/videos)

POST/videos

The request body accepts application/json, multipart/form-data and application/x-www-form-urlencoded. Fields not listed below are forwarded to the upstream model untouched, so vendor-specific parameters can be written exactly as in the vendor's own docs.

ParameterTypeRequiredDescription
modelstringRequiredVideo model ID, e.g. sora-2, sora-2-pro, doubao-seedance-2-0-260128
promptstringRequiredVideo prompt, in English or Chinese; empty or whitespace-only returns 400
secondsstringOptionalDuration in seconds as a string, e.g. "4"; the integer field duration works too. Allowed range is 1–3600, anything else returns 400 invalid_seconds
sizestringOptionalOutput resolution, e.g. 720x1280. sora-2 accepts only 720x1280 / 1280x720; sora-2-pro also accepts 1792x1024 / 1024x1792
input_referencestringOptionalFirst-frame reference image as URL or Base64 — supplying it makes this image-to-video; image (single) and images (multiple) are accepted as aliases
metadataobjectOptionalVendor-specific parameters, forwarded as-is
Duration is a billing multiplier, so send what you actually need. For sora-2 models, omitting size / seconds bills at 720x1280 and 4 seconds; a size outside the allowed set returns 400 instead of falling back to the default.
curl -X POST "https://www.starunion.net/v1/videos" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "A silver wolf running across a moonlit snowfield, cinematic shot",
"seconds": "4",
"size": "1280x720"
}'
JSON
{
"id": "video_7xN3f2k...",
"task_id": "video_7xN3f2k...",
"object": "video",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1708502400
}

Retrieve a Video (/videos)

GET/videos/{id}

status moves through queued → in_progress → completed (or failed); a task that has just been stored but not yet dispatched briefly returns unknown. Poll every 5–10 seconds; on failure error.message carries the reason. Tasks are scoped to the account owning the API key — someone else's task, or an unknown id, both return 400 task_not_exist.

As with OpenAI, the retrieve response for Sora models carries no video URL — once completed, call /videos/{id}/content to get the file. Other video models (e.g. doubao-seedance) additionally return metadata.url pointing at a platform proxy link, so either way works.
curl "https://www.starunion.net/v1/videos/video_7xN3f2k..." \
-H "Authorization: Bearer YOUR_API_KEY"
JSON
{
"id": "video_7xN3f2k...",
"task_id": "video_7xN3f2k...",
"object": "video",
"model": "sora-2",
"status": "completed",
"progress": 100,
"created_at": 1708502400,
"completed_at": 1708502460,
"seconds": "4",
"size": "1280x720"
}

Download the File

GET/videos/{id}/content

Returns the raw video stream. The platform fetches it from the origin on your behalf, so the upstream address and its signature are never exposed to the client. The response carries Cache-Control: public, max-age=86400 and can be used directly as the src of a <video> element. A task that has not completed yet returns 400.

cURL
curl "https://www.starunion.net/v1/videos/video_7xN3f2k.../content" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o output.mp4

Remix

POST/videos/{id}/remix

Regenerate from an already submitted task with a new prompt. The body only needs prompt — model, resolution and duration are inherited from the original task, and the same channel is reused so the style stays consistent.

Remix is supported by Sora models only; calling it on any other video model returns 400 remix_not_supported and is not billed. It creates a separate task billed on its own using the original task's duration / resolution — it is not a free retry. If the original task does not exist, belongs to another account, or its channel has been disabled, the call also returns 400.
cURL
curl -X POST "https://www.starunion.net/v1/videos/video_7xN3f2k.../remix" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Same wolf, now backlit at dusk, with a slow push-in"
  }'
JSON
{
"id": "video_9pQ8h1m...",
"task_id": "video_9pQ8h1m...",
"object": "video",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1708502500,
"remixed_from_video_id": "video_7xN3f2k..."
}

Didn't find what you were looking for?Contact us →