Begin on the first frame and finish on the last. One continuous 5-second shot: the garden gnome leans, tips, and launches from the pond rim, arcing through the air until it matches the mid-air crash into the koi pond. Preserve the same gnome, pond, koi, plants, and late-afternoon light. Slight handheld follow, no cuts. Native audio: stone scrape, wind whoosh, water slap, startled koi splash. No logos, no readable text, no products, no packaging, no prices, no CTA, no advertising, no watermark, no brand marks.
Wan 3.0 Prime Image-to-Video API
alibaba/wan-3.0-prime/image-to-videoWan 3.0 Prime (Image-to-Video) transforms a start-frame image and text prompt into a continuous video up to 30 seconds, with optional end-frame guidance, native audio-visual sync, and output up to 1080p. It carries the source subject, composition, and style into motion while adding action, camera movement, and sound.
Input
Drag and drop files, paste from clipboard, or provide a URL.
Drag and drop files, paste from clipboard, or provide a URL.
Output
IdleYour generated video will appear here
Configure the required inputs, resolution, and duration, then run the task.
Continue with
Examples
REST API
Quick Start
Authenticate, submit a valid input object, then use task_id to retrieve the video.
Connect to the Vidgo API
Create an API key, keep it only on your server, and send Authorization: Bearer VIDGO_API_KEY.
- Endpoint
- POST
https://api.vidgo.ai/api/generate/submit - Authentication
- Authorization: Bearer VIDGO_API_KEY
Submit one generation task
Run the smallest valid payload for this workflow. A successful submission immediately returns task_id without waiting for the video.
REQUEST_BODY=$(cat <<'JSON'
{
"model": "alibaba/wan-3.0-prime/image-to-video",
"input": {
"prompt": "Begin on the first frame and finish on the last. One continuous 5-second shot: the garden gnome leans, tips, and launches from the pond rim, arcing through the air until it matches the mid-air crash into the koi pond. Preserve the same gnome, pond, koi, plants, and late-afternoon light. Slight handheld follow, no cuts. Native audio: stone scrape, wind whoosh, water slap, startled koi splash. No logos, no readable text, no products, no packaging, no prices, no CTA, no advertising, no watermark, no brand marks.",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "adaptive",
"audio": true,
"enable_safety_checker": true,
"image_urls": [
"https://cdn.vidgo.ai/apis/models/alibaba/wan-3.0-prime/image-to-video/v1/01/input-start-frame.webp",
"https://cdn.vidgo.ai/apis/models/alibaba/wan-3.0-prime/image-to-video/v1/01/input-end-frame.webp"
]
}
}
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"Wait for the result
Query with task_id, continue for not_started/running, and stop for finished/failed. On success, read data.files[].file_url.
Track status
GET https://api.vidgo.ai/api/generate/status/{task_id}Poll about every 2 seconds, then back off gradually. Continue only for not_started or running and stop on finished or failed. You can instead add callback_url to the same top-level request contract.
not_startedrunningfinishedfailed{
"code": 200,
"data": {
"task_id": "task-unified-...",
"status": "running",
"created_time": "2026-08-22T10:00:00Z"
}
}{
"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 runnable example
Expand for a complete script with HTTP and business-code checks, task_id validation, polling, terminal-state handling, and a timeout boundary.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "alibaba/wan-3.0-prime/image-to-video",
"input": {
"prompt": "Begin on the first frame and finish on the last. One continuous 5-second shot: the garden gnome leans, tips, and launches from the pond rim, arcing through the air until it matches the mid-air crash into the koi pond. Preserve the same gnome, pond, koi, plants, and late-afternoon light. Slight handheld follow, no cuts. Native audio: stone scrape, wind whoosh, water slap, startled koi splash. No logos, no readable text, no products, no packaging, no prices, no CTA, no advertising, no watermark, no brand marks.",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "adaptive",
"audio": true,
"enable_safety_checker": true,
"image_urls": [
"https://cdn.vidgo.ai/apis/models/alibaba/wan-3.0-prime/image-to-video/v1/01/input-start-frame.webp",
"https://cdn.vidgo.ai/apis/models/alibaba/wan-3.0-prime/image-to-video/v1/01/input-end-frame.webp"
]
}
}
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
doneInput parameters
These are the fields accepted inside input. The request example shows the required top-level model field.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| image_urls | string[] | Yes | — | One or two public image URLs in Start, optional End order. |
| prompt | string | No | — | Optional; 1–20,000 characters after trimming when provided. |
| duration | integer | No | 5 | An integer from 2 through 30, inclusive. |
| resolution | string | No | 720p | 480p, 720p, or 1080p. |
| aspect_ratio | string | No | adaptive | adaptive, 16:9, 4:3, 1:1, 3:4, or 9:16. |
| audio | boolean | No | true | Whether to request an audio track; does not change the credit rate. |
| seed | integer | No | — | Optional integer from 0 through 2147483647. |
| enable_safety_checker | boolean | No | true | Whether to enable the safety checker. |
Response Fields
Submission returns task identity immediately. Status responses add progress, every output file, or a failure message.
| Field | Type | Description |
|---|---|---|
| code | integer | Application result code; successful responses use 0 or 200. |
| message | string | Human-readable message or error detail when present. |
| data.task_id | string | Task ID used in the status endpoint path. |
| data.status | string | not_started, running, finished, or failed. |
| data.created_time | string | Task creation time in date-time format. |
| data.progress | integer | Task progress from 0 to 100, when included in the response. |
| data.files[] | array | All output files from a successful task, in response order. |
| data.files[].file_url | string | Public URL for a generated video. |
| data.files[].file_type | string | File type, such as video. |
| data.error_message | string | null | Failure detail when status is failed. |
Task Lifecycle
Treat not_started and running as non-terminal states. finished and failed are terminal alternatives; stop polling when either is returned.
not_startedThe task was accepted and is waiting to begin.
runningGeneration is in progress. Continue polling the same task_id.
finishedGeneration succeeded. Read every video URL from data.files[].file_url.
failedGeneration stopped with an error. Read data.error_message and stop polling.
Polling and Errors
- AuthenticationA 401 response means the Bearer API key is missing or invalid. Correct it before retrying.
- ValidationA 400 response identifies an invalid field, unsupported media key, or insufficient credit balance. Correct the request before resubmitting.
- Network and timeoutA transport failure is different from a failed task. Retry status checks with a bounded timeout before deciding that the task failed.
- Polling intervalStart around every 2 seconds and increase the interval gradually for a long-running task.
- Terminal statesContinue only for not_started or running. Stop immediately on finished or failed.
- Callback optionProvide callback_url at the request top level to receive the final flat task object; polling remains available if delivery fails.
Endpoint limits
| Specification | Value | Details |
|---|---|---|
| Input mode | Image + optional text | image_urls requires 1–2 frames; prompt is optional for motion direction. |
| Output | Video task | The endpoint returns an asynchronous task ID. |
| Resolution | 480p / 720p / 1080p | resolution defaults to 720p when omitted. |
| Duration | 2–30 seconds | Every integer value in the inclusive range is valid; default is 5. |
| Aspect ratio | Adaptive + 5 fixed | adaptive, 16:9, 4:3, 1:1, 3:4, or 9:16. |
| Billing basis | Input video seconds + output seconds | 480p uses 13.6 credits/s; 720p uses 28 credits/s; 1080p uses 56 credits/s. |
Related Models
Wan 3.0 Prime Image To Video API — Frequently asked questions
What is the Wan 3.0 Prime Image-to-Video API?
Wan 3.0 Prime Image-to-Video is an Alibaba Tongyi Lab model for generating high-definition video from images. It animates static starting frames into continuous takes up to 30 seconds at up to 1080p resolution with native audio, supporting an optional ending frame for precise end-state control. Built on Wan 3.0 Prime's upgraded spatiotemporal alignment architecture, it preserves source facial likeness, intricate apparel textures, and lighting environments while delivering enhanced physical motion dynamics. You can call it programmatically or try it from the playground above.
What motion improvements does Wan 3.0 Prime Image-to-Video provide over Wan 3.0?
Wan 3.0 Prime substantially improves character facial stability, joint articulation, and complex physical dynamics (such as hair sway, flowing water, and fabric motion) under significant camera movements, greatly reducing distortion when animating from static images.
How do I guide video transitions with an end frame in Wan 3.0 Prime Image-to-Video?
Provide two image URLs in the image_urls array, where the first acts as the start frame and the second defines the closing frame. The model calculates spatiotemporal interpolation between both compositions, generating smooth intermediate dynamics and camera shifts across your chosen duration.
Does Wan 3.0 Prime Image-to-Video synthesize synchronized sound for photos?
Yes. With joint audiovisual diffusion, the model automatically analyzes visual context and prompt descriptions to synthesize matching ambient acoustics, motion foley, and impact sounds without requiring external audio inputs.
How can I ensure subject identity consistency in Wan 3.0 Prime Image-to-Video?
Upload a clear, well-lit starting image with distinct facial or product features, and describe specific motion directions in the prompt while avoiding contradictory character changes. The model anchors identity features directly from the initial still.
Does Wan 3.0 Prime Image-to-Video support 9:16 vertical video?
Yes. When aspect_ratio is set to adaptive, the output matches the aspect ratio of the first input image. You can also explicitly specify 9:16 to adapt horizontal source stills into vertical video compositions optimized for mobile feeds.
Can Wan 3.0 Prime Image-to-Video generate motion without a text prompt?
Yes. If no prompt is provided, the model automatically infers plausible physical dynamics and camera drift based on the image's scene content. Adding prompt text allows you to direct explicit trajectories, character actions, and sound design.















