Wan 2.2 Animate 2
Playground
Try it on WaveSpeedAI!Wan 2.2 Animate 2 is the next-generation Wan character animation model: an end-to-end DiT that makes the character in a reference image perform the motion of a driving video, with no pose extraction, prompt-controlled background, and strong identity preservation; generates 480p/720p videos up to 120s. Ready-to-use REST inference API, best performance, no coldstarts, affordable pricing.
Features
What is Wan 2.2 Animate 2?
Wan 2.2 Animate 2 (Wan2.2-Animate-2, the successor to Wan 2.2 Animate) is the next generation of the Wan character-animation family. It is an end-to-end model: the raw driving video conditions the generation directly inside a redesigned Diffusion Transformer, with no pose or keypoint extraction step. You provide one character image and one driving video, and the character performs the video’s full-body motion, hand gestures, and facial expressions.
Compared with Wan 2.2 Animate (v1):
- End-to-end motion transfer — no skeleton/pose preprocessing, which makes complex motion, fast dancing, and partially occluded performers noticeably more robust.
- Prompt-controlled background — the output background is generated from your prompt and is fully decoupled from both the reference image and the driving video. The background of your inputs does not matter.
- Strong identity preservation — the output character stays faithful to the reference image across the whole clip, including long videos.
- Long videos — driving videos up to 120 seconds are supported; segments are generated and chained natively by the model for seamless transitions.
The output video runs at 30 fps and follows the driving video’s duration and aspect ratio.
Note: Wan 2.2 Animate 2 focuses on character animation and does not include a replace mode. To swap a character into an existing shot while keeping the original scene and camera, use Wan 2.2 Animate (v1) in replace mode.
Pricing
Pricing depends on output length and resolution.
| Resolution | Price per 5 s | Max billed length |
|---|---|---|
| 480p | 0.20 USD | 120 s |
| 720p | 0.40 USD | 120 s |
Billing rules
-
Billed duration is clamped to the range 5–120 seconds
-
If the video is shorter than 5 s → billed as 5 s
-
If the video is longer than 120 s → billed as 120 s
-
480p: 0.20 USD per 5 s → 0.04 USD per second
-
720p: double 480p → 0.40 USD per 5 s → 0.08 USD per second
For example:
- 30 s at 480p → 30 × 0.04 = 1.20 USD
- 30 s at 720p → 30 × 0.08 = 2.40 USD
- 150 s at 720p (over the cap) → billed as 120 s → 120 × 0.08 = 9.60 USD
How to use Wan 2.2 Animate 2
-
image (required) Upload a clear character image. The character’s identity comes from here; the image background is ignored.
-
video (required) Upload the driving video whose motion and expressions you want to transfer. Up to 120 seconds.
-
prompt (optional) Describe how the character and the output background should look. The recommended format is:
Character appearance description: A young woman with shoulder-length pink hair, wearing a black leather jacket...
Background description: Plain light gray studio background, soft even lighting.Describe looks only — put motion wording in motion_prompt.
-
motion_prompt (optional) A short description of the motion in the driving video, e.g. “A person doing energetic street dance with rhythmic steps”.
-
resolution Choose 480p for faster, cheaper previews or 720p for higher-quality output.
-
seed (optional) Leave default for a fresh variation each run, or set a fixed integer to reproduce a result.
Practical tips
- Match the framing — keep the reference image and the driving video similar in camera distance and crop (full-body to full-body, half-body to half-body). Framing mismatch is the most common cause of weak results.
- Describe the background in the prompt — since the background follows the prompt, an explicit background description gives you full control of the scene.
- Keep the performer clear — avoid heavy occlusion and strong motion blur in the driving video.
- Prototype at 480p — find good inputs with 480p and short clips first, then switch to 720p and longer durations.
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'
{
"image": "https://interactive-examples.mdn.mozilla.net/media/cc0-images/painted-hand-298-332.jpg",
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"resolution": "480p",
"seed": -1
}
JSON
)
# 1. Submit the prediction.
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
-X POST "https://api.wavespeed.ai/api/v3/wavespeed-ai/wan-2.2/animate-2" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}" \
-H "Content-Type: application/json" \
-d "${REQUEST_BODY}")
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
' >&2
exit 1
fi
RESULT_URL=$(printf '%s' "${TASK}" | jq -r '.urls.get // empty')
if [ -z "${RESULT_URL}" ]; then RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result"; fi
# 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 type == "object" and has("data") then .data else . end')
STATUS=$(printf '%s' "${RESULT}" | jq -r '.status // empty')
case "${STATUS}" in
completed) printf '%s\n' "${RESULT}" | jq '.outputs'; break ;;
failed|cancelled|timeout) printf '%s\n' "${RESULT}" | jq . >&2; exit 1 ;;
created|processing) sleep 2 ;;
*) printf 'Unexpected status: %s
' "${STATUS}" >&2; exit 1 ;;
esac
doneParameters
Task Submission Parameters
Request Parameters
| Parameter | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
| image | string | Yes | - | The reference image of the character to animate. The output character keeps this identity; the background is generated from the prompt. | |
| video | string | Yes | - | The driving video whose body motion, hand gestures and facial expressions are transferred to the character. Up to 120 seconds. | |
| prompt | string | No | - | Describes the character's appearance and the output background, e.g. "Character appearance description: ...\nBackground description: ...". Looks only - put motion wording in motion_prompt. | |
| motion_prompt | string | No | - | - | Describes the motion in the driving video, e.g. "A person doing energetic street dance". |
| resolution | string | No | 480p | 480p, 720p | The resolution of the output video. |
| seed | integer | No | -1 | - | The random seed to use for the generation. -1 means a random seed will be used. |
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.urls.get | string | URL to retrieve the prediction result |
| data.status | string | Status of the task: created, processing, completed, or failed |
| 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.urls.get | string | URL to poll for the prediction result |
| data.status | string | Status: created, processing, completed, or failed |
| 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 |