Seedance 2 API
Generate Seedance 2 videos from your own code. Three endpoints cover text-to-video, image-to-video (with an optional last frame) and reference-to-video, which takes reference images, videos and audio in one request. Clips run 4 to 15 seconds from 480p to 4K, with native audio on by default. Seedance 2 is sold by several providers at different prices; each request is routed to the cheapest one that can serve it.
50% less than the priciest provider (7 compared). Same model, same output.
Quickstart
Async by design: submit a generation, get a run id back instantly, poll until it completes (or pass a callbackUrl). Each mode is its own endpoint.
Seedance 2 Text to Video API
1 — Start a generation
curl -X POST https://app.scenetra.com/api/v1/generate/seedance-2-t2v \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"Handheld follow shot of a street food vendor flipping noodles in a wok at night, steam and sparks, neon signs behind, sizzling and crowd chatter","duration":"5","resolution":"720p"}'Response (202)
{
"runId": "run_abc123",
"status": "PENDING",
"model": "seedance-2-t2v",
"estimatedCredits": 763,
"statusUrl": "/api/v1/runs/run_abc123"
}2 — Poll until COMPLETED (every 2-5 seconds)
curl https://app.scenetra.com/api/v1/runs/run_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"runId": "run_abc123",
"status": "COMPLETED",
"progress": { "completed": 1, "total": 1 },
"outputs": [
{ "type": "video", "url": "https://images.scenetra.com/..." }
],
"error": null,
"estimatedCredits": 763
}Request fields
| Field | Type | Description | Default |
|---|---|---|---|
| prompt* | string | Describe the video: subject, action, camera work, and any dialogue or sound direction. | — |
| duration | string | Duration of the video in seconds (4-15). Billed per second.4 · 5 · 6 · 7 · 8 · 9 · 10 · 11 · 12 · 13 · 14 · 15 | 5 |
| resolution | string | Video resolution. Higher resolutions cost more per second.480p · 720p · 1080p · 4k | 720p |
| aspect_ratio | string | Aspect ratio of the generated video. 'adaptive' follows the prompt or the primary media.adaptive · 21:9 · 16:9 · 4:3 · 1:1 · 3:4 · 9:16 | adaptive |
| generate_audio | string | Synchronized audio: voice, sound effects and music generated in the same pass. Some sellers cannot switch audio off, so turning it off can change the winning price.false · true | true |
| subject_content | string | What the video contains. Sellers differ in what they allow: 'general' (no faces) can unlock lower prices; 'mature' routes only to sellers without content restrictions.general · people · mature | people |
| callbackUrl | string (https URL) | Optional. When the run finishes (completed or failed), we POST the final run status to this URL — same shape as the poll response, plus model, params, and chargedCredits. Best-effort; polling remains the source of truth. | |
Unknown fields are rejected with a helpful 400. Media fields take https URLs. There is no provider parameter — every run is routed to the cheapest capable provider automatically.
Seedance 2 Image to Video API
1 — Start a generation
curl -X POST https://app.scenetra.com/api/v1/generate/seedance-2-i2v \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"Slow push-in, the subject turns to camera and smiles, soft wind in the hair","image":"https://example.com/first-frame.jpg","duration":"5"}'Response (202)
{
"runId": "run_abc123",
"status": "PENDING",
"model": "seedance-2-i2v",
"estimatedCredits": 900,
"statusUrl": "/api/v1/runs/run_abc123"
}2 — Poll until COMPLETED (every 2-5 seconds)
curl https://app.scenetra.com/api/v1/runs/run_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"runId": "run_abc123",
"status": "COMPLETED",
"progress": { "completed": 1, "total": 1 },
"outputs": [
{ "type": "video", "url": "https://images.scenetra.com/..." }
],
"error": null,
"estimatedCredits": 900
}Request fields
| Field | Type | Description | Default |
|---|---|---|---|
| prompt | string | Optional. Describe the desired motion and camera work; the look comes from the first frame. | — |
| image* | string (https URL) | First-frame image. The video starts from this image. | — |
| last_image | string (https URL) | Optional last-frame image. The video transitions from the first frame to this one. | — |
| duration | string | Duration of the video in seconds (4-15). Billed per second.4 · 5 · 6 · 7 · 8 · 9 · 10 · 11 · 12 · 13 · 14 · 15 | 5 |
| resolution | string | Video resolution. Higher resolutions cost more per second.480p · 720p · 1080p · 4k | 720p |
| aspect_ratio | string | Aspect ratio of the generated video. 'adaptive' follows the prompt or the primary media.adaptive · 21:9 · 16:9 · 4:3 · 1:1 · 3:4 · 9:16 | adaptive |
| generate_audio | string | Synchronized audio: voice, sound effects and music generated in the same pass. Some sellers cannot switch audio off, so turning it off can change the winning price.false · true | true |
| subject_content | string | What the video contains. Sellers differ in what they allow: 'general' (no faces) can unlock lower prices; 'mature' routes only to sellers without content restrictions.general · people · mature | people |
| callbackUrl | string (https URL) | Optional. When the run finishes (completed or failed), we POST the final run status to this URL — same shape as the poll response, plus model, params, and chargedCredits. Best-effort; polling remains the source of truth. | |
Unknown fields are rejected with a helpful 400. Media fields take https URLs. There is no provider parameter — every run is routed to the cheapest capable provider automatically.
Seedance 2 Reference to Video API
1 — Start a generation
curl -X POST https://app.scenetra.com/api/v1/generate/seedance-2-ref2v \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"@Image1 walks through a sunlit market holding @Image2, handheld follow shot, crowd murmur","reference_images":["https://example.com/person.jpg","https://example.com/product.jpg"],"duration":"5"}'Response (202)
{
"runId": "run_abc123",
"status": "PENDING",
"model": "seedance-2-ref2v",
"estimatedCredits": 900,
"statusUrl": "/api/v1/runs/run_abc123"
}2 — Poll until COMPLETED (every 2-5 seconds)
curl https://app.scenetra.com/api/v1/runs/run_abc123 \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"runId": "run_abc123",
"status": "COMPLETED",
"progress": { "completed": 1, "total": 1 },
"outputs": [
{ "type": "video", "url": "https://images.scenetra.com/..." }
],
"error": null,
"estimatedCredits": 900
}Request fields
| Field | Type | Description | Default |
|---|---|---|---|
| prompt* | string | Cite reference inputs in order with @-syntax: @Image1, @Video1, @Audio1. | — |
| reference_images | string[] (https URLs) | Up to 9 reference images for character, style or scene. Cite in the prompt as @Image1 and so on. | — |
| reference_videos | string[] (https URLs) | Up to 3 reference videos (mp4/mov), total duration up to 15s. Reference video seconds are billed as input. | — |
| reference_audios | string[] (https URLs) | Up to 3 reference audio files (wav/mp3). Requires at least one reference image or video. | — |
| duration | string | Duration of the video in seconds (4-15). Billed per second.4 · 5 · 6 · 7 · 8 · 9 · 10 · 11 · 12 · 13 · 14 · 15 | 5 |
| resolution | string | Video resolution. Higher resolutions cost more per second.480p · 720p · 1080p · 4k | 720p |
| aspect_ratio | string | Aspect ratio of the generated video. 'adaptive' follows the prompt or the primary media.adaptive · 21:9 · 16:9 · 4:3 · 1:1 · 3:4 · 9:16 | adaptive |
| generate_audio | string | Synchronized audio: voice, sound effects and music generated in the same pass. Some sellers cannot switch audio off, so turning it off can change the winning price.false · true | true |
| subject_content | string | What the video contains. Sellers differ in what they allow: 'general' (no faces) can unlock lower prices; 'mature' routes only to sellers without content restrictions.general · people · mature | people |
| callbackUrl | string (https URL) | Optional. When the run finishes (completed or failed), we POST the final run status to this URL — same shape as the poll response, plus model, params, and chargedCredits. Best-effort; polling remains the source of truth. | |
Unknown fields are rejected with a helpful 400. Media fields take https URLs. There is no provider parameter — every run is routed to the cheapest capable provider automatically.
Good to know
Billing
Runs bill your account credits at provider cost with 0% markup. The submit response includes the credit estimate; failed generations are refunded automatically. Add ?dryRun=1 to get the estimate without running anything.
Errors
Errors are always { "error": { "code", "message" } } with stable codes: unauthorized, model_not_available, invalid_parameter, insufficient_credits, rate_limited. A failed run is not an HTTP error — poll responses report status: "FAILED" with the reason.
Seedance 2 API FAQ
What does the subject_content field do?+
It tells the router what the video contains: general (no faces), people (the default) or mature. Providers differ in what they accept, so general can unlock cheaper providers, and mature routes only to providers without content restrictions. It never changes the prompt or the output.
Does ByteDance offer a public Seedance 2 API?+
ByteDance sells Seedance through its own cloud platforms (BytePlus, Volcengine), and several providers resell it. Scenetra prices your request across the providers we work with and runs it on the cheapest, so you don't need an account with each.
How much does the Seedance 2 API cost?+
Billed per second of output, in credits from your Scenetra balance at provider cost with no markup. With default settings (720p, 5 seconds), a text to video run is estimated at about 763 credits. The submit response returns the estimate for your exact settings, and adding ?dryRun=1 prices a request without running it.
Which provider runs my request?+
The cheapest one that supports your settings, chosen per request. There is no provider parameter: the same Seedance 2 request is priced across every provider we route to and runs on the lowest quote.
Do failed generations cost credits?+
No. Credits are reserved when you submit and refunded automatically if the run fails. A failed run is not an HTTP error: polling returns status FAILED with the reason.
Do I have to poll, or can I get a webhook?+
Both work. Pass callbackUrl and we POST the final run status to it when the run completes or fails. Delivery is best-effort, so polling GET /api/v1/runs/{runId} remains the source of truth.