Claude Opus 5.5 is live on SeedRouter

How to use the Seedance API: key, request, polling and references

Use the Seedance API step by step: create a key, send a video task, poll it for the video URL, add image, video and audio references, and hand it to an agent.

Read as Markdown

To use the Seedance API, create an API key, send the official ModelArk video task body to one endpoint, and poll the task it returns until the video URL is ready. The same steps work for Seedance 2.0, Seedance 2.0 Fast, Seedance 2.0 Mini and Seedance 2.5; only the model value and a few model-specific limits change.

This guide walks through each step with working code, then shows how to add references, edit a clip with Seedance 2.5, and hand the job to a coding agent.

What do you need before the first request?

  1. An API key. Create one on the API keys page and keep it on your server. Never put it in browser code.
  2. Credits. Add a balance on the billing page. Credits never expire, and failed tasks are not charged.
  3. A model ID. Pick one from the table below.
Model IDModelResolutionsClip length
dreamina-seedance-2-0Seedance 2.0480p to 4K4–15 seconds
dreamina-seedance-2-0-fastSeedance 2.0 Fast480p, 720p4–15 seconds
dreamina-seedance-2-0-miniSeedance 2.0 Mini480p, 720p4–15 seconds
dreamina-seedance-2-5Seedance 2.5480p to 1080p4–30 seconds

Not sure which one? The Seedance 2.0 vs Fast vs Mini guide and the Seedance 2.5 vs 2.0 guide compare them.

export SEEDROUTER_API_KEY="your-key"

How do you send a Seedance request?

POST the task to /v1/contents/generations/tasks. The body is the official ModelArk "create a video generation task" request:

curl https://api.seedrouter.ai/v1/contents/generations/tasks \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dreamina-seedance-2-0",
    "content": [{"type": "text", "text": "A red paper boat drifts across a calm pond at sunrise, slow dolly-in"}],
    "resolution": "720p",
    "ratio": "16:9",
    "duration": 5,
    "generate_audio": true
  }'

The response is a task ID, not a video:

{"id": "task_..."}

If you already call ModelArk, change only the base URL to https://api.seedrouter.ai/v1 and the API key. Unknown fields are rejected before anything is charged, and so is a setting a model does not support, such as 1080p on Fast or Mini.

How do you get the video?

Poll the task every 10 to 20 seconds until status is succeeded, failed or expired. A 5-second 720p clip usually takes two to three minutes. In Python:

import os
import time
import requests

API = "https://api.seedrouter.ai/v1"
headers = {"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}"}

response = requests.post(
    f"{API}/contents/generations/tasks",
    headers=headers,
    json={
        "model": "dreamina-seedance-2-0",
        "content": [{"type": "text", "text": "A red paper boat drifts across a calm pond at sunrise, slow dolly-in"}],
        "resolution": "720p",
        "ratio": "16:9",
        "duration": 5,
    },
    timeout=60,
)
response.raise_for_status()
task_id = response.json()["id"]

deadline = time.monotonic() + 1800
while time.monotonic() < deadline:
    result = requests.get(f"{API}/contents/generations/tasks/{task_id}", headers=headers, timeout=30)
    result.raise_for_status()
    task = result.json()
    if task["status"] == "succeeded":
        print(task["content"]["video_url"])
        break
    if task["status"] in ("failed", "expired"):
        raise RuntimeError(task["error"]["message"])
    time.sleep(15)
else:
    raise TimeoutError(f"Still waiting. Resume polling task {task_id}.")

A succeeded task has the video in content.video_url, the billed video tokens in usage.completion_tokens, and the settings that were actually rendered, including the seed the model picked. The video is hosted on our storage; download it to your own if you need it long term.

A timeout while polling does not mean the video failed. Keep the task ID and check it again; submitting a new task means paying for a second video. There is no callback URL, so polling is the way to get the result, and a submitted task cannot be cancelled.

How do you add images, videos and audio?

Add items to content, each with a public URL and a role:

