Skip to navigation

Seedance 2.5

Generate 4–30 second videos at 480p, 720p or 1080p from text, a first and last frame, or up to 30 images, 10 videos and 10 audio clips as references; edit or extend a video.

  • Asynchronous: the create call returns a task ID; the video arrives when the task succeeds (usually a few minutes).
  • Four ways in: text only, a first frame, a first and last frame, or reference images, videos and audio in any mix (audio alone works too).
  • task_type says whether reference videos are material for a new video, a video to edit, or a video to extend, so the request is checked before you pay.
  • Sound is generated by default at no extra cost; MP4 by default, MOV on request.
  • Billed by the size and length of the video, plus the length of any reference videos. A failed task costs nothing.
POST/v1/videos/tasksTry it

Opens this model in the API Explorer. Enter your BeatAPI API key to create a task: the call is real and is billed to your own balance.

Model IDs

Four Seedance models share this endpoint. The values below come straight from the gateway contract; only Seedance 2.5 accepts task_type, output_format and seed.

Model IDduration (s)resolutionMax reference imagesMax reference videosMax reference audioChoose it when
seedance-2.54–30480p, 720p, 1080p301010You need clips up to 30 seconds, large reference sets, editing or extending a video, or MOV output.
seedance-24–15480p, 720p, 1080p, 4k933You need 4K output, or a lower price than 2.5 at the same resolution.
seedance-2-fast4–15480p, 720p933You want a lower price at 480p or 720p and keep generate_audio.
seedance-2-mini4–15480p, 720p933Price matters most; 480p or 720p, no generate_audio field.

Endpoint and authentication

POST https://api.beatapi.io/v1/videos/tasks

Authorization string Required

Your BeatAPI API key, sent as Bearer <BEATAPI_API_KEY>. Create keys in the Dashboard. Keep keys on your server; never ship them in a browser or mobile app.

Send the body as JSON with Content-Type: application/json. Idempotency-Key is optional: send a unique value (at most 255 characters) per logical request and reuse it only to retry that exact body. Within 24 hours a retry with the same key and body returns the first response again with Idempotent-Replayed: true; the same key with a different body returns 409 idempotency_conflict. Responses other than 2xx are not stored, so a retry after a 400 or 402 runs again.

How a request works

1

Create the task

POST the parameters below to the endpoint. A 201 means the task was accepted and its price reserved from your balance; the work runs in the background. Save data.id.

2

Wait for it to finish

Call GET /v1/tasks/{task_id} and wait data.poll_after_seconds between calls (5 s for images, 8 s for videos) until status is succeeded or failed. Or register a webhook for task.succeeded and task.failed; keep polling as the fallback, because a task stopped by the processing timeout sends no event.

3

Save the result

On succeeded, download every data.output.media[].url and store the files you need; BeatAPI does not promise how long result URLs stay available. On failed, read data.error_code and data.error_message: the reserved amount was returned to your balance, and data.retryable says whether sending the same request again can succeed.

Input modes

ModeRequired inputsNotes
Text to videomodel, promptSend no media arrays.
First framemodel, prompt, images (1 link)The video starts from the image and takes its aspect ratio.
First and last framemodel, prompt, images (2 links)images[0] is the first frame, images[1] the last.
Referencesmodel, prompt, at least one of reference_images, reference_videos, reference_audiosAny mix, including audio only. Cannot be combined with images. Use task_type to edit or extend a reference video.

Request parameters

model string Required

The model to run.

Value: seedance-2.5

If the value is wrong

  • Missing: "model" is required
  • An image model sent to this endpoint: "model" nano-banana-2 is served by POST /v1/images/tasks, not this endpoint

prompt string Required

What happens in the video: subject, action, camera movement, style and sound. With references, say what each input is for.

Length: 1–5000 characters

  • Length is counted in characters (a CJK character counts as one).
  • Refer to inputs by their position, for example “the first reference image” or “the second reference video”.
  • When you make a new video from reference videos, avoid words such as “replace”, “remove” or “extend”, or the model may read the request as an edit; send task_type: "reference" to be sure. For edit, say what to change and what to keep. For extend, describe what happens next.

If the value is wrong

  • Missing: "prompt" is required
  • Empty or longer than the limit: "prompt" has an unsupported length

images string[] Optional

A first frame, or a first and a last frame.

Items: 1–2
Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • One link: the video starts from this image. Two links: images[0] is the first frame and images[1] the last.
  • The video takes the aspect ratio of the first image; aspect_ratio is not applied.
  • For more pictures, or pictures that guide the video without being frames, use reference_images instead.

