Courtyard Fan Dance
Wan Animate Move API
alibaba/wan/v2.2-14b/animate/moveWan Animate Move transforms a single character image into dynamic video using motion extracted from a reference video, featuring full-body pose retargeting, expressive facial synchronization, and multiple resolution tiers. It preserves the subject's distinct facial features, wardrobe textures, and physical proportions while accurately reproducing the driver video's movement timing.
Drag and drop files, paste from clipboard, or provide a URL. One image. Playground uploads: JPG, PNG or WebP, up to 10 MiB. The API requires an HTTP(S) URL array.
1/1 files added
Drag and drop files, paste from clipboard, or provide a URL. One video. Playground uploads: MP4, MOV or MKV, up to 100 MiB. Billing uses source duration rounded up to seconds.
1/1 files added
Examples
REST API Spec
Quick Start
A real generation example. The request matches the default input; the response was captured from its test-environment submission.
Step 1: Configure API authentication
Obtain an API key from the dashboard and include Authorization: Bearer <API_KEY> in every request header.
- Submission Endpoint
- POST
https://api.vidgo.ai/api/generate/submit - Auth Header
- Authorization: Bearer VIDGO_API_KEY
Step 2: Submit a generation task
POST /api/generate/submit. Pass model and optional callback_url at the root level, with generation parameters inside input.
REQUEST_BODY=$(cat <<'JSON'
{
"model": "alibaba/wan/v2.2-14b/animate/move",
"input": {
"image_urls": [
"https://cdn.vidgo.ai/apis/models/alibaba/wan/v2.2-14b/animate/move/v1/01/input-image.png"
],
"video_url": "https://cdn.vidgo.ai/apis/models/alibaba/wan/v2.2-14b/animate/move/v1/01/input-video.mp4",
"resolution": "480p"
}
}
JSON
)
RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
CODE=$(printf '%s' "$RESPONSE" | jq -r '.code // empty')
if [ "$CODE" != "0" ] && [ "$CODE" != "200" ]; then
printf 'API error: %s
' "$RESPONSE" >&2
exit 1
fi
printf '%s
' "$RESPONSE"Step 3: Poll for task completion
Poll status with task_id; continue while not_started or running, and stop on finished or failed. Read video URLs from data.files[].file_url on success, or data.error_message on failure.
Status Endpoint
GET https://api.vidgo.ai/api/generate/status/{task_id}Poll status using task_id; continue while not_started or running, stop when finished or failed. On success, read data.files[].file_url; on failure, read data.error_message.
not_startedrunningfinishedfailed{
"code": 200,
"data": {
"task_id": "GSOXV2FCR91IOHT2",
"status": "running",
"created_time": "2026-09-23T09:54:19"
}
}{
"code": 200,
"data": {
"task_id": "task-unified-...",
"status": "finished",
"files": [
{
"file_url": "https://storage.vidgo.ai/generated/video.mp4",
"file_type": "video"
}
],
"created_time": "2026-08-22T10:00:00Z",
"progress": 100,
"error_message": null
}
}Complete end-to-end script example
Expand to view a production-ready script with retry logic, error handling, and timeout safeguards.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "alibaba/wan/v2.2-14b/animate/move",
"input": {
"image_urls": [
"https://cdn.vidgo.ai/apis/models/alibaba/wan/v2.2-14b/animate/move/v1/01/input-image.png"
],
"video_url": "https://cdn.vidgo.ai/apis/models/alibaba/wan/v2.2-14b/animate/move/v1/01/input-video.mp4",
"resolution": "480p"
}
}
JSON
)
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
TASK_ID=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.data.task_id // .task_id // empty')
BUSINESS_CODE=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Submit failed:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
if [ -z "$TASK_ID" ]; then
printf 'Submit response did not include task_id:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
START_TIME=$(date +%s)
POLL_DELAY=2
while true; do
if [ $(( $(date +%s) - START_TIME )) -ge 600 ]; then
printf 'Timed out after 600 seconds
' >&2
exit 1
fi
STATUS_RESPONSE=$(curl --silent --show-error --fail-with-body \
--url "https://api.vidgo.ai/api/generate/status/$TASK_ID" \
--header "Authorization: Bearer $VIDGO_API_KEY")
STATUS=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.data.status // .status // empty')
BUSINESS_CODE=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Status request failed:
%s
' "$STATUS_RESPONSE" >&2
exit 1
fi
case "$STATUS" in
finished)
printf '%s' "$STATUS_RESPONSE" | jq -r '(.data.files // .files // [])[]?.file_url'
break
;;
failed)
printf '%s' "$STATUS_RESPONSE" | jq -r '.data.error_message // .error_message // "Generation failed"' >&2
exit 1
;;
not_started|running)
sleep "$POLL_DELAY"
if [ "$POLL_DELAY" -lt 10 ]; then POLL_DELAY=$((POLL_DELAY + 1)); fi
;;
*)
printf 'Unexpected task status: %s
' "$STATUS" >&2
exit 1
;;
esac
doneRequest Parameters (input object)
POST /api/generate/submit accepts only the following input fields. Set model and optional callback_url at the root. URLs must contain a hostname and no credentials or whitespace.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| image_urls | array<string> | Yes | — | Exactly one public HTTP(S) image URL in an array. Bare strings and Base64 are rejected. |
| video_url | string | Yes | — | Required public HTTP(S) source video URL. Vidgo inspects files up to 100 MiB. Duration must be positive; do not send a duration field. |
| resolution | string | No | 480p | 480p, 580p or 720p. Defaults to 480p only when omitted. Null, empty strings, aliases and surrounding whitespace are rejected. |
Response Fields (query result)
Task details returned when polling GET /api/generate/status/{task_id}:
| Field | Type | Description |
|---|---|---|
| code | integer | Business response code, 200 on success. |
| data.task_id | string | Globally unique asynchronous task identifier. |
| data.status | string | Execution status: not_started, running, finished, or failed. |
| data.files | array | Generated video files upon completion, each with file_url and file_type. |
| data.error_message | string | null | Error description if task fails. |
Task Lifecycle
Clients should inspect the status field and stop polling when reaching finished or failed:
not_startedTask received and queued for execution.
runningGeneration is in progress.
finishedGeneration complete; retrieve video URL from data.files.
failedGeneration failed; inspect data.error_message; deducted credits are refunded per standard policy.
Polling & Error Handling
- Recommended Polling IntervalThe playground increases the polling interval from 2 seconds up to 10 seconds and stops on finished or failed.
- Network Fluctuations & RetriesA failed status query does not mean generation failed. Retry the status query for the same task without resubmitting.
- Asynchronous Webhook CallbackProvide callback_url at the root of the request payload to receive the completed task result automatically via POST.
Specifications
| Specification | Value | Description |
|---|---|---|
| Model ID | alibaba/wan/v2.2-14b/animate/move | Use this value in the root model field. |
| Resolution | 480p / 580p / 720p | 480p, 580p or 720p. Defaults to 480p only when omitted. Null, empty strings, aliases and surrounding whitespace are rejected. |
| Billing | 7 / 12 / 15 credits/sec | Estimated credits = ceil(source video seconds) × the resolution rate. Vidgo measures duration on the server. For example, 5.1 seconds at 480p costs 42 credits ($0.210). Media inspection errors are rejected before deduction; failed tasks are refunded. |
Related Models
Wan Animate Move API Frequently Asked Questions
What is the Wan Animate Move API?
Wan Animate Move is an Alibaba model for video motion transfer from images and reference videos. It extracts full-body skeletal movement, head orientation, and facial expressions from a driving video to animate a single still character portrait across 480p, 580p, and 720p resolutions. Built on Wan2.2-Animate's 14B parameter multimodal architecture, it preserves the character's facial likeness, wardrobe textures, and physical proportions while reproducing dynamic motion with temporal coherence. You can call it programmatically or try it from the playground above.
What image formats does Wan Animate Move accept?
Wan Animate Move accepts standard JPEG, PNG, and WebP image formats provided as a single public HTTP(S) URL in the image_urls array. In the web playground, you can upload files up to 10 MiB, and images with clear subject lighting and visible posture produce the most consistent motion retargeting.
What are the requirements for the source video in Wan Animate Move?
The source driving video must be accessible via a public HTTP or HTTPS URL in the video_url parameter, formatted as MP4, MOV, or MKV, and under 100 MiB in file size. Videos with steady camera angles, good lighting, and uninterrupted subject movement provide the clearest skeletal keypoints for animation.
How does Wan Animate Move preserve character identity during motion transfer?
Wan Animate Move leverages spatio-temporal cross-attention to isolate motion representations from identity features. It locks the original face geometry, hairstyle, and outfit patterns from your input image while mapping joint rotations and facial expressions from the reference video onto that preserved identity.
How is billing calculated for Wan Animate Move?
Billing is calculated by rounding the source video duration up to the nearest whole second and multiplying by the resolution rate: 7 credits/sec ($0.035/sec) for 480p, 12 credits/sec ($0.060/sec) for 580p, and 15 credits/sec ($0.075/sec) for 720p. If input validation fails or generation cannot complete, deducted credits are refunded automatically.
Which resolution option should I choose for Wan Animate Move?
Choose 480p as the default tier for rapid pose validation and iterative testing at the lowest credit cost, 580p for balanced social media sharing, or 720p when delivering final high-definition animations for professional client presentations and production assets.
When should I choose Wan Animate Move over Wan Animate Replace?
Choose Wan Animate Move when you want to take an isolated character portrait and animate them into a brand-new performance driven by reference motion. Choose Wan Animate Replace when you already have a complete video scene and wish to swap an existing actor with a new subject while keeping the original background, camera trajectory, and lighting.















