Bytedance Seedance 2.0 Video Edit Turbo API Documentation
Playground
Try it on WaveSpeedAI!Seedance 2.0 (Video-Edit Turbo) is the turbo tier for editing an input video from a natural-language prompt — faster, more affordable high-resolution output while preserving subject identity, composition, and motion. Ready-to-use REST API, best performance, no coldstarts, affordable pricing.
Features
Seedance 2.0 Video-Edit Turbo is the turbo tier for editing an input video from a natural-language prompt — faster, more affordable high-resolution output while preserving subject identity, composition, and motion of the original.
Key Features
- Turbo tier — Optimized for cost and speed at higher resolutions.
- Conversational video editing — Describe the change in plain language; the model rewrites the scene while keeping the original motion intact.
- Subject and motion preservation — Faces, objects, and camera movement from the input video stay consistent through the edit.
- Multi-reference support — Optionally guide style, character identity, or audio with reference images and audio clips.
- Native audio synchronization — Generates synchronized audio in a single pass.
Parameters
| Parameter | Required | Description |
|---|---|---|
| prompt | Yes | Describe the edit. |
| video | Yes | Input video URL. Videos longer than 15 s are trimmed to 15 s. |
| reference_images | No | Optional reference images for style or character guidance. |
| reference_audios | No | Optional reference audio for audio guidance. |
| duration | No | Output length in seconds (4-15). Auto-detected from the input video if not specified. |
| aspect_ratio | No | 16:9, 9:16, 4:3, 3:4, 1:1, 21:9. Adapts to the input if not specified. |
| resolution | No | 720p (default) or 1080p. |
| generate_audio | No | Generate synchronized audio for the output video (default: true) |
| enable_web_search | No | Enable web search for real-time context. |
How to Use
- Upload the input video. Anything longer than 15 s is trimmed to the first 15 s automatically.
- Write the edit prompt. Describe the change you want — the prefix
Edit the input video.is added for you. - (Optional) Add references. Reference images can constrain style or identity; reference audio can constrain the soundtrack.
- Pick a turbo resolution.
720por1080p. - Run. Receive the edited video at the requested resolution with synchronized audio.
Writing Effective Prompts
Editing keeps your source video and changes only what you name. Be precise about the scope, and describe the change as from A to B.
State the change plainly
Name exactly what to add, remove, or modify — and use an editing trigger word (add, remove, replace, change to, modify) so the intent is unambiguous.
- “Replace the man’s coffee cup with a book, keep everything else unchanged.”
- “Remove the subtitles.”
- “Change the background from a city street to a snowy forest.”
Use timestamps for partial edits
Confine a change to a time range so the rest of the clip is untouched.
- “From 4-6s, change the man’s action from drinking coffee to waving; leave the rest unchanged.”
Reference images for edits
Attach images to specify a replacement, and bind each explicitly (see below).
- “Replace the woman on the right with the person in @Image 1.”
Referencing uploaded assets
When you attach images, videos, or audio, bind each one explicitly in the prompt by its upload order — @Image 1, @Video 1, @Audio 1 — and say what it’s for. Don’t rely on labels drawn inside the image itself.
- “The knight in @Image 1 walks through the castle in @Image 2.”
- “Refer to @Video 1 for the camera movement only; keep its shot order.”
- “@Image 1 and @Image 2 are Character 1, voiced by @Audio 1.”
When a reference is already accurate, just point to it — no need to re-describe it in detail.
Audio edits
You can add, remove, or modify audio too.
- “Translate the dialogue to Spanish, keep lip movements matched, no subtitles.”
- “Remove the background music; keep only ambient and action sounds.”
Negative control
Positive descriptions work best, but you can suppress subtitles and audio:
- “No subtitles.”
- “No BGM — ambient and action sounds only.”
- “No audio.”
Weak vs. strong
| prompt | |
|---|---|
| weak | change the video |
| strong | Replace the red car in the video with a black motorcycle, matching its motion and speed. Keep the road, lighting, and camera movement unchanged. From 2s onward, add faint dust kicked up behind the rear wheel. Keep the original engine audio. |
Pricing
Billed as a base rate on input duration + output duration seconds, plus a resolution surcharge on output seconds only. Input duration is clamped to the 2-15 s range (sources shorter than 2 s are padded with the last frame).
| Component | Per second |
|---|---|
| Base (input + output seconds) | $0.075 |
| 720p surcharge (output seconds) | $0.02 |
| 1080p surcharge (output seconds) | $0.04 |
Examples (input 5 s, output 5 s):
| Resolution | Cost |
|---|---|
| 720p | $0.85 |
| 1080p | $0.95 |
Examples (input 12 s, output 12 s):
| Resolution | Cost |
|---|---|
| 720p | $2.04 |
| 1080p | $2.28 |
Notes
- Inputs longer than 15 s are trimmed to 15 s and inputs shorter than 2 s are padded with the last frame to 2 s before editing — billing reflects the conformed length.
- Auto-detected duration matches the input length (rounded up), clamped to the 4-15 s range.
- Native audio generation is included.
Related Models
- Seedance 2.0 Video-Edit — Standard tier at 480p / 720p / 1080p.
- Seedance 2.0 Fast Video-Edit Turbo — Faster, cheaper turbo tier.
Notice: Use @Image 1, @Image 2, @Audio 1, etc. to reference your uploaded assets. Number each type separately, in upload order.
Authentication
For authentication details, please refer to the Authentication Guide.
API Endpoints
Submit Task & Query Result
set -euo pipefail
export WAVESPEED_API_KEY="your-api-key"
REQUEST_BODY=$(cat <<'JSON'
{
"prompt": "A cinematic ocean wave at sunrise, highly detailed",
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"aspect_ratio": "16:9",
"resolution": "720p",
"enable_web_search": false,
"generate_audio": true
}
JSON
)
# 1. Submit the prediction once. Never retry this request automatically:
# a retry after an unclear failure can create a second, billed task.
CHECK='The task may already exist. Check History or the predictions list before submitting again.'
if ! SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
--connect-timeout 10 --max-time 60 \
-X POST "https://api.wavespeed.ai/api/v3/bytedance/seedance-2.0/video-edit-turbo" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}" \
-H "Content-Type: application/json" \
-d "${REQUEST_BODY}"); then
printf 'Submit failed. %s\n' "${CHECK}" >&2
exit 1
fi
TASK=$(printf '%s' "${SUBMIT_RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
PREDICTION_ID=$(printf '%s' "${TASK}" | jq -r '.id // empty')
if [ -z "${PREDICTION_ID}" ]; then
printf 'Submission response did not contain a prediction id. %s\n' "${CHECK}" >&2
exit 1
fi
RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result"
# 2. Poll until the prediction reaches a final status.
BODY_FILE=$(mktemp)
trap 'rm -f "${BODY_FILE}"' EXIT
while true; do
# Transient errors (429, 5xx) are retried, honoring Retry-After.
HTTP_CODE=$(curl --silent --show-error --fail-with-body \
--connect-timeout 10 --max-time 60 --retry 5 --retry-delay 2 \
--output "${BODY_FILE}" --write-out '%{http_code}' \
"${RESULT_URL}" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}" || true)
case "${HTTP_CODE}" in
2??) ;;
000|429|5??) # dropped connection or temporary error: keep polling
printf 'Task %s: HTTP %s, polling again in 10s\n' "${PREDICTION_ID}" "${HTTP_CODE}" >&2
sleep 10; continue ;;
*) printf 'Task %s: HTTP %s\n' "${PREDICTION_ID}" "${HTTP_CODE}" >&2
cat "${BODY_FILE}" >&2; exit 1 ;;
esac
RESULT=$(jq 'if type == "object" and has("data") then .data else . end' "${BODY_FILE}")
STATUS=$(printf '%s' "${RESULT}" | jq -r '.status // empty')
case "${STATUS}" in
completed) printf '%s\n' "${RESULT}" | jq '.outputs'; break ;;
failed|cancelled|timeout|deleted)
printf 'Task %s ended with status %s\n' "${PREDICTION_ID}" "${STATUS}" >&2
printf '%s\n' "${RESULT}" | jq . >&2; exit 1 ;;
*) sleep 2 ;;
esac
doneRetry temporary errors only while polling, never the submit request. Errors, retries and timeouts
Parameters
Task Submission Parameters
Request Parameters
| Parameter | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
| prompt | string | Yes | - | Describe the edit you want applied to the input video. | |
| video | string | Yes | - | URL of the input video to edit. Videos longer than 15s are trimmed to 15s. The output is at least 4s long. | |
| reference_images | array<string> | No | - | 0 ~ 9 items | Optional reference image URLs to guide the edit (subject identity, style, etc.). |
| reference_audios | array<string> | No | - | 0 ~ 3 items | Optional reference audio URLs to guide audio generation. |
| aspect_ratio | string | No | - | 16:9, 9:16, 4:3, 3:4, 1:1, 21:9 | Aspect ratio of the output video. Adapts to the input if not specified. |
| resolution | string | No | 720p | 720p, 1080p | Turbo output resolution. |
| duration | integer | No | - | 4 ~ 15 | Advanced option. Output video length in seconds (4-15). Auto-detected from the input video if not specified. |
| enable_web_search | boolean | No | false | - | Enable web search for real-time information. |
| generate_audio | boolean | No | true | - | Whether to generate native audio for the edited output. Defaults to true. When set to false, the input video's audio track is preserved on the output instead. |
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data.id | string | Unique identifier for the prediction, Task Id |
| data.model | string | Model ID used for the prediction |
| data.outputs | array | Output values, usually URL strings; some models return text strings or structured result objects (empty when status is not completed) |
| data.urls | object | Object containing related API endpoints |
| data.status | string | Task status. completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses. |
| data.created_at | string | ISO timestamp of when the request was created (e.g., “2023-04-01T12:34:56.789Z”) |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |
Result Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | Yes | - | Task ID |
Result Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data | object | The prediction data object containing all details |
| data.id | string | Unique identifier for the prediction |
| data.model | string | Model ID used for the prediction |
| data.outputs | array<string | object> | Array of generated outputs (empty when status is not completed). Items are usually URL strings, but may be text strings or structured result objects, depending on the model. |
| data.urls | object | Object containing related API endpoints |
| data.status | string | Status: completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses |
| data.created_at | string | ISO timestamp of when the request was created |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |