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

By SeedRouter · Published 2026-09-25 · Updated 2026-09-25

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](https://seedrouter.ai/apikeys) page and keep it on your server. Never put it in browser code.
2. **Credits.** Add a balance on the [billing page](https://seedrouter.ai/billing). Credits never expire, and failed tasks are not charged.
3. **A model ID.** Pick one from the table below.

| Model ID                     | Model             | Resolutions   | Clip length  |
| ---------------------------- | ----------------- | ------------- | ------------ |
| `dreamina-seedance-2-0`      | Seedance 2.0      | 480p to 4K    | 4–15 seconds |
| `dreamina-seedance-2-0-fast` | Seedance 2.0 Fast | 480p, 720p    | 4–15 seconds |
| `dreamina-seedance-2-0-mini` | Seedance 2.0 Mini | 480p, 720p    | 4–15 seconds |
| `dreamina-seedance-2-5`      | Seedance 2.5      | 480p to 1080p | 4–30 seconds |

Not sure which one? The [Seedance 2.0 vs Fast vs Mini guide](https://seedrouter.ai/blog/seedance-2-0-vs-fast-vs-mini) and the [Seedance 2.5 vs 2.0 guide](https://seedrouter.ai/blog/seedance-2-5-vs-2-0) compare them.

```bash
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:

```bash
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:

```json
{"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:

```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`:

```bash
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
  }'
```

| Mode                 | What goes in `content`                                                          |
| -------------------- | ------------------------------------------------------------------------------- |
| Text to video        | One text item                                                                   |
| First frame          | Text plus one image with role `first_frame`                                     |
| First and last frame | Text plus one `first_frame` and one `last_frame` image                          |
| References           | Text 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`:

```json
{
  "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](https://seedrouter.ai/blog/seedance-api-pricing) 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:

```text
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](https://seedrouter.ai/apikeys) 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](https://seedrouter.ai/docs/seedance-2-0) and [Seedance 2.5](https://seedrouter.ai/docs/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](https://seedrouter.ai/docs/api/errors) 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](https://seedrouter.ai/models/seedance-2-0#playground). For longer clips and editing, change the model to `dreamina-seedance-2-5` and see the [Seedance 2.5](https://seedrouter.ai/models/seedance-2-5) page.