If the value is wrong

  • More than two links: "images" accepts at most 2 items
  • Combined with any reference_* field: Cannot combine "images" with reference inputs in one task
  • Not an https:// link: "images[0]" must be a public HTTPS URL

reference_images string[] Optional

Pictures that guide the content, characters, products or style of the video.

Items: 1–30
Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • Images are used in list order; refer to them in the prompt by position.

If the value is wrong

  • More than the maximum: "reference_images" accepts at most 30 items
  • Combined with images: Cannot combine "images" with reference inputs in one task

reference_videos string[] Optional

Videos to take motion, camera work or content from, or the video to edit or extend (see task_type).

Items: 1–10
Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • Each link must return an MP4 or MOV file whose host allows byte-range requests: the gateway reads the length of every clip before creating the task, because reference seconds are billed.
  • Required for task_type edit and extend.

Reference videos add to the price for every second they run (see Billing). Trim them to the part you need.

If the value is wrong

  • More than the maximum: "reference_videos" accepts at most 10 items
  • The clip cannot be read: A reference video could not be read: reference_videos[0]: its host does not allow byte-range requests. Send an MP4 or MOV file at a public HTTPS URL whose host allows byte-range requests.

reference_audios string[] Optional

Music, voice or sound to follow. Audio alone, without any image or video reference, is accepted.

Items: 1–10
Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • WAV and MP3 clips are measured against the limits below; other formats are passed to the model unmeasured.

If the value is wrong

  • More than the maximum: "reference_audios" accepts at most 10 items

duration integer OptionalDefault: 5

Length of the video in seconds, a whole number.

Default: 5
Range: 4–30

  • If you leave it out, 5 is sent — also with task_type auto and reference.
  • With task_type: "extend", always send it: it is the length of the finished video including the source. To add 5 seconds to a 5-second clip, send 10; leaving it out asks for 5 seconds in total.
  • With task_type: "edit", leave it out: the result keeps the source video’s length.

If the value is wrong

  • Outside the range or not a whole number: "duration" is outside its supported range
  • Sent with task_type: "edit": task_type "edit" keeps the reference video's length: leave "duration" out

aspect_ratio string OptionalDefault: adaptive

Shape of the video as width:height. adaptive lets the model choose from the inputs.

Allowed values: adaptive, 21:9, 16:9, 4:3, 1:1, 3:4, 9:16
Default: adaptive

  • Ignored when images carries a first frame: the video takes the frame’s aspect ratio.
  • With task_type edit or extend, leave it out or send adaptive: the result keeps the source video’s shape.
  • With adaptive (or frames) the reservation assumes the largest frame of the chosen resolution, so it can be slightly higher than with a fixed ratio.

If the value is wrong

  • A value not in the list: "aspect_ratio" must be one of: [adaptive 21:9 16:9 4:3 1:1 3:4 9:16]
  • A fixed ratio with edit or extend: task_type "edit" keeps the reference video's aspect ratio: leave "aspect_ratio" out or send "adaptive"

resolution string OptionalDefault: 720p

Output resolution. Higher resolution costs more per second.

Allowed values: 480p, 720p, 1080p
Default: 720p

  • Lower case only. 4K is not available on Seedance 2.5 (use seedance-2).

If the value is wrong

  • A value not in the list (for example 4k or 720P): "resolution" must be one of: [480p 720p 1080p]

generate_audio boolean OptionalDefault: true

Whether the video has a generated soundtrack. The price is the same either way.

Default: true

If the value is wrong

  • Not true or false: "generate_audio" must be a boolean

seed integer Optional

A fixed number makes results easier to repeat; leave it out or send -1 for a random seed.

Range: -1–4294967295

  • The same seed with the same request gives similar, not guaranteed identical, results.

If the value is wrong

  • Outside the range: "seed" is outside its supported range

task_type string Optional

What to do with reference_videos: make a new video from them (reference), edit one (edit), or extend one (extend). auto (or leaving it out) lets the model decide from the prompt.

Allowed values: auto, reference, edit, extend

  • Naming the type lets the gateway check the request before anything is charged; see Task types below for the rules of each.
  • With auto or reference a duration is always sent (5 if you leave it out), so a prompt the model reads as an edit fails after submission (refunded) or is re-run as an edit billed at the source video’s length. Send edit when you mean an edit.

