> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nunchux.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Authenticate every request with your API key in the `X-API-Key` header or `Authorization: Bearer`. Keys start with `sk-nunchux-`.
> Image generation is synchronous: the image is in the response.
> Video generation is asynchronous: submit the job, poll its task until it reaches a terminal status, then download the output promptly, because output URLs expire.

# Seedance

> ByteDance's Seedance video model for text-to-video and image-to-video with generated audio.

# Seedance

Seedance is ByteDance's video model line. Each version generates a clip from a text prompt or from a starting image, and can score the clip with generated audio. Generation is asynchronous. You submit a task, poll it until the status is terminal, then download the clip. The route mirrors ByteDance's own API, so the request and response shapes are the provider's.

<Note>
  Best for

  * Prompt-driven scenes. A usable clip from a written description, with no shoot and no source footage.
  * Animating a still. A first frame fixes the composition and the prompt drives the motion.
  * Clips with sound. The model generates a track with the picture unless you turn it off.
</Note>

## Models

| Model | Model ID | Tasks | Resolution | Duration |
| - | - | - | - | - |
| Seedance 2.5 | `dreamina-seedance-2-5-260628` | t2v, i2v | 480p, 720p | Up to 15 s |

One model ID serves both tasks. The items in `content[]` select the task. A `text` item alone gives text-to-video. A `text` item plus a `first_frame` image item gives image-to-video.

On image-to-video the output shape follows the first frame. Crop the image to the shape you want before you upload it.

## Endpoints

| Step | Route |
| - | - |
| Submit | `POST /v1/bytedance/contents/generations/tasks` |
| Poll | `GET /v1/bytedance/contents/generations/tasks/{task_id}` |

The poll route is the submit route with the task ID appended.

## Request

Send your API key in the `X-API-Key` header. See [Authentication](/authentication). Set `Content-Type: application/json`. The examples also send a `User-Agent` header that names your application.

<ParamField body="model" type="string" required>
  The model ID: `dreamina-seedance-2-5-260628`.
</ParamField>

<ParamField body="content" type="array" required>
  The prompt and, on image-to-video, the first frame. Put the `text` item first.

  <Expandable title="item properties">
    <ParamField body="type" type="string" required>
      `text` for the prompt. `image_url` for an image.
    </ParamField>

    <ParamField body="text" type="string">
      The prompt. Required on a `text` item. All tasks. Describe the subject, the action and the camera move.
    </ParamField>

    <ParamField body="role" type="string">
      On an `image_url` item. Set `first_frame` for the image the clip starts on. Image-to-video.
    </ParamField>

    <ParamField body="image_url" type="object">
      On an `image_url` item. The image container.

      <Expandable title="properties">
        <ParamField body="url" type="string" required>
          The URL of the image. The provider fetches it, so the URL must be reachable from the internet.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="resolution" type="string" default="720p">
  The output tier: `480p` or `720p`. All tasks. A larger frame uses more video tokens.
</ParamField>

<ParamField body="generate_audio" type="boolean" default="true">
  Send `false` for a silent clip. All tasks. The flag is a billing dimension: a clip with sound and a silent clip are priced differently.
</ParamField>

## Response

### Submit

A 200 status means that the provider accepted the task. It does not mean that the clip is ready.

<ResponseField name="id" type="string" required>
  The task ID. It starts with `cgt-`. Poll `GET /v1/bytedance/contents/generations/tasks/{task_id}` with it.
</ResponseField>

### Poll

<ResponseField name="status" type="string" required>
  `queued` or `running` while the task runs. `succeeded`, `failed`, `cancelled` or `expired` when it ends. Poll until you read one of the four terminal values.
</ResponseField>

<ResponseField name="content.video_url" type="string">
  The URL of the clip. Present only when `status` is `succeeded`. The URL expires. Download the clip as soon as the task succeeds.
</ResponseField>

<ResponseField name="error" type="object">
  The failure detail. Present when the task did not succeed. Read it before you resubmit.
</ResponseField>

<ResponseField name="usage.completion_tokens" type="integer">
  The number of video tokens the clip used. Present when `status` is `succeeded`. Seedance is billed by this count, so the cost is known when the task completes.
</ResponseField>

## Example

Submit, poll, download. The submit and the poll use the same path. The poll appends the task ID.