curl https://api.seedrouter.ai/v1/contents/generations/tasks \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dreamina-seedance-2-0",
    "content": [
      {"type": "text", "text": "The character from the image walks through the market in the video, same camera move"},
      {"type": "image_url", "image_url": {"url": "https://example.com/character.png"}, "role": "reference_image"},
      {"type": "video_url", "video_url": {"url": "https://example.com/market.mp4"}, "role": "reference_video"}
    ],
    "ratio": "adaptive",
    "duration": 8
  }'
ModeWhat goes in content
Text to videoOne text item
First frameText plus one image with role first_frame
First and last frameText plus one first_frame and one last_frame image
ReferencesText plus any mix of reference_image, reference_video and reference_audio

Seedance 2.0 and its Fast and Mini versions take up to 9 reference images, 3 videos and 3 audio tracks; Seedance 2.5 takes up to 30, 10 and 10. Media must be URLs: base64 and file uploads are not accepted. Reference images and videos with real human faces are not supported by the model. Media is checked when the task starts, and a file that breaks a limit fails the task before any generation, without a charge.

How do you edit or extend a clip with Seedance 2.5?

Send the clip as a reference_video and set omni_reference_task_type:

{
  "model": "dreamina-seedance-2-5",
  "content": [
    {"type": "text", "text": "Change the jacket to red. Keep everything else the same."},
    {"type": "video_url", "video_url": {"url": "https://example.com/clip.mp4"}, "role": "reference_video"}
  ],
  "omni_reference_task_type": "edit"
}

Use edit to change what is in the footage and extend to continue it past its last frame. For edit, leave duration at its default of -1; for both, leave ratio as adaptive. The input seconds are billed at the reference rate, as the pricing guide explains.

How do you let a coding agent use the Seedance API?

A coding agent such as Claude Code, Codex or Cursor can call the API with a shell command or a short script. SeedRouter does not ship an MCP server, a packaged skill or a ComfyUI node; this prompt is the whole integration. Export the key first, then paste:

Use the SeedRouter API to generate a Seedance video for me.

Security: read SEEDROUTER_API_KEY from my local environment. Never ask me to paste it and never print it.

Goal: [subject, action, camera move, lighting, what the clip is for]
Model: [dreamina-seedance-2-0 | dreamina-seedance-2-0-fast | dreamina-seedance-2-0-mini | dreamina-seedance-2-5]
Resolution: [480p | 720p | 1080p | 4k]    Ratio: [16:9 | 9:16 | 1:1 | adaptive]    Duration: [seconds]
References: [public image, video or audio URLs with their roles, or none]

Send POST https://api.seedrouter.ai/v1/contents/generations/tasks with
{"model": "...",
 "content": [{"type": "text", "text": "..."}],
 "resolution": "...", "ratio": "...", "duration": 5}
Media goes in content as image_url, video_url or audio_url items with a role,
never base64. Do not add fields that are not in the API reference.

Before sending, show me the request body and wait for my approval: each
task is charged. Then poll GET https://api.seedrouter.ai/v1/contents/generations/tasks/{id}
every 15 seconds until status is succeeded, failed or expired. If polling
times out, keep checking the same task; never resubmit. Save
content.video_url into ./videos/ and tell me the file path.

The approval step matters: the agent spends your balance, so it should never submit on its own.

Frequently asked questions

How do I get a Seedance API key?

Sign in, open the API keys page and create a key. The same key works for every Seedance model and for the other models on SeedRouter.

Where is the Seedance API documentation?

The Seedance 2.0 and Seedance 2.5 API references list every field, limit and error, with examples in cURL, Python, Node.js and Go, plus an OpenAPI file and a copyable Markdown version.

Can I generate several videos at once?

Send one task per video and poll the tasks in parallel. Each task returns one video and is billed on its own. To list recent tasks, call GET /v1/contents/generations/tasks with page_num, page_size and filters such as filter.status.

What errors should I handle?

A 400 means the body broke a rule, such as an unknown field or an unsupported resolution, and nothing is charged. A task that ends failed or expired carries an error code and message and is not charged either. The error guide lists every code and when to retry.

Send your first request

Create a key, add a small balance, and run the Python example above, or try the same request with no code in the Seedance 2.0 playground. For longer clips and editing, change the model to dreamina-seedance-2-5 and see the Seedance 2.5 page.

Related guides