If the value is wrong

  • A value not in the list: "task_type" must be one of: [auto reference edit extend]
  • edit or extend without a reference video: task_type "edit" needs a video in "reference_videos"
  • reference without any reference input: task_type "reference" needs reference inputs

output_format string Optional

Container of the result: mp4 (used when you leave it out) or mov. The price is the same.

Allowed values: mp4, mov

  • mov suits further editing. It is not always available; when it is not, the request is refused before anything is charged with a sentence naming the formats you can use now.

If the value is wrong

  • A value not in the list: "output_format" must be one of: [mp4 mov]

The gateway also checks these combinations before creating the task:

  • images cannot be combined with reference inputs

Input media limits

The gateway reads every input before the task is created and refuses one outside these limits with a 400 bad_request that names the input. Nothing is charged.

MediaLimits checked before the task is created
Imageswidth and height 300–6000 px; aspect ratio (width ÷ height) 0.4–2.5; at most 30 MB each
Videoseach 2–30 s; 30 s in total; width and height 300–6000 px; aspect ratio (width ÷ height) 0.4–2.5; 407,696–8,295,044 pixels per frame (width × height); 24–60 FPS; at most 200 MB each
Audioeach 2–30 s; 30 s in total; at most 15 MB each
  • Reference videos must be MP4 or MOV, at a public HTTPS link whose host answers byte-range requests. A clip whose length cannot be read is always refused, because its seconds are billed.
  • Image size is checked when the host reports it. Use JPEG, PNG or WebP; a file the model cannot use fails the task after submission with bad_request, and the task is refunded.
  • Limits are reported in the order length, sides, aspect ratio, pixels, frame rate and size. The message names the input by list and position, counting from 0 like the field errors: reference_videos[0] is 1.5 seconds long; this model takes reference video of 2 to 30 seconds.
  • Lengths are measured with a 0.1-second tolerance. Sizes are checked only when the host reports them.
  • Image and audio links are refused at create only when the host answers with a 4xx error or returns an empty file, for example images[1] could not be downloaded: the URL returned HTTP 404.; other problems with them surface after submission.
  • A clip at 23.976 FPS counts as below 24 and is refused; re-export it at 24 FPS or higher.
  • Have a local file? Upload it with POST /v1/files and pass the returned data.url.

Task types

The “Needs” and “Leave out” columns are checked when the task is created: a request that breaks them is refused with 400 bad_request and costs nothing.

task_typeWhat it doesNeedsLeave out
auto or omittedThe model decides from the prompt whether reference videos are material, a video to edit or a video to extend.——
referenceA new video made from the references.At least one reference_* input—
editChanges one reference video. The result keeps its length and aspect ratio.reference_videosduration; aspect_ratio (or send adaptive)
extendContinues one reference video and keeps its aspect ratio. duration is the total length including the source.reference_videosaspect_ratio (or send adaptive)
  • These can still fail the task after it was created (bad_request, refunded): an edit whose source video is shorter than 4 or longer than 30 seconds, and a prompt the model reads as a different kind of task than the one you named. The message says what to change — which task_type to send, or how to word the prompt.

Writing the prompt for each task type

You wantSendWrite the prompt like this
A new video from the referencestask_type: "reference"Describe a new shot and say what each reference is for. Avoid “replace”, “remove”, “extend” or “continue”.
To change a videotask_type: "edit"Say what to add, remove or replace, and what must stay the same.
To continue a videotask_type: "extend"Describe what happens next, and set duration to the total length.

Fields this model does not accept

Sending one of these is refused before anything is charged, instead of being ignored:

  • watermark, quality, sound, multi_shots or character_orientation → field "watermark" is not supported by model seedance-2.5 (with the field you sent).
  • A name no BeatAPI video model uses → unknown field: <name>.
  • duration: -1 (model-chosen length) → "duration" is outside its supported range; send a whole number of seconds.

Request examples

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "seedance-2.5",
"prompt": "A slow tracking shot through a rain-lit night market, neon reflections on wet stone, ambient crowd sound",
"duration": 5,
"aspect_ratio": "16:9",
"resolution": "720p"
}'

Text to video

A 5-second 720p landscape clip with sound.

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "seedance-2.5",
"prompt": "A slow tracking shot through a rain-lit night market, neon reflections on wet stone, ambient crowd sound",
"duration": 5,
"aspect_ratio": "16:9",
"resolution": "720p"
}'

First and last frame

