DEV Community

WesLin
WesLin

Posted on

Seedance 2.5 API: The Official Endpoint and 6 Gotchas

Three sites sell access to "the Seedance 2.5 API". Only one of them belongs to ByteDance. Here's the official endpoint, the model ID, and the six things that cost us time.

The official endpoint

ByteDance hosts the official API on BytePlus ModelArk. If you want to know which sites are actually ByteDance, check the domain on the endpoint before you write any code. Everything else selling a "Seedance API" is a reseller sitting in front of this.

You need an authorization bearer token and a JSON body to start a task:

curl -X POST https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ARK_API_KEY" \
  -d '{
    "model": "dreamina-seedance-2-5-260628",
    "content": [
      { "type": "text", "text": "A slow push-in on a red door at the end of a corridor, matching the light in @Image1." },
      { "type": "image_url", "image_url": { "url": "https://example.com/door.png" }, "role": "reference_image" }
    ],
    "generate_audio": true,
    "ratio": "16:9",
    "duration": 15
  }'
Enter fullscreen mode Exit fullscreen mode

The model ID for Seedance 2.5 is dreamina-seedance-2-5-260628. If you pass the older Seedance 2.0 ID instead, you'll need dreamina-seedance-2-0-260128. You can confirm both IDs and the route directly in ByteDance's ModelArk docs.

The request body

The API takes a single JSON payload. Use these exact field names:

Field Type Default What it does
model string required the model id
content object[] required the input list: text, images, videos
omni_reference_task_type string auto task-type hint; marked new in the docs
resolution string output resolution
ratio string aspect ratio
duration integer seconds
frames integer frame count
generate_audio boolean true makes the sound in the same pass
watermark boolean false
output_format string mp4 marked new in the docs
seed integer -1
camera_fixed boolean false
return_last_frame boolean false
draft boolean false
service_tier string default
callback_url string
execution_expires_after integer 172800 seconds, so 48 hours
priority integer 0
safety_identifier string end-user identifier

Three defaults in this schema will surprise you if you don't check them:

  • generate_audio defaults to true — you'll generate sound tracks by default even if you only wanted silent video clips.
  • execution_expires_after defaults to 172800 — the docs call it the task expiration threshold, so that's 48 hours.
  • omni_reference_task_type defaults to auto — the system guesses your reference mode unless you tell it what task you're running.

Gotcha 1: your references are bound inside the prompt string

The content array holds text, reference images, and reference videos. The model takes up to 30 images, 10 video clips, and 10 audio clips in one call.

Instead of passing separate fields for character shots or motion guides, you point to your files directly inside the prompt string using @Image1, @Video1, and @Video2. ByteDance's own example prompt contains: "The strawberry flavor refers to @Image1" and "referring to the composition of @Video1" and "referring to the impact of @Video3".

The number after @Video or @Image counts against the order of items inside content. Nothing in the parameter table says this; the doc's example is the only place it appears. If you reorder items in content, @Video1 silently binds to a completely different clip.

Here's the minimal shape for a text prompt paired with an image reference:

[
  { "type": "text", "text": "A slow push-in on a red door at the end of a corridor, matching the light in @Image1." },
  { "type": "image_url", "image_url": { "url": "https://example.com/door.png" }, "role": "reference_image" }
]
Enter fullscreen mode Exit fullscreen mode

Gotcha 2: the result URL dies in 24 hours

When a job finishes, the API returns a presigned URL (a link that carries its own expiry and signature in the query string) in content.video_url.

Look at the query parameters on that URL and you'll find X-Tos-Expires=86400. That's 86,400 seconds — so the link is dead in 24 hours, and anything you didn't copy is gone. If you save the URL in your database instead of copying the file, every video in your product's library is a dead link the next day, and nothing in the API tells you it happened. We copy every finished file to our own storage for exactly that reason.

Gotcha 3: audio is on unless you turn it off

The generate_audio setting defaults to true. That means the model makes synchronized sound in the same pass as the video frames.

So you'll get generated audio tracks even when your application only asked for background video. If your product adds its own soundtrack or needs silent video, you'll need to pass "generate_audio": false in your request body. If you leave the field unset, it won't be silent.

Gotcha 4: there is no 4K tier on 2.5

Don't build a 4K option into your UI for Seedance 2.5. The official ModelArk rate table lists only a 480p/720p tier and a 1080p tier for dreamina-seedance-2-5-260628.

4K exists on Seedance 2.0 (dreamina-seedance-2-0-260128), but it isn't available on 2.5. Several platform pages advertise 4K for 2.5 anyway. For example, a page titled "Seedance 2.5 API Now Available - 30s 4K AI Video on Kie.ai" mentions 4K in its title, but its own rate card lists only 480P, 720P, and 1080P.

Set your resolution to 480p, 720p, or 1080p. We haven't tested what a 4K request does on 2.5 — there's no tier to bill it against, so don't find out in production.

Gotcha 5: it is async, and the only thing you get back is an id

Task creation is strictly asynchronous. The API won't keep an HTTP connection open while the video finishes.

When you send a creation request, the only thing you get back is a task ID:

{ "id": "cgt-2026******-****" }
Enter fullscreen mode Exit fullscreen mode

You have to poll the task endpoint to check the status:

curl -X GET "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks?page_size=3&filter.status=succeeded" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ARK_API_KEY"
Enter fullscreen mode Exit fullscreen mode

When a task completes, the response gives you the full state:

{
  "id": "cgt-2026******-****",
  "model": "dreamina-seedance-2-5-260628",
  "status": "succeeded",
  "content": { "video_url": "https://ark-content-generation-ap-southeast-1.tos-ap-southeast-1.volces.com/...?X-Tos-Expires=86400&X-Tos-Signature=***" },
  "usage": { "completion_tokens": 108900, "total_tokens": 108900 },
  "resolution": "720p",
  "ratio": "16:9",
  "duration": 5,
  "framespersecond": 24
}
Enter fullscreen mode Exit fullscreen mode

A finished task object carries several fields, but these are the ones that matter most for your app:

  • status — tells you if the job succeeded, failed, or is still running.
  • content.video_url — the temporary storage link to the generated MP4 file.
  • usage.completion_tokens — the exact token count you're billed on.

Billing runs per million tokens, and usage.completion_tokens is what ByteDance charges you for.

Gotcha 6: first-and-last-frame is a documented mode

The create-task documentation includes tabs for seven distinct modes:

  • multimodal reference (takes text, images, video and audio together)
  • edit video
  • extend video
  • audio video first frame
  • audio video first and last frames
  • image to video from base64
  • text to video

Worth knowing, because a wrapper only exposes the modes its authors wired up. If you need a clean transition between two states, first-and-last-frame is documented right there in ByteDance's own endpoint tabs — check whether the API you picked passes it through.

If you would rather not write the integration

If you want to run Seedance 2.5 in the browser without managing task queues, storage copies, and polling workers, you can use Seadanse. It takes reference images and reference clips for 5, 10, 15, 20, 25, or 30-second clips at 480p, 720p, or 1080p. It doesn't support reference audio, it has no video extension mode, and it caps at 1080p and 30 seconds. You can check what a clip costs directly on our pricing page.

Where these facts came from

Every parameter, endpoint path, and model name here comes from ByteDance's official documentation:

Top comments (0)