Video generation
POST /v1/videos
Asynchronous video generation. Rendering takes a while (typically tens of seconds to a few minutes), so it uses a submit + poll model: submit returns a task ID immediately, then you poll for the result.
Supports text-to-video, image-to-video (single-image first frame / first-and-last frame / multi-image reference), plus reference video and reference audio for advanced use.
1. Submit: POST /v1/videos
1.1 Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
model |
string | Yes | Video model ID. See 1.2 Models. |
prompt |
string | Yes | Text prompt. With reference assets you must refer to them explicitly as @Image1 / @Video1 / @Audio1 — see 1.4 @ reference syntax. |
seconds |
string | Yes | Duration in seconds, as a string, range "5"–"15". |
aspect_ratio |
string | No | Aspect ratio, default 16:9. Allowed values in 1.3 Value ranges. |
resolution |
string | No | Resolution. Determined by the chosen model (see 1.2 Models); usually no need to send it. |
size |
string | No | Standard parameter — a pixel string, one of 1280x720 / 1920x1080 / 720x1280 / 1080x1920, expressing orientation + resolution in a single field (the gateway translates it into whatever shape the target model's upstream expects). aspect_ratio + resolution are an optional, more granular equivalent; if both are sent, the explicit aspect_ratio / resolution wins. |
image_url |
string | No | Single reference image, https:// URL or base64 data: URL, used as the first frame for image-to-video. Also accepts an asset:// asset reference (then treated as a character reference, not a first frame — see 1.5 Virtual-character asset library). Use this when you have only 1 image. Image inputs do not add billed tokens. |
reference_image_urls |
string[] | No | Multiple reference images (up to 9) for style / character consistency, each a URL, data URL, or asset:// asset reference (see 1.5 Virtual-character asset library). @ImageN maps to the Nth item. |
reference_video |
string | No | Reference video (send alongside reference_videos; value = first array item). |
reference_videos |
string[] | No | Reference video array (up to 3, total length ≤ 15s). Note: the reference video's content adds to billed tokens (e.g. a 5s reference video adds roughly 108,900 tokens), but requests with video input are billed at a lower "with video input" per-token price tier — both tier prices are listed in the console model catalog. |
audio_url |
string | No | Reference audio, e.g. for voice style (send alongside reference_audios; value = first array item). Requires ≥1 reference image. |
reference_audios |
string[] | No | Reference audio array (up to 3, total length ≤ 15s). mp3 / wav / m4a / aac / ogg / flac, etc. |
video_config |
object | No | Advanced config; currently supports reference_mode. See 1.3 Value ranges. |
generate_audio |
boolean | No | Whether to include the model-generated soundtrack (music / sound effects). Defaults to true; set false for a silent video. |
seed |
integer | No | Random seed. With the same seed and otherwise identical parameters, generations are reproducible. |
Video generation requires an active subscription (token-based billing, see 3. Billing). Without one the API returns 402.
1.2 Models
There are two product lines: a domestic line and an overseas line (-hw suffix), with independent capabilities and pricing. The overseas line supports the virtual-character asset library (asset://); the domestic line does not. Per-model prices are in the console model catalog.
| Model | Output | Line | Asset library | Notes |
|---|---|---|---|---|
doubao-seedance-2-0 |
720p | Domestic | ✗ | Standard definition. Omni reference (image + video + audio) and extreme aspect ratios. |
doubao-seedance-2-0-1080p |
1080p | Domestic | ✗ | High definition; same capabilities, higher resolution (slower, more tokens per video). |
doubao-seedance-2-0-hw |
720p | Overseas | ✓ | Standard definition; same as domestic 720p plus the virtual-character asset library. |
doubao-seedance-2-0-1080p-hw |
1080p | Overseas | ✓ | High-definition overseas line. |
doubao-seedance-2-0-fast-hw |
720p | Overseas | ✓ | Fast variant — faster generation, lower per-token price. |
1.3 Value ranges
| Parameter | Allowed values / limits |
|---|---|
seconds |
Integer string, "5"–"15" (inclusive). |
aspect_ratio |
16:9 / 9:16 / 1:1 / 4:3 / 3:4 / 21:9 (default 16:9). |
resolution |
Determined by the model: 720p tier (doubao-seedance-2-0 / -hw / -fast-hw) → 720p, 1080p tier (doubao-seedance-2-0-1080p / -1080p-hw) → 1080p. |
size |
Standard values: 1280x720 / 720x1280 (720p models), 1920x1080 / 1080x1920 (1080p models). Non-standard aspect ratios (e.g. 21:9's 1680x720) still need aspect_ratio + resolution. |
video_config.reference_mode |
auto (default, multi-image reference) / start_frame (first frame, exactly 1 image) / start_end (first + last frame, exactly 2 images, no reference video). |
| Reference images | up to 9. |
| Reference videos | up to 3, total length ≤ 15s. |
| Reference audios | up to 3, total length ≤ 15s, and require ≥1 reference image. |
Portrait: send
size:"720x1280"(recommended), or the equivalentaspect_ratio:"9:16"+resolution:"720p". If both are sent, the explicitaspect_ratio/resolutionwins. Image-to-video: sendimage_url(single) orreference_image_urls(multiple), and refer to the image as@Image1inprompt— otherwise the model won't condition on the reference image.
1.4 @ reference syntax
With reference assets, the model relies on @ImageN / @VideoN / @AudioN in prompt to know each asset's role. Assets are cited by type + index (e.g. Image 1 / Video 1 / Audio 1), numbered by their order of appearance in the request:
@Image1=reference_image_urls[0](orimage_urlfor a single image),@Image2=reference_image_urls[1], and so on@Video1=reference_videos[0], and so on@Audio1=reference_audios[0], and so on
With multiple assets you must reference them explicitly via @, otherwise the model guesses which image is which.
1.5 Virtual-character asset library
Besides https:// URLs and base64 data: URLs, the reference-image fields also accept asset://<asset ID> references — virtual-character material that is private to your org and that you upload beforehand to your own asset library. Upload it first via the asset library API to obtain an asset:// ID, then reference it in the video request:
{ "image_url": "asset://asset-20260713-xyz" }Rules:
- Assets are private to your org: only the creating org can reference its own
asset://IDs; referencing another org's (or a nonexistent) ID returns 400. See the asset library API to upload / list / delete. - An
asset://reference may go inimage_urlor as any item ofreference_image_urls, and can be mixed with plain URLs / data URLs (e.g. "library character + your own scene image"). - An
asset://item is always treated as a character reference — even in theimage_urlfield it is not used as a first frame. For first-frame semantics, use a plain URL / data URL. - In
prompt, refer to it as@ImageNper 1.4 @ reference syntax — numbering works exactly like regular reference images (by order of appearance in the request). - Like regular reference images, asset references do not add billed tokens, and they count toward the "up to 9 reference images" limit.
- Overseas line (
-hwseries) only:doubao-seedance-2-0-hw/-1080p-hw/-fast-hw. The domestic line (doubao-seedance-2-0/-1080p) does not supportasset://.
1.6 Response
A successful submit returns immediately (task queued, video not produced yet):
{ "id": "task_xxxxxxxx", "status": "queued", "seconds": 5 }Use the id field as the task ID for polling.
A successful submit is not a produced video. A queued task can still fail (e.g. content-safety rejection); wait for a terminal state via polling.
1.7 Examples
Text-to-video (size only, standard usage)
Sending size alone is enough to fix both orientation and resolution — no need to also send aspect_ratio / resolution:
curl https://api.portal.aiin1.ai/v1/videos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "doubao-seedance-2-0",
"prompt": "a red fox running in snow, cinematic",
"seconds": "10",
"size": "720x1280"
}'Text-to-video (landscape)
curl https://api.portal.aiin1.ai/v1/videos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "doubao-seedance-2-0-1080p",
"prompt": "A cinematic tracking shot through a neon-lit rainy street at night, slow dolly-in, 35mm grain",
"aspect_ratio": "16:9",
"size": "1920x1080",
"seconds": "10"
}'Text-to-video (portrait)
curl https://api.portal.aiin1.ai/v1/videos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "doubao-seedance-2-0",
"prompt": "a red fox running in snow, cinematic",
"seconds": "10",
"aspect_ratio": "9:16",
"resolution": "720p",
"size": "720x1280"
}'Image-to-video (single-image first frame)
The reference image may be an https:// URL or a base64 data: URL. The prompt must refer to it as @Image1.
curl https://api.portal.aiin1.ai/v1/videos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "doubao-seedance-2-0",
"prompt": "@Image1 as the first frame, slow camera push-in, the character turns to look into the distance",
"seconds": "10",
"size": "720x1280",
"image_url": "https://example.com/start-frame.jpg",
"video_config": { "reference_mode": "start_frame" }
}'Image-to-video (multi-image: character + setting)
curl https://api.portal.aiin1.ai/v1/videos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "doubao-seedance-2-0",
"prompt": "@Image1 character wearing a white dress, dancing in the setting from @Image2, anamorphic lens",
"aspect_ratio": "21:9",
"resolution": "720p",
"size": "1680x720",
"seconds": "15",
"reference_image_urls": [
"https://example.com/character.jpg",
"https://example.com/setting.jpg"
]
}'Image-to-video (first + last frame: exactly 2 images)
curl https://api.portal.aiin1.ai/v1/videos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "doubao-seedance-2-0",
"prompt": "Smoothly transition from the first frame to the second, with natural camera movement and lighting changes",
"seconds": "10",
"size": "1280x720",
"reference_image_urls": [
"https://example.com/start-frame.jpg",
"https://example.com/end-frame.jpg"
],
"video_config": { "reference_mode": "start_end" }
}'Virtual-character asset library (asset:// reference)
Mixing a library character with your own scene image — @Image1 refers to the asset, @Image2 to the scene. The model must be an overseas -hw name (the domestic line does not support asset://):
curl https://api.portal.aiin1.ai/v1/videos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "doubao-seedance-2-0-hw",
"prompt": "@Image1 character standing in the setting from @Image2, waving at the camera and smiling, natural light",
"seconds": "5",
"size": "1280x720",
"reference_image_urls": [
"asset://asset-20260713-xyz",
"https://example.com/scene.jpg"
]
}'Omni reference (image + video + audio)
When using
audio_url/reference_audiosyou must also send ≥1 reference image, otherwise it errors.
curl https://api.portal.aiin1.ai/v1/videos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "doubao-seedance-2-0",
"prompt": "@Image1 character dancing to the rhythm of @Audio1, camera motion referencing @Video1, cut on strong beats",
"aspect_ratio": "16:9",
"resolution": "720p",
"size": "1280x720",
"seconds": "10",
"reference_image_urls": [
"https://example.com/character.jpg",
"https://example.com/scene.jpg"
],
"reference_video": "https://example.com/camera-motion.mp4",
"reference_videos": ["https://example.com/camera-motion.mp4"],
"audio_url": "https://example.com/track.mp3",
"reference_audios": ["https://example.com/track.mp3"]
}'2. Poll: GET /v1/videos/{id}
curl https://api.portal.aiin1.ai/v1/videos/task_xxxxxxxx \
-H "Authorization: Bearer YOUR_API_KEY"status goes queued → processing → completed (or failed). Rendering is slow; poll every few seconds.
In progress:
{ "id": "task_xxxxxxxx", "status": "processing" }Completed:
{
"id": "task_xxxxxxxx",
"status": "completed",
"video_url": "https://<bucket>.r2.cloudflarestorage.com/...&X-Amz-Signature=...",
"usage": { "total_tokens": 108900 }
}Failed:
{ "id": "task_xxxxxxxx", "status": "failed" }About
video_url: on completion you get a download link with limited validity — download or re-host it promptly. For a reliable way to fetch the file, prefer the/contentendpoint below.
Field reference
| Field | Description |
|---|---|
id |
Task ID for polling. Bound to your API key's organization; others cannot access it. |
status |
queued / processing / completed / failed. |
video_url |
Convenience download link on completion, with limited validity. |
usage.total_tokens |
Returned on completion — the exact token count billed for this task; use it to reconcile invoices. |
Download the video: GET /v1/videos/{id}/content
Besides the video_url convenience field in the poll response, you can also fetch the raw video bytes directly from a standard endpoint (compatible with the OpenAI SDK's .download_content()). Only available once the task is completed:
curl https://api.portal.aiin1.ai/v1/videos/task_xxxxxxxx/content \
-H "Authorization: Bearer YOUR_API_KEY" \
-o output.mp4Returns binary content as Content-Type: video/mp4. Use whichever fits — video_url is convenient for direct distribution/preview but has limited validity; /content has no expiry concerns and is the recommended way to reliably fetch the video file in production.
3. Billing
- Billed by generated tokens: cost = generated tokens × the per-1M-token price. Per-model unit prices are listed in the console model catalog.
- The token count is deterministic for a given resolution and duration: 720p ≈ 21,780 tokens per second of video (5s ≈ 108,900); 1080p ≈ 49,005 tokens/s (5s ≈ 245,025).
doubao-seedance-2-0-fast-hwuses the same token count as 720p, at a lower unit price. - Reference images do not add billed tokens. Requests containing a reference video do have the video's content added to the token count (e.g. a 5s reference video adds roughly 108,900 tokens), but the whole request is billed at the cheaper "with video input" per-1M-token unit price — both prices are visible in the console model catalog.
- The poll response includes
usage.total_tokens, which is exactly what gets billed — use it to reconcile invoices. - Settled when the video completes; failed / abandoned tasks are not billed.
4. Common errors
| HTTP | Scenario | Notes |
|---|---|---|
| 400 | Missing model |
Incomplete request. |
| 400 | seconds wrong type |
seconds must be a string, e.g. "10" (not a number). |
| 400 | seconds out of range |
Range is "5"–"15". |
| 400 | Wrong field type | e.g. size sent as a number, reference_image_urls not an array of strings. |
| 400 | Unsupported size value |
Only 1280x720 / 1920x1080 / 720x1280 / 1080x1920 are supported; use aspect_ratio + resolution for other aspect ratios. |
| 400 | Resolution does not match the model tier | Resolution is determined by the model you pick: the 720p tier (doubao-seedance-2-0 / -hw / -fast-hw) renders 720p only, the 1080p tier (-1080p / -1080p-hw) renders 1080p only. A cross-tier size / resolution is rejected — switch to the matching model variant. |
| 400 | Too many reference assets | images ≤ 9 / videos ≤ 3 / audios ≤ 3. |
| 400 | Audio without a reference image | Audio reference requires ≥1 reference image. |
| 401 | Invalid API key | Check the Authorization header. |
| 402 | No active subscription | Video is billed per token; you need an active subscription first. |
| 403 | Model not allowed for this key | Check the key's allowed models. |
| 404 | Task not found / not your org | The polled id is wrong or not owned by the current key's org. |
| 413 | Request body too large | Prefer https:// URLs for reference images; switch from a large data URL to a URL. |
| 503 | Temporarily unavailable | Upstream timeout or no available channel; retry later. |