The video moves from the first image to the second.

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "seedance-2.5",
"prompt": "The camera pushes in from the bottle on the table to the singer on a neon stage in one continuous move",
"images": [
"https://media.beatapi.io/samples/smart-bottle.png",
"https://media.beatapi.io/samples/neon-singer.png"
],
"duration": 6,
"resolution": "720p"
}'

Image and audio references

A performance that follows a character image and a music clip.

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "seedance-2.5",
"prompt": "The singer from the first reference image performs on stage in time with the reference music, warm spotlights, slow orbiting camera",
"reference_images": [
"https://media.beatapi.io/samples/neon-singer.png"
],
"reference_audios": [
"https://media.beatapi.io/samples/neon-singer-preview.mp3"
],
"duration": 8,
"resolution": "720p",
"task_type": "reference"
}'

Image, video and audio references

Replace the video link with your own MP4 or MOV. Every second of the reference video is billed (see Billing).

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "seedance-2.5",
"prompt": "A product film: the bottle from the first reference image on a turntable, camera movement like the first reference video, cut to the beat of the reference music",
"reference_images": [
"https://media.beatapi.io/samples/smart-bottle.png"
],
"reference_videos": [
"https://your-cdn.example.com/clips/source.mp4"
],
"reference_audios": [
"https://media.beatapi.io/samples/neon-singer-preview.mp3"
],
"duration": 8,
"resolution": "720p",
"task_type": "reference"
}'

Edit a video

Replace the link with your own MP4 or MOV of 4 to 30 seconds. Leave out duration and aspect_ratio: the result keeps the source’s length and shape.

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "seedance-2.5",
"prompt": "Change the jacket of the person in the first reference video to bright red; keep everything else the same",
"reference_videos": [
"https://your-cdn.example.com/clips/source.mp4"
],
"resolution": "720p",
"task_type": "edit",
"output_format": "mov"
}'

Extend a video

Replace the link with your own clip. For a 5-second source, duration: 10 adds five seconds.

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "seedance-2.5",
"prompt": "The car keeps driving along the coast road as the sun sets, the camera rises to a wide aerial view",
"reference_videos": [
"https://your-cdn.example.com/clips/source.mp4"
],
"duration": 10,
"resolution": "720p",
"task_type": "extend"
}'

Responses

Create a task (201)

The task object. output is null until the task succeeds. Fields marked “while running” disappear once the task finishes.

{
"data": {
"id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
"object": "task",
"task_kind": "video",
"capability_id": "seedance-2.5",
"capability_version": 1,
"media_type": "video",
"model": "seedance-2.5",
"status": "queued",
"stage": "queued",
"created_at": 1791993600,
"updated_at": 1791993600,
"completed_at": null,
"poll_after_seconds": 8,
"output": null,
"usage": {
"credits_reserved": 1.148671,
"credits_settled": 0,
"credits_refunded": 0,
"credits_charged": 1.148671,
"billable_duration_seconds": 5
},
"request_id": "req_5f0c2a9e4b7d4e31",
"error_code": null,
"error_message": null
}
}
FieldTypeDescription
data.idstringTask ID: task_ followed by 32 letters and digits. Use it to poll and to match webhook events.
data.objectstringAlways task.
data.task_kindstringimage or video.
data.capability_idstringThe model ID you sent.
data.capability_versionintegerContract version of the model, currently 1.
data.media_typestringimage or video.
data.modelstringThe model ID you sent (same as capability_id).
data.statusstringqueued, processing, succeeded or failed. Only the last two are final.
data.stagestringRepeats status; kept for older clients.
data.created_atintegerWhen the task was created, Unix seconds.
data.updated_atintegerLast change, Unix seconds.
data.completed_atinteger | nullWhen the task finished, Unix seconds; null while it runs.
data.poll_after_secondsintegerWhile running: how long to wait before the next poll (5 for images, 8 for videos).
data.typical_secondsobjectWhile running, when enough recent tasks exist: p50 and p90 completion times in seconds over the last window, from samples tasks.
data.outputobject | nullThe result; null until status is succeeded. See the output fields below.
data.usage.credits_reservednumberUSD held from your balance when the task was created.
data.usage.credits_chargednumberUSD this task costs; 0 on a failed task.
data.usage.credits_settlednumberUSD finally taken; set when the task succeeds, otherwise 0.
data.usage.credits_refundednumberUSD returned to your balance; equals the reservation on a failed task once the refund is recorded.
data.usage.billable_duration_secondsintegerVideo only: the seconds the price is based on. Absent when the model reports no duration.
data.request_idstringRequest ID. Include it when you contact support.
data.error_codestring | nullFailure code; null unless the task failed.
data.error_messagestring | nullWhat went wrong and what to change; null unless the task failed.