<CodeGroup>
  ```bash cURL theme={"system"}
  BASE=https://api.nunchux.ai
  TASKS=$BASE/v1/bytedance/contents/generations/tasks

  # 1. Submit
  SUBMIT=$(curl -sS --fail-with-body "$TASKS" \
    -H "X-API-Key: $NUNCHUX_API_KEY" \
    -H "Content-Type: application/json" \
    -H "User-Agent: YourApp/1.0" \
    -d '{
      "model": "dreamina-seedance-2-5-260628",
      "content": [
        { "type": "text", "text": "a fox trotting through a snowy forest at dawn" }
      ],
      "resolution": "720p",
      "generate_audio": false
    }') || { echo "submit failed: $SUBMIT" >&2; exit 1; }
  TASK=$(jq -er '.id' <<<"$SUBMIT") || { echo "no id in: $SUBMIT" >&2; exit 1; }

  # 2. Poll until the status is terminal
  DELAY=5
  for _ in $(seq 1 90); do
    RESP=$(curl -sS "$TASKS/$TASK" \
      -H "X-API-Key: $NUNCHUX_API_KEY" \
      -H "User-Agent: YourApp/1.0")
    STATUS=$(jq -r '.status // ""' <<<"$RESP")
    case "$STATUS" in succeeded|failed|cancelled|expired) break ;; esac
    sleep "$DELAY"; DELAY=$(( DELAY * 2 > 30 ? 30 : DELAY * 2 ))
  done

  # 3. Check for failure
  [ "$STATUS" = "succeeded" ] || { echo "task $STATUS: $(jq -r '.error // "no error"' <<<"$RESP")" >&2; exit 1; }

  # 4. Download
  curl -sSL -o seedance.mp4 "$(jq -r '.content.video_url' <<<"$RESP")"
  ```

  ```python Python theme={"system"}
  # pip install requests
  import os, time, requests

  BASE = "https://api.nunchux.ai"
  TASKS = f"{BASE}/v1/bytedance/contents/generations/tasks"
  HEADERS = {
      "X-API-Key": os.environ["NUNCHUX_API_KEY"],
      "User-Agent": "YourApp/1.0",
  }

  # 1. Submit
  submit = requests.post(
      TASKS,
      headers=HEADERS,
      json={
          "model": "dreamina-seedance-2-5-260628",
          "content": [
              {"type": "text", "text": "a fox trotting through a snowy forest at dawn"}
          ],
          "resolution": "720p",
          "generate_audio": False,
      },
  )
  if not submit.ok:
      raise RuntimeError(f"submit failed: HTTP {submit.status_code} {submit.text}")
  task = submit.json()["id"]

  # 2. Poll until the status is terminal
  delay = 5
  for _ in range(90):
      data = requests.get(f"{TASKS}/{task}", headers=HEADERS).json()
      status = data.get("status", "")
      if status in ("succeeded", "failed", "cancelled", "expired"):
          break
      time.sleep(delay)
      delay = min(delay * 2, 30)
  else:
      raise TimeoutError("Seedance task did not reach a terminal status")

  # 3. Check for failure
  if status != "succeeded":
      raise RuntimeError(f"Seedance task {status}: {data.get('error')}")

  # 4. Download
  with requests.get(data["content"]["video_url"], stream=True, timeout=300) as r:
      r.raise_for_status()
      with open("seedance.mp4", "wb") as f:
          for chunk in r.iter_content(1 << 14):
              f.write(chunk)
  ```
</CodeGroup>

To animate a still, append an item with `type` set to `image_url` and `role` set to `first_frame`, with the image URL under `image_url.url`. The body below replaces the submit body in the example.

```json Image-to-video theme={"system"}
{
  "model": "dreamina-seedance-2-5-260628",
  "content": [
    { "type": "text", "text": "the fox turns and trots toward the camera" },
    {
      "type": "image_url",
      "role": "first_frame",
      "image_url": { "url": "https://example.com/frame.jpg" }
    }
  ],
  "resolution": "720p",
  "generate_audio": false
}
```

## Tips

* Describe motion and camera, not just the scene. A static description gives the model nothing to animate.
* Keep the prompt to one clear action. Busy, multi-event prompts are harder to render cleanly.
* Draft at 480p to settle the wording, then re-run the same prompt at 720p. A smaller frame uses fewer video tokens.
* Decide about audio before you run. The flag changes the price, so a silent draft is the cheaper way to test a prompt.
* Poll every 5 seconds at first, then back off to 30 seconds. Polls are free and never use a concurrency slot.

## Errors and limits

A 200 status on submit means that the provider accepted the task. It does not mean that the task succeeded. A task that fails later ends with `status` set to `failed`, `cancelled` or `expired`, and `error` explains why. Read it before you resubmit.

A failed submit returns an HTTP error status. See [Error codes](/errors).

A 5xx status or a timeout on submit does not tell you whether the task was created. Never resubmit blindly. If the submit returned an `id`, poll it. If it returned nothing, check your credits before you try again.

ByteDance applies these limits to each first or last frame image you attach:

* 300 to 6,000 pixels on each side
* An aspect ratio, width over height, between 0.4 and 2.5
* Under 30 MB per file

Seedance is billed by the number of video tokens the finished clip uses. The charge is known when the task completes, not before it starts. A longer or larger clip uses more tokens, and the audio flag changes the rate. Every task counts toward the simultaneous-jobs cap of your plan. See [Rate limits](/rate-limits), [Credits & pricing](/credits-pricing) and the [Partner models overview](/partner-models/overview).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.