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.
Seedance 2.5
Use doubao-seedance-2-5 (720p) or doubao-seedance-2-5-1080p (1080p) with the same POST /v1/videos and task polling endpoints.
seconds accepts strings "4"–"30", or "0" for automatic duration. Inputs allow 30 images, 10 videos and 10 audio files, up to 50 items total, using downloadable HTTPS URLs. Images also accept PNG/JPEG/WebP base64 data URLs, converted by the gateway. Video/audio data URLs and asset:// are unsupported. First-frame and first/last-frame modes require aspect_ratio:"adaptive" (the 2.5 default); omit a fixed pixel size. output_format accepts mp4 or mov; generate_audio defaults to true in this gateway.
You may supply native mode and media instead of the legacy reference fields. Modes are TEXT_TO_VIDEO, IMAGE_TO_VIDEO, FIRST_LAST_FRAME, REFERENCE_MATERIAL, VIDEO_EDIT and VIDEO_EXTEND. Media objects contain type, role and url. Editing requires seconds:"0"; editing and extension require aspect_ratio:"adaptive". Never mix media with legacy reference fields.
Settlement uses actual output tokens. Official USD list prices per million tokens without/with video input: 720p $10.70 / $6.40; 1080p $11.70 / $7.00. Subscription and channel multipliers still apply.
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, at most 5000 characters for domestic standard 2.0 / 2.5. With reference assets you must refer to them explicitly as @Image1 / @Video1 / @Audio1 — see 1.4 @ reference syntax. |
seconds |
string | Yes | Domestic 2.0 standard/1080p: "4"–"15"; 2.5: "4"–"30" or "0" automatic; other 2.0 variants: "5"–"15". Always integer strings. |
aspect_ratio |
string | No | 16:9 / 9:16 / 1:1 / 4:3 / 3:4 / 21:9. 2.0 defaults to 16:9; 2.5 also accepts and defaults to adaptive. 2.5 first-frame, first/last-frame, edit and extend modes require adaptive: output ratio follows the material. Omit size; do not copy a fixed-ratio 2.0 image-to-video example unchanged. |
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 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 (2.0 up to 9; 2.5 up to 30) 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 (2.0 up to 3, total length ≤ 15s; 2.5 up to 10). 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). 2.0 requires an image or video; 2.5 allows audio-only references. |
reference_audios |
string[] | No | Reference audio array (2.0 up to 3, total length ≤ 15s; 2.5 up to 10). 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. |
mode |
string | No | 2.5 advanced mode; see the mode/role table below. Inferred from reference fields when omitted. |
media |
object[] | No | 2.5 material objects with type, role, url. Cannot be combined with legacy reference fields or video_config. |
output_format |
string | No | 2.5: mp4 (default) or mov. |
watermark |
boolean | No | 2.5: add a watermark; defaults to false. |
Video generation requires an active subscription (token-based billing, see 3. Billing). Without one the API returns 402.
Materials and limits: 2.5 allows 50 materials in total. Use directly downloadable HTTPS URLs; images also accept
data:image/png;base64,..., JPEG or WebP (decoded image ≤ 10 MiB; whole JSON request ≤ 15 MiB). The gateway converts inline images, with no separate customer upload. Video/audio references cannot usedata:.asset://remains overseas-hwonly. Resolution: both 2.0 and 2.5 pin 720p/1080p to the model ID. A cross-tiersize/resolutionreturns 400; explicit aspect-ratio precedence does not override the model resolution tier.
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-5 |
720p | Domestic | ✗ | 4–30s or automatic duration; edit/extend, MOV and more reference materials. |
doubao-seedance-2-5-1080p |
1080p | Domestic | ✗ | 2.5 high-definition tier; same remaining rules as 720p. |
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-fast |
720p | Domestic | ✗ | Fast variant — faster generation, lower per-token price. |
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 |
Domestic 2.0 standard/1080p: "4"–"15"; 2.5: "4"–"30" or "0" automatic; other 2.0 variants: "5"–"15". Always integer strings. |
aspect_ratio |
16:9 / 9:16 / 1:1 / 4:3 / 3:4 / 21:9. 2.0 defaults to 16:9; 2.5 also accepts and defaults to adaptive. 2.5 first-frame, first/last-frame, edit and extend modes require adaptive: output ratio follows the material. Omit size; do not copy a fixed-ratio 2.0 image-to-video example unchanged. |
resolution |
Fixed by the model: doubao-seedance-2-0 / doubao-seedance-2-5 and 720p fast/hw variants render 720p; model IDs containing -1080p render 1080p. No 480p/4K tier. |
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 | 2.0: up to 9; 2.5: up to 30. |
| Reference videos | 2.0: up to 3, total duration ≤ 15s; 2.5: up to 10. |
| Reference audios | 2.0: up to 3, total duration ≤ 15s, with an image or video; 2.5: up to 10, including audio-only references. |
Portrait text-to-video / multi-image reference (excluding 2.5 first/last-frame modes): 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.
2.5 media modes (when using them, omit image_url, reference_*, audio_url and video_config):
mode |
Material requirements |
|---|---|
TEXT_TO_VIDEO |
No materials |
IMAGE_TO_VIDEO |
Exactly one image/first_frame; adaptive |
FIRST_LAST_FRAME |
One each of image/first_frame and image/last_frame; adaptive |
REFERENCE_MATERIAL |
image/reference_image, video/reference_video, audio/reference_audio; at least one item, no first/last frames |
VIDEO_EDIT / VIDEO_EXTEND |
Reference roles with at least one video/reference_video; adaptive; editing requires seconds:"0" |
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
Seedance 2.5 image-to-video (material determines ratio)
{"model":"doubao-seedance-2-5","prompt":"@Image1 moves slowly","seconds":"5","aspect_ratio":"adaptive","image_url":"https://example.com/start-frame.jpg","generate_audio":true}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.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.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.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.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.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",
"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.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.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)
In 2.0,
audio_url/reference_audiosrequire an image or video; 2.5 also permits audio-only references.
curl https://api.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.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.aiin1.ai/v1/videos/task_xxxxxxxx/content \
-H "Authorization: Bearer YOUR_API_KEY" \
-o output.mp4Returns video bytes; MP4 normally uses Content-Type: video/mp4. A 2.5 MOV request returns the actual video format. 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.
- 2.0 token estimates (actual settlement uses returned usage; 2.5 does not use a fixed per-second estimate): 720p ≈ 21,780 tokens per second of video (5s ≈ 108,900); 1080p ≈ 49,005 tokens/s (5s ≈ 245,025). The fast variants (
doubao-seedance-2-0-fast/-fast-hw) use 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 |
Domestic 2.0 standard/1080p: "4"–"15"; 2.5: "4"–"30" or "0" automatic; other 2.0 variants: "5"–"15". Always integer strings. |
| 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 / -fast / -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 | 2.0: 9/3/3; 2.5: 30/10/10, 50 total. |
| 400 | 2.0 audio without visual material | Include an image or video; 2.5 permits audio-only references. |
| 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 | Model-service timeout or no available channel; retry later. |