Finished task

GET /v1/tasks/{task_id} returns HTTP 200 with status: "succeeded" and the result in data.output.

{
"data": {
"id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
"object": "task",
"task_kind": "video",
"capability_id": "seedance-2.5",
"capability_version": 1,
"media_type": "video",
"model": "seedance-2.5",
"status": "succeeded",
"stage": "succeeded",
"created_at": 1791993600,
"updated_at": 1791993690,
"completed_at": 1791993690,
"output": {
"media": [
{
"type": "video",
"url": "https://media.beatapi.io/outputs/task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ/0.mp4",
"mime_type": "video/mp4"
}
],
"r2_url": "https://media.beatapi.io/outputs/task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ/0.mp4"
},
"usage": {
"credits_reserved": 1.148671,
"credits_settled": 1.148671,
"credits_refunded": 0,
"credits_charged": 1.148671,
"billable_duration_seconds": 5
},
"request_id": "req_5f0c2a9e4b7d4e31",
"error_code": null,
"error_message": null
}
}

Output fields

FieldTypeDescription
output.mediaobject[]The generated files; one video for this model.
output.media[].typestringAlways video.
output.media[].urlstringHTTPS link to the stored video. Download and keep it; no retention period is promised.
output.media[].mime_typestringvideo/mp4, or video/quicktime for output_format: "mov".
output.r2_urlstringThe video URL again, for older clients. Read media instead.

Failed task

A failed task is still HTTP 200 on GET /v1/tasks/{task_id}: the failure is in the body. The reservation is returned in full, so nothing is charged.

{
"data": {
"id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
"object": "task",
"task_kind": "video",
"capability_id": "seedance-2.5",
"capability_version": 1,
"media_type": "video",
"model": "seedance-2.5",
"status": "failed",
"stage": "failed",
"created_at": 1791993600,
"updated_at": 1791993690,
"completed_at": 1791993690,
"output": null,
"usage": {
"credits_reserved": 1.148671,
"credits_settled": 0,
"credits_refunded": 1.148671,
"credits_charged": 0,
"billable_duration_seconds": 5
},
"retryable": true,
"request_id": "req_5f0c2a9e4b7d4e31",
"error_code": "processing_failed",
"error_message": "The task failed during processing on our side. Retry; a failed task is refunded."
}
}
FieldTypeDescription
data.error_codestringOne of bad_request and content_policy_violation (change the request) or processing_unavailable, processing_timeout, processing_failed and result_transfer_failed (try again later). See Errors.
data.error_messagestringA sentence that names the problem and the fix.
data.retryablebooleanPresent only on a failed task: true when the same request can succeed if you send it again.
data.usageobjectOnce the refund is recorded (normally at the moment the task fails): credits_charged and credits_settled are 0, and credits_refunded equals credits_reserved.

Complete example

Create a task, wait for it with the server’s polling hint, and print the result URLs. Set BEATAPI_API_KEY in your environment and install requests.

import os
import time
import uuid
import requests
API = "https://api.beatapi.io"
HEADERS = {"Authorization": f"Bearer {os.environ['BEATAPI_API_KEY']}"}
def create_task(body: dict) -> dict:
# One Idempotency-Key per logical request: a retry with the same key cannot create a second task.
headers = {**HEADERS, "Idempotency-Key": str(uuid.uuid4())}
for attempt in range(3):
response = requests.post(f"{API}/v1/videos/tasks", headers=headers, json=body, timeout=60)
if response.status_code in (429, 503) and attempt < 2:
time.sleep(int(response.headers.get("Retry-After", 10)))
continue
break
try:
payload = response.json()
except ValueError: # an edge error page is not JSON
response.raise_for_status()
raise
if not response.ok:
error = payload["error"]
raise RuntimeError(f"{response.status_code} {error['code']}: {error['message']} (request_id={error.get('request_id')})")
return payload["data"]
def wait_for_task(task_id: str, timeout_seconds: int = 1800) -> dict:
deadline = time.monotonic() + timeout_seconds
while time.monotonic() < deadline:
response = requests.get(f"{API}/v1/tasks/{task_id}", headers=HEADERS, timeout=30)
if response.status_code == 429 or response.status_code >= 500:
time.sleep(int(response.headers.get("Retry-After", 10)))
continue
response.raise_for_status()
task = response.json()["data"]
if task["status"] in ("succeeded", "failed"):
return task
time.sleep(task.get("poll_after_seconds", 5))
raise TimeoutError(f"task {task_id} is still running; keep polling later")
task = create_task({
"model": "seedance-2.5",
"prompt": "A slow tracking shot through a rain-lit night market, neon reflections on wet stone, ambient crowd sound",
"duration": 5,
"aspect_ratio": "16:9",
"resolution": "720p"
})
print("created", task["id"])
task = wait_for_task(task["id"])
if task["status"] == "failed":
raise SystemExit(f"{task['error_code']}: {task['error_message']}")
for item in task["output"]["media"]:
print(item["url"])

