Seedance 2.5 Flash Motion Control Video API

bytedance/seedance-2.5-flash/motion-control

Transfer the motion of a reference video onto a character with Seedance 2.5 Flash. 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.

Motion Control
Input

Drag & drop or click to upload

10% OFF

Idle

$0.675per run·~14 / $10

Related Models

README

Seedance 2.5 Flash Motion Control

Seedance 2.5 Flash 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 10 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. 1080p is generated at 720p and upscaled.

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 10. 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. 1080p is generated at 720p and upscaled. 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.15$0.75$1.50$4.50
720p$0.30$1.50$3.00$9.00
1080p$0.75$3.75$7.50$22.50

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

Related Models

Note:This website uses AI models provided by third parties. Documentation prices are for reference and may be outdated. The Generate button shows an estimate; the final task charge prevails.

Seedance 2.5 Flash Motion Control API — Quick start

Grab a WaveSpeedAI API key, then call POST https://api.wavespeed.ai/api/v3/bytedance/seedance-2.5-flash/motion-control with your input as JSON. The endpoint returns a prediction id. Start polling the result endpoint around every 2 seconds, increase the interval for long-running tasks, and stop on any terminal status. On completed, read output values from data.outputs. Examples for Seedance 2.5 Flash Motion Control below.

HTTP example
set -euo pipefail

: "${WAVESPEED_API_KEY:?Set WAVESPEED_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.
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
  -X POST "https://api.wavespeed.ai/api/v3/bytedance/seedance-2.5-flash/motion-control" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $WAVESPEED_API_KEY" \
  -d "$REQUEST_BODY")

TASK=$(printf '%s' "$SUBMIT_RESPONSE" | jq 'if has("data") then .data else . end')
PREDICTION_ID=$(printf '%s' "$TASK" | jq -r '.id')
if [ -z "$PREDICTION_ID" ] || [ "$PREDICTION_ID" = "null" ]; then
  printf 'Submission response did not contain a prediction id
' >&2
  exit 1
fi
RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/$PREDICTION_ID/result"

# 2. Poll until the prediction finishes.
while true; do
  RESPONSE=$(curl --silent --show-error --fail-with-body "$RESULT_URL" \
    -H "Authorization: Bearer $WAVESPEED_API_KEY")
  RESULT=$(printf '%s' "$RESPONSE" | jq 'if has("data") then .data else . end')
  STATUS=$(printf '%s' "$RESULT" | jq -r '.status')
  case "$STATUS" in
    completed) printf '%s\n' "$RESULT" | jq '.outputs'; break ;;
    failed|cancelled|timeout|deleted) printf '%s\n' "$RESULT" | jq . >&2; exit 1 ;;
    *) sleep 2 ;;
  esac
done
Node.js example
const submitUrl = "https://api.wavespeed.ai/api/v3/bytedance/seedance-2.5-flash/motion-control";
const apiKey = process.env.WAVESPEED_API_KEY;
if (!apiKey) throw new Error('Set WAVESPEED_API_KEY');

async function requestJson(url, options = {}) {
  const response = await fetch(url, options);
  if (!response.ok) throw new Error(await response.text());
  return response.json();
}

// 1. Submit the prediction.
const body = await requestJson(submitUrl, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
        "video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
        "resolution": "720p",
        "generate_audio": true
}),
});
const task = body.data ?? body;
if (!task.id) throw new Error("Submission response did not contain a prediction id");
const resultUrl = `https://api.wavespeed.ai/api/v3/predictions/${task.id}/result`;

// 2. Poll until the prediction finishes.
while (true) {
  const resultBody = await requestJson(resultUrl, {
    headers: { "Authorization": `Bearer ${apiKey}` },
  });
  const result = resultBody.data ?? resultBody;
  if (result.status === "completed") {
    console.log(result.outputs);
    break;
  }
  if (["failed", "cancelled", "timeout", "deleted"].includes(result.status)) throw new Error(JSON.stringify(result));
  await new Promise(resolve => setTimeout(resolve, 2000));
}
Python example
import json
import os
import time
from urllib.request import Request, urlopen

api_key = os.environ["WAVESPEED_API_KEY"]
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
payload = {
    "video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
    "resolution": "720p",
    "generate_audio": True
}

def request_json(url, data=None):
    request = Request(url, data=data, headers=headers, method="POST" if data else "GET")
    with urlopen(request) as response:
        return json.load(response)

# 1. Submit the prediction.
body = request_json("https://api.wavespeed.ai/api/v3/bytedance/seedance-2.5-flash/motion-control", json.dumps(payload).encode())
task = body.get("data", body)
if not task.get("id"):
    raise RuntimeError("Submission response did not contain a prediction id")
result_url = f"https://api.wavespeed.ai/api/v3/predictions/{task['id']}/result"

# 2. Poll until the prediction finishes.
while True:
    result_body = request_json(result_url)
    result = result_body.get("data", result_body)
    status = result.get("status")
    if status == "completed":
        print(result.get("outputs", []))
        break
    if status in {"failed", "cancelled", "timeout", "deleted"}:
        raise RuntimeError(result)
    time.sleep(2)

Seedance 2.5 Flash Motion Control API — Frequently asked questions

What is the Seedance 2.5 Flash Motion Control API?

Seedance 2.5 Flash Motion Control is a ByteDance model for pose / motion driven video, exposed as a REST API on WaveSpeedAI. Transfer the motion of a reference video onto a character with Seedance 2.5 Flash. 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. You can call it programmatically or try it from the playground above.

How do I call the Seedance 2.5 Flash Motion Control API?

POST your input parameters to the model's REST endpoint (shown in the API tab of this playground) with your WaveSpeedAI API key in the Authorization header. Submission returns a prediction ID. Poll the result endpoint starting around every 2 seconds, increase the interval for long-running tasks, and stop on any terminal status. The playground generates Python, JavaScript, and cURL examples for submitting requests and polling results. Full request/response shape is documented at https://wavespeed.ai/docs/docs-api/bytedance/seedance-2.5-flash/motion-control.

How much does Seedance 2.5 Flash Motion Control cost per run or per second?

Seedance 2.5 Flash Motion Control starts at $0.675 per run or per second. That figure is the base price — the final charge scales with the parameters you set in the form (output size, length, count, references, or whatever knobs this model exposes), so a higher-quality or larger output costs more than a minimal one. The exact cost for your current input is shown live next to the Generate button before you submit, and the actual per-call charge is recorded on the prediction afterwards.

What inputs does Seedance 2.5 Flash Motion Control accept?

Key inputs: `prompt`, `video`, `resolution`, `reference_images`, `generate_audio`. The full JSON schema (types, defaults, allowed values) is rendered above the Generate button and mirrored in the API reference at https://wavespeed.ai/docs/docs-api/bytedance/seedance-2.5-flash/motion-control.

How do I get started with the Seedance 2.5 Flash Motion Control API?

Sign up for a free WaveSpeedAI account to claim starter credits, copy your API key from /accesskey, then call the endpoint shown in the API tab of the playground. The playground also auto-generates a code sample in Python, JavaScript, or cURL for the parameters you've set.

Can I use Seedance 2.5 Flash Motion Control outputs commercially?

Commercial usage rights depend on the model's license, set by its provider (ByteDance). Check the provider's applicable terms and WaveSpeedAI's Terms of Service before commercial use.

llms.txt — bytedance/seedance-2.5-flash/motion-control for AI agents and LLMs