The Seedance API is the Volcengine Ark content-generation API, and five facts cover most of it. Tasks are created with POST https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks. The model id is doubao-seedance-2-5-260628, and the generation comparison explains when to pick it over 2.0. Authentication is Authorization: Bearer $ARK_API_KEY. The call is asynchronous, so you create a task and then poll it. And the result URL stays valid for 24 hours. The browser route is a separate product, covered in the how-to guide.
The endpoint, in one line
Two calls make up the whole integration. Creating a task is POST https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks, and reading one back is GET https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks/{id}. The path segment /api/v3/ is the API version and has nothing to do with the model generation, which is why a request to /v2/... cannot succeed no matter which model you name. The API overview maps these against the rest of the platform.
Endpoints that do not exist
Search for this endpoint and most of the top results hand you a path the vendor does not document. One reseller opens with curl -X POST https://api.seedance.com/v2/generate, plus a motion_score field that appears nowhere in Ark. Another publishes POST /api/open/v1/video/generations under its own domain, a third documents /v2/generate beside GET /v2/status, and a fourth lists /api/v1/generate/text-to-video.
Ark publishes no v1 or v2 API scheme. Each of those paths belongs to a service that proxies the real one, and the field names give it away: official requests use content, ratio and duration, while the resold shapes use prompt, aspect_ratio and motion_score.
Authentication and the two base URLs
Every official call carries -H "Authorization: Bearer $ARK_API_KEY" and -H "Content-Type: application/json". The key is long-lived, so it belongs in a secret store rather than a client bundle.
| Base URL | Use |
|---|---|
https://ark.cn-beijing.volces.com/api/v3 | Standard inference |
https://ark.cn-beijing.volces.com/api/plan/v3 | Agent Plan enterprise only |
Use the enterprise key and base URL together on the second row; mixing them can 调用失败或产生额外费用, meaning the call fails or bills extra.
Creating a task: the request fields
The minimal request
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-5-260628",
"content": [
{ "type": "text", "text": "A 30-second sequence in three shots: [0-10s] a workshop at dawn, [10-20s] hands assembling a clock movement, [20-30s] the finished clock on a windowsill." },
{ "type": "image_url",
"image_url": { "url": "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/seedance2.5_30s_input.png" },
"role": "reference_image" }
],
"generate_audio": true,
"ratio": "16:9",
"duration": 30
}'

Three field groups carry the request. model names the model. content is an array in which every entry declares a type, and media entries also a role. The generation parameters sit at the top level, here generate_audio, ratio and duration.
Roles are first_frame, last_frame, reference_image, reference_video and reference_audio. Output runs 4 to 30 seconds at 480p, 720p or 1080p, in mp4 or mov, and ratio accepts 21:9, 16:9, 4:3, 1:1, 3:4, 9:16 and adaptive.
One caution. The create-task reference page lists fields the tutorial never shows, including resolution, seed, watermark and callback_url, and that page could not be read in full for this review. Everything above has a documented value inside an official example.
Driving it from Python
Ark ships an official Python SDK under the package name volcenginesdkarkruntime, and the video models share one call shape.
import os
from volcenginesdkarkruntime import Ark
client = Ark(api_key=os.environ["ARK_API_KEY"])
task = client.content_generation.tasks.create(
model="doubao-seedance-2-5-260628",
content=[
{
"type": "text",
"text": "A workshop at dawn, hands assembling a clock movement.",
},
{
"type": "image_url",
"image_url": {
"url": "https://arkdocs.tos-cn-beijing.volces.com/images/video-generation/seedance2.5_30s_input.png"
},
"role": "reference_image",
},
],
generate_audio=True,
ratio="16:9",
duration=30,
)
print(task.id)
result = client.content_generation.tasks.get(task_id=task.id)
print(result.status)
The create call returns a task id; the get call returns the status and, on success, the hosted video URL.
Polling and the status values
TASK_ID="cgt-2026****-****"
while :; do
payload=$(curl -s -X GET \
"https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks/${TASK_ID}" \
-H "Authorization: Bearer $ARK_API_KEY")
status=$(printf '%s' "$payload" | jq -r .status)
[ "$status" = "queued" ] || [ "$status" = "running" ] || break
sleep 10
done
if [ "$status" = "succeeded" ]; then
curl -sL -o "seedance-${TASK_ID}.mp4" \
"$(printf '%s' "$payload" | jq -r .content.video_url)"
fi
The status values
status takes six values: queued, running, cancelled, succeeded, failed and expired. Only a queued task can be cancelled, and a cancelled record disappears after 24 hours.
Three limits shape the loop. Only tasks from the last 7 days can be queried, so an older id is gone. A result URL is valid for 24 hours. And a Seedance 2.5 URL accepts at most 100 downloads, which is the vendor telling you to copy the file into your own storage rather than hand the Ark link to users.
Four task types then constrain the parameters.
| Task | Trigger | Extra rule |
|---|---|---|
| Text to video | Text only | None |
| First or last frame | first_frame or last_frame role | ratio must be adaptive |
| Reference to video | A reference_image, reference_video or reference_audio entry | None |
| Video edit | A reference_video plus an edit intent | ratio adaptive, duration -1 |
| Video extend | A reference_video plus an extend intent | ratio must be adaptive |
A video edit also requires the reference video to run 4 to 30 seconds, and setting omni_reference_task_type declares the intended task type so a mismatch surfaces before generation instead of after it.
What the vendor has not published
Not published as of this review: latency, queue depth and success-rate guarantees; any per-second price, since Ark bills on tokens and the price breakdown is where the formula lives; the create-task page’s per-field types and defaults, because that page could not be read in full; and any free quota for this model. Rate limits are published, at 600 requests per minute for enterprise accounts against 180 for individuals.
Frequently asked questions
Is the Seedance API official? Yes. It is documented on the Volcengine domain, authenticated with an Ark API key, and billed on the Ark pricing page.
Why does my request fail on ratio? First-frame, video-edit and video-extend tasks all require ratio to be adaptive, and a video edit also needs duration set to -1.
How long do I have to fetch the video? 24 hours, with at most 100 downloads on a 2.5 result URL. Tasks stay queryable for 7 days, and a callback URL can replace the polling loop.
Does the same model id work on both base URLs? No. The Agent Plan enterprise base URL needs its own key and its own supported models, and mixing them can fail or bill extra.
Check every field against the official pages before shipping.