Billing

  • The price follows the size and length of the video: more seconds, a higher resolution or a larger frame cost more. Sound and output_format do not change it; reference images and audio add nothing.
  • Without reference video, a 16:9 clip costs about 0.106(480p),0.106 (480p), 0.228 (720p) or $0.564 (1080p) per second. Other aspect ratios differ by a few percent.
  • With reference_videos, the whole request moves to the lower “with video input” rate, and every second of reference video counts like a second of output: about 0.064(480p),0.064 (480p), 0.137 (720p) or $0.337 (1080p) per second of output plus reference, at 16:9.
  • The table below shows 8-second clips; its “with video input” rows include an 8-second reference video.
  • An edit pays for the source video twice — once as the reference and once as the output, which keeps the source’s length (rounded up to a whole second). usage.billable_duration_seconds shows the output seconds.
  • The price is reserved when the task is created. With adaptive or frames the reservation assumes the largest frame of the resolution. You pay the reservation, or the actual amount if the delivered video comes to more.
  • A very short reference video can be billed for a minimum length, which can bring the settled amount above the reservation; usage on the finished task shows what was charged.
  • A failed task, including one refused by moderation after submission, is refunded in full.

Current list prices, the same as on Pricing. An account with a negotiated discount pays less; data.usage on the task always shows the amount actually charged.

OptionList price (USD)
8 sec · 480p · no video input$0.851963
8 sec · 480p · with video input$1.019707
8 sec · 720p · no video input$1.832178
8 sec · 720p · with video input$2.192918
8 sec · 1080p · no video input$4.534641
8 sec · 1080p · with video input$5.403976

Common errors

Error or symptomCauseFix
400 resolution "1080p" is not available for this model right now; available: …No line serving this model accepts that value at the moment; the same can happen for aspect_ratio.Use one of the listed values, or retry later.
400 field "watermark" is not supported by model seedance-2.5A field this model does not accept (also quality, sound).Remove the field.
400 "resolution" must be one of: [480p 720p 1080p]4k, 2k or upper case such as 720P.Send 480p, 720p or 1080p; for 4K use seedance-2.
400 "duration" is outside its supported rangeNot a whole number from the range, or sent as a string.Send an integer such as 5.
400 Cannot combine "images" with reference inputs in one taskFrames and reference_* in the same request.Use frames or references. For several pictures, put them all in reference_images.
400 task_type "edit" keeps the reference video's length: leave "duration" outduration sent with an edit.Remove duration.
400 A reference video could not be read: reference_videos[0]: …Not an MP4 or MOV, a host without byte-range support, a 404, or an empty file.Host the clip on public HTTPS storage that supports range requests, or upload it with POST /v1/files.
400 The reference videos run 35 seconds in total; this model takes at most 30.The reference clips together are too long.Trim or drop clips.
Task failed with bad_request: “Seedance read the prompt as an edit of the reference video …”auto with an edit-sounding prompt: a duration is always sent (5 by default), and an edit keeps the source’s length.Send task_type: "edit" without duration and aspect_ratio, or task_type: "reference" with a prompt that describes a new shot.
Task failed with bad_request: “For task_type “edit”, the video being edited must be 4 to 30 seconds long …”The source video of an edit is shorter than 4 or longer than 30 seconds.Trim or replace the source; the failed task was refunded.
Task failed with content_policy_violationThe prompt, an input or the result was refused by moderation (real people, public figures, copyrighted characters). An input that shows a real person can be refused, and there is no way to have a face approved.Change the input. Retrying unchanged fails again; nothing is charged.
402 insufficient_creditsThe balance is below the reservation; long reference videos and adaptive raise it.Top up, shorten the references, or pick a fixed aspect_ratio.

HTTP errors at a glance

