Bytedance Seedance 2.5 Motion Control API Documentation

Bytedance Seedance 2.5 Motion Control API Documentation

Playground

Try it on WaveSpeedAI!

Transfer the motion of a reference video onto a character with Seedance 2.5. Your character, from a picture or a short description, performs the same movements, gestures and camera motion as the video, in 480p, 720p or 1080p for up to 30 seconds. Ready-to-use REST inference API, best performance, no coldstarts, affordable pricing.

Features

Seedance 2.5 Motion Control transfers the motion of a reference video onto a character. Your character performs the same movements, gestures, timing and camera motion as the person in the video, while the background, framing and pacing of the video are kept.


Why Choose This?

  • Faithful motion transfer - Dance, gestures, walking, turning and full-body action carry over from the reference video to your character.

  • Character identity from your pictures - Face and hairstyle come from the first image. Add outfit, prop or location pictures, up to 30 images in total, to change what the character wears or where the scene takes place.

  • Video-driven timing and camera - Duration, framing and camera movement follow the reference video, so the result drops straight into your cut.

  • Native audio - Generate synchronized audio, or keep the original soundtrack of the reference video.

  • Up to 1080p, up to 30 seconds - Choose 480p for fast previews or 1080p for final delivery.


Parameters

ParameterRequiredDescription
videoYesURL of the motion reference video, 4 to 30 seconds. Only the first 30 seconds of a longer video are used, and a shorter video is billed as 4 seconds.
reference_imagesNoReference image URLs, up to 30. The first image is the character who performs the motion; a clear picture with a visible face works best. Add further pictures of an outfit, props or a location to use them in the shot.
promptNo*Optional extra direction; leave empty to transfer the motion as it is. *Required when no reference image is given: describe the character who replaces the person in the video.
resolutionNoOutput resolution: 480p, 720p, or 1080p. Default: 720p.
generate_audioNoGenerate synchronized audio for the output. When set to false, the reference video’s audio track is kept. Default: true.

The output duration and aspect ratio follow the reference video.


How to Use

  1. Upload the motion video — Provide a clip of the movement you want to copy, 4 to 30 seconds.
  2. Add reference pictures (optional) — The first picture is the character who performs the motion; add outfit, prop or location pictures after it. No picture? Describe the character in the prompt.
  3. Add direction if needed — Leave prompt empty, or add a short instruction.
  4. Choose resolution — Select 480p, 720p, or 1080p.
  5. Submit — Generate the video. API requests are asynchronous; poll the result endpoint until the video URL is available.

Tips for Better Results

  • Use a motion video with one clearly visible performer and a stable camera.
  • Pick a character image whose pose and framing are close to the first frame of the video (full body for full-body motion).
  • Keep the character’s face and clothing clearly visible in the image.
  • No picture? Describe the character in the prompt, for example a knight in silver armor. This works for human-like characters. For animals or objects, add a picture of the character instead.
  • Extra reference pictures are used where they fit: an outfit changes what the character wears, a location replaces the setting. Anything they do not cover stays as in the video.
  • Avoid heavily occluded limbs in the reference video; fast, complex motion is easier to follow when the performer stays in frame.

Pricing

Charges are based on the duration of the reference video, rounded up to whole seconds, with a 4-second minimum and a 30-second maximum.

ResolutionPer second5 seconds10 seconds30 seconds
480p$0.22$1.10$2.20$6.60
720p$0.44$2.20$4.40$13.20
1080p$1.10$5.50$11.00$33.00

For example, a 3.2-second clip is billed as 4 seconds, and a 8.04-second clip is billed as 9 seconds.


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'
{
  "video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
  "resolution": "720p",
  "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.5/motion-control" \
  -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
done

Retry temporary errors only while polling, never the submit request. Errors, retries and timeouts

Parameters

Task Submission Parameters

Request Parameters

ParameterTypeRequiredDefaultRangeDescription
videostringYes-URL of the motion reference video, 4 to 30 seconds. Only the first 30 seconds of a longer video are used, and a shorter video is billed as 4 seconds. The result follows its duration, camera and background.
reference_imagesarray<string>No-0 ~ 30 itemsOptional reference image URLs. The first image is the character who performs the motion. Add pictures of an outfit, props or a location to use them in the shot (30 images at most). Without any image, describe the character in the prompt.
promptstringNo-Optional extra direction for the result. Required when no reference image is given: describe the character who replaces the person in the video.
resolutionstringNo720p480p, 720p, 1080pOutput video resolution.
generate_audiobooleanNotrue-Whether to generate native audio for the output. Defaults to true. When set to false, the reference video's audio track is preserved on the output instead.

Every model also accepts the global request options enable_sync_mode and enable_base64_output; see their pages for details.

Response Parameters

ParameterTypeDescription
codeintegerHTTP status code (e.g., 200 for success)
messagestringStatus message (e.g., “success”)
data.idstringUnique identifier for the prediction, Task Id
data.modelstringModel ID used for the prediction
data.outputsarrayOutput values, usually URL strings; some models return text strings or structured result objects (empty when status is not completed)
data.urlsobjectObject containing related API endpoints
data.statusstringTask status. completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses.
data.created_atstringISO timestamp of when the request was created (e.g., “2023-04-01T12:34:56.789Z”)
data.errorstringError message (empty if no error occurred)
data.timingsobjectObject containing timing details
data.timings.inferenceintegerInference time in milliseconds

Result Request Parameters

ParameterTypeRequiredDefaultDescription
idstringYes-Task ID

Result Response Parameters

ParameterTypeDescription
codeintegerHTTP status code (e.g., 200 for success)
messagestringStatus message (e.g., “success”)
dataobjectThe prediction data object containing all details
data.idstringUnique identifier for the prediction
data.modelstringModel ID used for the prediction
data.outputsarray<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.urlsobjectObject containing related API endpoints
data.statusstringStatus: completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses
data.created_atstringISO timestamp of when the request was created
data.errorstringError message (empty if no error occurred)
data.timingsobjectObject containing timing details
data.timings.inferenceintegerInference time in milliseconds
© 2026 WaveSpeedAI. All rights reserved.