Doubao Seedance 2.0 Video API Guide: Task-Based Generation via Volcengine Ark
A practical guide to Seedance 2.0 video generation: model IDs, async task flow, text-to-video, image-to-video, pricing caveats, and how to route Seedance through TheRouter without overclaiming unsupported features.
Doubao Seedance 2.0 is a video generation model family from ByteDance. The practical API shape is asynchronous: create a generation task, store the returned task id, poll until it succeeds, then fetch the video URL before it expires. If you are using TheRouter, the safe integration stance is to route the verified Seedance model IDs through our media endpoints while keeping provider-specific task fields explicit and tested.
We wrote this guide because Seedance queries are implementation-shaped: developers are not asking whether the model exists; they are asking which endpoint to call, which model id to pass, and where the polling loop belongs. The short answer: use the full-quality doubao/doubao-seedance-2-0 model for final renders, use doubao/doubao-seedance-2-0-fast for iteration, and keep a retryable async workflow around every request.
- Swap three values, not three SDKs. Change
api_key,base_url, andmodelin the existing OpenAI client. Keep your request/response code unchanged. - Map model IDs explicitly. The target provider's model id is almost never identical to the OpenAI id. Keep a single dict of
{ openai_id: target_id }outside business logic. - Verify streaming format. SSE chunks must follow the OpenAI
data: {...}+data: [DONE]contract. Test one streaming call before moving production traffic. - Check rate-limit headers. Some providers omit
x-ratelimit-*headers. Add a wrapper that defaults safely when headers are absent. - Keep a rollback path. Ship the swap behind a feature flag, run both endpoints in shadow for 24 hours, then cut over.
Seedance 2.0 at a Glance
| Decision point | Recommended default | Why it matters |
|---|---|---|
| Final-quality model | doubao/doubao-seedance-2-0 | Better fit for production clips and higher-quality review passes |
| Iteration model | doubao/doubao-seedance-2-0-fast | Lower-cost, lower-latency draft path for prompt tuning |
| Native Ark task API | POST /v1/contents/generations/tasks then poll task detail | Volcengine documents video generation as a task lifecycle, not a blocking response |
| TheRouter path | Use the model pages and media-generation route documented for your account | We avoid promising an exact product path beyond verified docs and code |
| Inputs to test first | Text prompt, one reference image, 5-second duration, 16:9 | Small jobs expose auth, model-id, polling, and output URL behavior quickly |
ByteDance's Seed page describes Seedance 2.0 as a unified multimodal audio-video generation architecture that can use text, image, audio, and video inputs as references. Volcengine's Ark docs list a dedicated video generation API section with create, query, list, cancel, and delete task pages; the create-task page was last updated on 2026-06-25. Sources: ByteDance Seedance 2.0, Volcengine Ark create video generation task API, Volcengine Ark Seedance 2.0 tutorial. Retrieved 2026-06-26.
When to Use Standard vs Fast
Use standard Seedance 2.0 when the clip is close to production: product hero shots, final social assets, brand review, or any prompt where motion stability matters more than turnaround time. The TheRouter model card describes it as the flagship text/image-to-video tier and exposes the model id doubao/doubao-seedance-2-0.
Use Seedance 2.0 Fast when the prompt is still changing. We like it for storyboard passes, camera-language tuning, and finding the right reference image before spending on a final render. The Fast model page positions it as the lower-cost, lower-latency variant for iterative video drafting.
Internal links to keep nearby:
- Provider hub: ByteDance / Doubao on TheRouter
- Standard model: doubao/doubao-seedance-2-0
- Fast model: doubao/doubao-seedance-2-0-fast
- Related provider guide: Volcengine Ark / Doubao API Complete Guide
- Adjacent video alternative: OpenAI Sora 2 Pro
Native Volcengine Ark Task Flow
Volcengine's Seedance API is easiest to reason about as a queue:
- Submit a task with model id, content references, duration, ratio, resolution, and watermark preference.
- Save the returned task id.
- Poll the task endpoint with exponential backoff.
- Treat
succeededas the only downloadable state. - Persist the generated asset to your own storage; third-party guides report expiring output URLs, so do not leave the only copy at the provider URL.
A native Ark-style text-to-video request looks like this:
curl -X POST "https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d '{
"model": "doubao-seedance-2-0-260128",
"content": [
{
"type": "text",
"text": "A golden retriever running through a sunlit wheat field, wide tracking shot, cinematic lighting"
}
],
"resolution": "1080p",
"ratio": "16:9",
"duration": 5,
"watermark": false
}'
The exact public model id differs between native Ark (doubao-seedance-2-0-260128) and TheRouter (doubao/doubao-seedance-2-0). Keep this mapping in config rather than scattering strings through application code. Source: Apidog Seedance 2.0 API walkthrough, retrieved 2026-06-26; cross-checked against local TheRouter model data.
Routing Seedance Through TheRouter
For TheRouter, the integration goal is not to hide that video generation is asynchronous. It is to keep one account, one routing layer, and stable model identifiers while preserving the provider task semantics your app needs.
A minimal TypeScript shape looks like this:
const response = await fetch("https://api.therouter.ai/v1/videos", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.THEROUTER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "doubao/doubao-seedance-2-0",
prompt: "A clean product demo shot, white background, slow orbit camera",
seconds: 5,
aspect_ratio: "16:9",
size: "1080p",
}),
});
const task = await response.json();
console.log(task.id);
Then poll the returned id:
async function waitForVideo(taskId: string) {
for (let attempt = 0; attempt < 30; attempt++) {
const r = await fetch(`https://api.therouter.ai/v1/videos/${taskId}`, {
headers: { Authorization: `Bearer ${process.env.THEROUTER_API_KEY}` },
});
const task = await r.json();
if (task.status === "succeeded") return task;
if (task.status === "failed" || task.status === "expired") throw new Error(task.status);
await new Promise((resolve) => setTimeout(resolve, Math.min(30000, 2000 * 2 ** attempt)));
}
throw new Error("Seedance task timed out");
}
We deliberately keep this example conservative: verify your account's current media endpoint and response fields before shipping. The truthful capability we can stand behind is that TheRouter exposes routed media-generation jobs where implemented; we should not claim every provider-specific response field is normalized unless docs or code verify it.
Text-to-Video and Image-to-Video Examples
Start with text-to-video because it isolates the moving parts:
{
"model": "doubao/doubao-seedance-2-0",
"prompt": "A macro shot of a mechanical keyboard assembling itself, shallow depth of field, soft studio lighting",
"seconds": 5,
"aspect_ratio": "16:9",
"size": "1080p"
}
Once polling works, add a reference image:
{
"model": "doubao/doubao-seedance-2-0-fast",
"prompt": "Animate the reference image into a slow dolly-in product reveal, keep the logo stable",
"image_url": "https://example.com/reference-product.png",
"seconds": 5,
"aspect_ratio": "1:1",
"size": "720p"
}
Our production preference is to store the original prompt, reference asset hash, model id, task id, final asset URL, and any provider error body. Video bugs are hard to reproduce if you only save the final URL.
Pricing, Latency, and Output Retention
TheRouter's local model data currently mirrors Ark video cost as a per-video flat request estimate: 4.66668 for doubao/doubao-seedance-2-0 and 3.66672 for doubao/doubao-seedance-2-0-fast, with a note that the values should be refined after observed usage. Volcengine's pricing page was updated on 2026-06-23 and search snippets show video price rows varying by resolution, aspect ratio, input duration, and output duration.
That means the responsible engineering stance is:
- do not promise Seedance is the cheapest video route;
- cap duration and resolution in product UI;
- log request parameters next to cost records;
- use Fast for prompt exploration, then standard for final render;
- download and re-host completed videos rather than relying on provider retention.
Sources: Volcengine Ark model pricing, local docs/lib/models-data.ts, Apidog Seedance API walkthrough. Retrieved 2026-06-26.
Common Errors and Fixes
| Symptom | Likely cause | Fix |
|---|---|---|
401 or 403 | Wrong key, disabled model, or wrong provider account | Recreate the key, enable Seedance in the provider console, and test a tiny 5-second job |
Task never leaves queued | Provider-side capacity or too-aggressive polling | Back off to 5-30 second polling intervals and show a pending state in UI |
failed with content-policy text | Prompt, reference image, or requested output violates policy | Store the failure body and show a human-editable prompt correction path |
| Output URL disappears | Temporary provider storage | Copy the asset to your own object storage immediately after success |
| Costs surprise the team | Duration, resolution, or reference inputs changed | Make seconds, size, and model tier visible in logs and dashboards |
Production Checklist
- Keep model ids in config:
doubao/doubao-seedance-2-0anddoubao/doubao-seedance-2-0-fast. - Implement idempotency on task submission so retries do not create duplicate videos.
- Poll with exponential backoff and an upper timeout.
- Save prompt, model, parameters, task id, status history, cost estimate, and final asset URL.
- Download completed videos to durable storage.
- Expose Fast vs standard as a product choice, not a hidden random router decision.
- Link your internal docs to TheRouter's ByteDance provider page and both Seedance model pages so operators can verify current metadata.
FAQ
Is Seedance 2.0 OpenAI-compatible?
The native Volcengine task API is not simply a chat-completions call; it is a video task API. TheRouter can still sit in front of media-generation jobs where implemented, but you should treat video generation as asynchronous rather than expecting a blocking OpenAI chat response.
Which model id should I use on TheRouter?
Use doubao/doubao-seedance-2-0 for standard quality and doubao/doubao-seedance-2-0-fast for faster iteration. The native Ark ids include date-stamped names such as doubao-seedance-2-0-260128.
Can I send images as references?
Yes. TheRouter model metadata lists text and image inputs with video output for both Seedance 2.0 variants, and ByteDance describes Seedance 2.0 as using multimodal references. Test the exact image field shape against your chosen endpoint before building bulk workflows.
How long should polling wait?
Use a product-level timeout rather than a fixed number copied from a blog. Start with 2-5 second intervals, back off toward 30 seconds, and keep the task visible to users if the provider queue is slow.
Should I route every video job through Fast first?
Not every job. Use Fast when the prompt is still uncertain; use standard when a human has approved the storyboard or reference image. That split saves money without hiding quality tradeoffs.