Errors before a task exists arrive as a non-2xx response, and nothing is charged. Branch on error.code or error.retryable; message names the problem. The full list and retry policy are on Errors.

{
"error": {
"code": "bad_request",
"message": "\"prompt\" is required",
"retryable": false,
"request_id": "req_5f0c2a9e4b7d4e31"
}
}
HTTP statuserror.codeWhat to do
400bad_request, content_policy_violationFix the request; the message names the field. Do not retry unchanged.
401missing_api_key, invalid_api_key (older clients may see unauthorized)Send a valid key as Authorization: Bearer <key>.
402insufficient_creditsTop up, or raise the key’s quota, then send it again.
403forbiddenThe key or account may not use this model (for example, free credit only covers some models). Do not retry unchanged.
404not_foundOn GET /v1/tasks/{task_id}: the task does not exist for this key’s account. Check the ID.
409idempotency_conflictUse a new Idempotency-Key, or wait for the first request with this key to finish.
429rate_limit_exceededWait Retry-After seconds (also error.retry_after_seconds), then retry.
500internal_errorRetry with backoff; contact support with request_id if it continues.
503processing_unavailable, processing_timeout, processing_failed, result_transfer_failedNothing was charged. Retry with exponential backoff.

Differences from Seedance 2.0

Seedance 2.5Seedance 2.0, 2.0 Fast, 2.0 Mini
Longest video30 s15 s
Reference setsUp to 30 images, 10 videos, 10 audio clipsUp to 9 images, 3 videos, 3 audio clips
Reference video length2–30 s each, 30 s in total1.8–15 s each, 15 s in total
Audio-only referenceAcceptedRefused: needs at least one image or video reference
task_type (edit, extend)YesNo
output_format (MOV)YesNo (MP4)
seedYesNo
4KNoseedance-2 only

Authentication

AuthorizationBearer

Send your API key as Authorization: Bearer <BEATAPI_API_KEY>.

Headers

Idempotency-KeystringOptional<=255 characters

Send the body as JSON with Content-Type: application/json. Idempotency-Key is optional: send a unique value (at most 255 characters) per logical request and reuse it only to retry that exact body. Within 24 hours a retry with the same key and body returns the first response again with Idempotent-Replayed: true; the same key with a different body returns 409 idempotency_conflict. Responses other than 2xx are not stored, so a retry after a 400 or 402 runs again.

Request

This endpoint expects an object.
modelenumRequired

The model to run.

Value: seedance-2.5

If the value is wrong

  • Missing: "model" is required
  • An image model sent to this endpoint: "model" nano-banana-2 is served by POST /v1/images/tasks, not this endpoint
Allowed values:
promptstringRequired1-5000 characters

What happens in the video: subject, action, camera movement, style and sound. With references, say what each input is for.

Length: 1–5000 characters

  • Length is counted in characters (a CJK character counts as one).
  • Refer to inputs by their position, for example “the first reference image” or “the second reference video”.
  • When you make a new video from reference videos, avoid words such as “replace”, “remove” or “extend”, or the model may read the request as an edit; send task_type: "reference" to be sure. For edit, say what to change and what to keep. For extend, describe what happens next.

If the value is wrong

  • Missing: "prompt" is required
  • Empty or longer than the limit: "prompt" has an unsupported length
aspect_ratioenumOptionalDefaults to adaptive

Shape of the video as width:height. adaptive lets the model choose from the inputs.

Allowed values: adaptive, 21:9, 16:9, 4:3, 1:1, 3:4, 9:16

Default: adaptive

  • Ignored when images carries a first frame: the video takes the frame’s aspect ratio.
  • With task_type edit or extend, leave it out or send adaptive: the result keeps the source video’s shape.
  • With adaptive (or frames) the reservation assumes the largest frame of the chosen resolution, so it can be slightly higher than with a fixed ratio.

If the value is wrong

  • A value not in the list: "aspect_ratio" must be one of: [adaptive 21:9 16:9 4:3 1:1 3:4 9:16]
  • A fixed ratio with edit or extend: task_type "edit" keeps the reference video's aspect ratio: leave "aspect_ratio" out or send "adaptive"
durationintegerOptional4-30Defaults to 5

Length of the video in seconds, a whole number.

Default: 5

Range: 4–30

  • If you leave it out, 5 is sent — also with task_type auto and reference.
  • With task_type: "extend", always send it: it is the length of the finished video including the source. To add 5 seconds to a 5-second clip, send 10; leaving it out asks for 5 seconds in total.
  • With task_type: "edit", leave it out: the result keeps the source video’s length.

