Video
Seedance 2.5
ByteDance's Seedance 2.5 on POST /v1/videos, with the same request and job shape as every other video model
(see Video generation). This page covers what is specific to Seedance 2.5: the five ways to call it,
task_type for calls with a reference video, which hosts support what, and the errors you can hit.
Use bytedance/seedance-2.5 to let VideoRouter pick the cheapest host that can serve your exact request, or
bytedance/seedance-2.5/<host> (for example bytedance/seedance-2.5/fal) to try one host first. A named host is a preference:
if it fails, the call falls over to the others unless you send "provider": {"allow_fallbacks": false}.
| You want | Send |
|---|---|
| Text-to-video | prompt only |
| Animate a first frame (and optionally a last frame) | start_image_url, optionally end_image_url |
| A new video guided by images, video clips and audio (reference-to-video) | input_references, input_video_references, input_audio_references. Refer to them in the prompt as @Image1, @Video1, @Audio1, in upload order. |
| Edit a clip | one clip in input_video_references and task_type: "edit" |
| Extend a clip | one clip in input_video_references and task_type: "extend" |
First-frame, first-and-last-frame and reference inputs can't be mixed in one call. Duration is duration_secs from 4 to 30 seconds;
resolution is 480p, 720p or 1080p; aspect_ratio accepts 21:9 as well as the usual ratios (a 21:9 request is only
routed to hosts that can render it, see Video generation). Draft mode is covered below.
How many reference files a call can carry depends on the host that serves it (up to 30 images, 10 videos and 10 audio clips on the
largest). VideoRouter only routes the call to hosts that can take everything you sent, and returns a 400 if none can.
Reference videos: task_type
When a call includes input_video_references, Seedance has to decide what the job is: a new video guided by your clip
(reference), an edit of the clip, or an extension of it. task_type chooses.
Default: if you send input_video_references and don't send task_type, the call runs as
reference, a new video that uses your clip as a guide. Sending "auto" explicitly lets the prompt decide instead (not recommended, and you may get unexpected results); send
"edit" / "extend" to change the clip. Calls without a reference video (images or audio only) have no task to pick and ignore it.
| task_type | What you get | duration_secs | aspect_ratio |
|---|---|---|---|
reference (default) | A new video guided by your clip, images and audio. The clip is not changed. | Yours, 4 to 30 s | Yours |
edit | Your clip, changed: replace a person, restyle, swap an object. Exactly one clip, 4 to 30 s long. | Not used: the output keeps the clip's length | Not used: the output keeps the clip's ratio |
extend | Your clip, continued. Exactly one clip, 4 to 30 s long. | Yours: how long to generate | Follows the clip |
auto | Seedance reads your prompt and picks one of the three. Not recommended, and you may get unexpected results. | Sent as you gave it | Sent as you gave it |
task_type: "reference" default when a reference video is sent
- A new video guided by your clip, images and audio. You choose
duration_secsandaspect_ratio. - Write the prompt as “use @Video1 as the character / motion reference, generate…”. Don't ask to change, replace or recreate what is in the clip.
- Don't send
duration_secs: -1with it (that value means “match the clip”): it returns400 duration_task_type_conflict.
task_type: "edit" modify the clip you send
- Changes the clip itself. Exactly one reference clip is required.
- The output follows the clip: same length, same aspect ratio. Leave out
duration_secsandaspect_ratio; if you send them they are ignored. - Shortcut: a single reference video with
duration_secs: -1and notask_typeis treated asedit. - Billing: the clip's seconds (rounded up) plus the output seconds, at the host's real cost plus the platform fee. The estimate uses the probed length of your clip (30 s if it can't be probed); the final charge is the host's actual cost.
task_type: "extend" continue the clip
- Continues the clip. Exactly one reference clip is required.
- Aspect ratio follows the clip; you choose how long to generate with
duration_secs. - Don't send
duration_secs: -1: it returns400 duration_task_type_conflict.
task_type: "auto" let the prompt decide Not recommended
- Not recommended, and you may get unexpected results. Seedance reads your prompt and picks new video, edit or extension, so the same request can come back as a different kind of job than you meant. Pin
reference,editorextendinstead. - Your
duration_secsandaspect_ratioare sent as you gave them. If the prompt reads as an edit, Seedance rejects them (an edit has no length or ratio of its own) and the job fails, sometimes only after a few minutes. Failed jobs are not charged, and the call may fall over to another host. - If you leave
duration_secsandaspect_ratioout, the clip can decide the output length and ratio, so a prompt that reads as an edit may hand back something shaped like your clip. Pinreferencewhen you want a new video.
Which hosts support what
Pinning a task_type routes the call only to hosts that can honor it. If none of the hosts available for your model can, the call
returns 400 task_type_not_supported. Support for reference videos on Seedance 2.5:
| Host | reference | edit | extend | Notes |
|---|---|---|---|---|
| MachGen, Atlas Cloud, Fal | Yes | Yes | Yes | |
OpenSand (including the -unrestricted row) | Yes | Yes | Yes | |
SandBase (including -unrestricted) | Yes | Yes | Yes | Reference videos with real people's faces can be refused by SandBase's content moderation; the call then fails over. |
| ToAPIs | Yes | Yes | Yes | |
| WaveSpeed | Yes | Yes | Yes | |
SoCheap (-low) | Yes | No | No | Takes a reference video only with an explicit task_type: "reference" (up to 3 clips). |
| OpenRouter, Replicate | Cannot pin a task | No | No | Used only when you name them yourself; the call then runs as auto. |
Because reference is the default, a Seedance 2.5 call with a reference video and no task_type is only routed to hosts that can pin it. If you name
a host that can't (for example bytedance/seedance-2.5/replicate), the call runs there as auto rather than being moved to a different host.
Examples
A new scene that uses a clip as the character reference (the default), at 21:9:
curl https://videorouter.sh/api/v1/videos \
-H "Authorization: Bearer llmr_sk_live_..." -H "Content-Type: application/json" \
-d '{"model": "bytedance/seedance-2.5",
"prompt": "@Video1 is the character, identity reference only. Late night in a small basement bathroom, he measures the sink with a cloth tape, whispering to himself. Slow handheld push-in.",
"duration_secs": 30, "aspect_ratio": "21:9", "resolution": "1080p",
"input_references": [{"type": "image_url", "image_url": {"url": "https://example.com/bathroom.png"}}],
"input_video_references": [{"type": "video_url", "video_url": {"url": "https://example.com/character.mp4"}}]}'
Edit a clip (no duration or ratio):
curl https://videorouter.sh/api/v1/videos \
-H "Authorization: Bearer llmr_sk_live_..." -H "Content-Type: application/json" \
-d '{"model": "bytedance/seedance-2.5",
"prompt": "@Video1 is the reference. Replace the man with the character in @Image1.",
"task_type": "edit",
"input_references": [{"type": "image_url", "image_url": {"url": "https://example.com/hero.jpg"}}],
"input_video_references": [{"type": "video_url", "video_url": {"url": "https://example.com/clip.mp4"}}]}'
Extend a clip:
curl https://videorouter.sh/api/v1/videos \
-H "Authorization: Bearer llmr_sk_live_..." -H "Content-Type: application/json" \
-d '{"model": "bytedance/seedance-2.5",
"prompt": "Extend @Video1: continue the shot, he slowly lifts his head and looks into the camera.",
"task_type": "extend", "duration_secs": 12,
"input_video_references": [{"type": "video_url", "video_url": {"url": "https://example.com/clip.mp4"}}]}'
Draft mode
Iterate cheaply, pay for 1080p once. Send "draft": true and Seedance 2.5 renders a
480p preview at roughly a quarter of the 1080p price. Re-roll as many drafts as you like;
when one is right, send its id as draft_id and the same take is
re-rendered at 1080p — same prompt, references, seed and audio setting, so the final
keeps the exact composition and motion you approved.
# 1. 480p draft
curl https://videorouter.sh/api/v1/videos \
-H "Authorization: Bearer llmr_sk_live_..." -H "Content-Type: application/json" \
-d '{"model": "bytedance/seedance-2.5/atlas-cloud", "prompt": "A red balloon drifts up against a blue sky",
"duration_secs": 5, "draft": true}'
# -> {"id": "atlascloud:abc...", "draft": true, "draft_expires_at": 1791659164, ...}
# 2. poll GET /v1/videos/{id} until "completed", watch the 480p preview, then:
curl https://videorouter.sh/api/v1/videos \
-H "Authorization: Bearer llmr_sk_live_..." -H "Content-Type: application/json" \
-d '{"draft_id": "atlascloud:abc..."}'
# -> a NEW job id (with "from_draft"); poll it for the 1080p video
- Billing: the draft bills as a normal 480p render and the final as a normal 1080p render (each at the host's real cost + the platform fee). Drafting pays off when you would otherwise generate several 1080p takes to find a good one — a single draft + final costs a little more than rendering 1080p directly.
- Window: a draft can be finalized within 7 days (
draft_expires_at), once, and only after it has completed. A failed final can be retried. - Final request: carries only
draft_id— no prompt, images, duration or resolution (they're fixed by the draft). - Host pinning: a draft only exists on the host that rendered it, so the final always runs there and never fails over. Drafts route only to hosts that support draft mode; text-to-video and image-to-video only (no reference/edit inputs).
Errors and failed jobs
| You see | Why | What to do |
|---|---|---|
400 task_type_not_supported | No host available for your model can honor the task_type you pinned. | Drop the task_type, or use a model whose hosts support it (see the table above). |
400 duration_task_type_conflict | duration_secs: -1 means “match the clip” (an edit) but you pinned reference or extend. | Send a real duration_secs, or use task_type: "edit". |
400 “needs exactly one input_video_references clip” | edit and extend work on a single clip. | Send one clip. |
400 “applies to reference-to-video calls only” | task_type was sent without any reference input. | Add the reference inputs, or drop task_type. |
“Seedance read this prompt as a video edit”
If you send a fixed duration_secs / aspect_ratio with task_type: "auto" and the prompt reads as an edit, Seedance rejects the job,
sometimes only after a few minutes. Either resend with "task_type": "reference" (and reword the prompt so the clip is only a reference), or with
"task_type": "edit" and without those two fields. A failed job is not charged.
“The output audio may be related to copyright restrictions”
Seedance sometimes rejects a finished render because of the audio it generated. It is not tied to your request, the job is not charged, and resubmitting usually succeeds.
Billing
Seedance 2.5 is billed per second of output at the host's real cost plus the platform fee. On most hosts the seconds of your reference video count as well (edit: clip plus output), so a longer reference clip costs more. The price estimate shows this; the final charge is the host's actual cost, and failed jobs are not charged. See Video generation: billing and Pricing & billing.