If the value is wrong

  • Outside the range or not a whole number: "duration" is outside its supported range
  • Sent with task_type: "edit": task_type "edit" keeps the reference video's length: leave "duration" out
generate_audiobooleanOptionalDefaults to true

Whether the video has a generated soundtrack. The price is the same either way.

Default: true

If the value is wrong

  • Not true or false: "generate_audio" must be a boolean
imageslist of stringsOptional

A first frame, or a first and a last frame.

Items: 1–2

Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • One link: the video starts from this image. Two links: images[0] is the first frame and images[1] the last.
  • The video takes the aspect ratio of the first image; aspect_ratio is not applied.
  • For more pictures, or pictures that guide the video without being frames, use reference_images instead.

If the value is wrong

  • More than two links: "images" accepts at most 2 items
  • Combined with any reference_* field: Cannot combine "images" with reference inputs in one task
  • Not an https:// link: "images[0]" must be a public HTTPS URL
output_formatenumOptional

Container of the result: mp4 (used when you leave it out) or mov. The price is the same.

Allowed values: mp4, mov

  • mov suits further editing. It is not always available; when it is not, the request is refused before anything is charged with a sentence naming the formats you can use now.

If the value is wrong

  • A value not in the list: "output_format" must be one of: [mp4 mov]
Allowed values:
reference_audioslist of stringsOptional

Music, voice or sound to follow. Audio alone, without any image or video reference, is accepted.

Items: 1–10

Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • WAV and MP3 clips are measured against the limits below; other formats are passed to the model unmeasured.

If the value is wrong

  • More than the maximum: "reference_audios" accepts at most 10 items
reference_imageslist of stringsOptional

Pictures that guide the content, characters, products or style of the video.

Items: 1–30

Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • Images are used in list order; refer to them in the prompt by position.

If the value is wrong

  • More than the maximum: "reference_images" accepts at most 30 items
  • Combined with images: Cannot combine "images" with reference inputs in one task
reference_videoslist of stringsOptional

Videos to take motion, camera work or content from, or the video to edit or extend (see task_type).

Items: 1–10

Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • Each link must return an MP4 or MOV file whose host allows byte-range requests: the gateway reads the length of every clip before creating the task, because reference seconds are billed.
  • Required for task_type edit and extend.

Notes: Reference videos add to the price for every second they run (see Billing). Trim them to the part you need.

If the value is wrong

  • More than the maximum: "reference_videos" accepts at most 10 items
  • The clip cannot be read: A reference video could not be read: reference_videos[0]: its host does not allow byte-range requests. Send an MP4 or MOV file at a public HTTPS URL whose host allows byte-range requests.
resolutionenumOptionalDefaults to 720p

Output resolution. Higher resolution costs more per second.

Allowed values: 480p, 720p, 1080p

Default: 720p

  • Lower case only. 4K is not available on Seedance 2.5 (use seedance-2).

If the value is wrong

  • A value not in the list (for example 4k or 720P): "resolution" must be one of: [480p 720p 1080p]
Allowed values:
seedintegerOptional-1-4294967295

A fixed number makes results easier to repeat; leave it out or send -1 for a random seed.

Range: -1–4294967295

  • The same seed with the same request gives similar, not guaranteed identical, results.

If the value is wrong

  • Outside the range: "seed" is outside its supported range
task_typeenumOptional

What to do with reference_videos: make a new video from them (reference), edit one (edit), or extend one (extend). auto (or leaving it out) lets the model decide from the prompt.

Allowed values: auto, reference, edit, extend

  • Naming the type lets the gateway check the request before anything is charged; see Task types below for the rules of each.
  • With auto or reference a duration is always sent (5 if you leave it out), so a prompt the model reads as an edit fails after submission (refunded) or is re-run as an edit billed at the source video’s length. Send edit when you mean an edit.

If the value is wrong

  • A value not in the list: "task_type" must be one of: [auto reference edit extend]
  • edit or extend without a reference video: task_type "edit" needs a video in "reference_videos"
  • reference without any reference input: task_type "reference" needs reference inputs
Allowed values:

Response

The task object. output is null until the task succeeds. Fields marked “while running” disappear once the task finishes.

Errors

400
Bad Request Error
401
Unauthorized Error
402
Payment Required Error
403
Forbidden Error
409
Conflict Error
429
Too Many Requests Error
500
Internal Server Error
503
Service Unavailable Error