The Wan first-and-last-frame-to-video model generates a smoothly transitioning video based on a first frame image, a last frame image, and a text prompt. Its capabilities include the following:
Video specifications: The duration is fixed at 5 seconds, and the resolution is fixed at 720P.
Intelligent prompt optimization: This feature automatically rewrites input prompts, which significantly improves the results for short prompts.
Others: You can choose whether to add an AIGC watermark.
Quick links: Try it on the Wan official website
The features on the Wan official website may differ from the capabilities that the API supports. This document reflects the actual capabilities of the API and is updated promptly with any new features.
Model overview
Feature | Input example | Output video | ||
First frame image | Last frame image | Prompt | ||
First-and-last-frame-to-video |
|
| Realistic style, a black kitten looks up at the sky curiously, the camera gradually rises from eye level, ending with a top-down shot of the kitten's curious eyes. | |
Model | Description | Output video format |
wan2.1-kf2v-plus | Wan 2.1 Professional Edition (silent video) Complex motion, physical law restoration, and detailed picture quality. | Resolution level: 720P Video duration: 5 seconds Fixed specifications: 30 fps, MP4 (H.264 encoding) |
Before you make a call, check the models supported in each region.
Prerequisites
Before making a call, obtain an API key and set the API key as an environment variable. If you use an SDK to make calls, install the DashScope SDK for Python or Java.
The Beijing and Singapore regions have separate API keys and request endpoints. Do not use them interchangeably. Cross-region calls cause authentication failures or service errors.
HTTP
Because image-to-video tasks are time-consuming, typically taking 1 to 5 minutes, the API uses asynchronous invocation. The process involves two core steps: Create a task -> Poll for the result. The details are as follows:
The actual time required depends on the number of tasks in the queue and service execution conditions. Please be patient while you wait for the result.
Step 1: Create a task to get a task ID
Singapore region: POST https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis
Beijing region: POST https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis
After the task is created, use the returned
task_idto query the result. The task_id is valid for 24 hours. Do not create duplicate tasks. Use polling to retrieve the result.
Request parameters | Generate a video from the first and last framesGenerate a video based on the first frame, last frame, and a prompt. Use a negative promptUse the negative_prompt parameter to prevent the "person" element from appearing in the generated video. |
Headers | |
Content-Type The content type of the request. Set this parameter to | |
Authorization The identity authentication credentials for the request. This API uses an Model Studio API key for identity authentication. Example: Bearer sk-xxxx. | |
X-DashScope-Async The asynchronous processing configuration parameter. HTTP requests support only asynchronous processing. You must set this parameter to Important If this request header is missing, the error message "current user api does not support synchronous calls" is returned. | |
Request body | |
model The model name. Example: wan2.1-kf2v-plus. For more information, see Models and pricing. | |
input The basic input information, such as the prompt. | |
parameters The video processing parameters. |
Response parameters | Successful responseSave the task_id to query the task status and result. Error responseThe task creation failed. For more information, see Error messages to resolve the issue. |
output The task output information. | |
request_id The unique request ID. You can use this ID to trace and troubleshoot issues. | |
code The error code for a failed request. This parameter is not returned if the request is successful. For more information, see Error messages. | |
message The detailed information about a failed request. This parameter is not returned if the request is successful. For more information, see Error messages. |
Step 2: Query the result by task ID
Singapore region: GET https://dashscope-intl.aliyuncs.com/api/v1/tasks/{task_id}
Beijing region: GET https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}
Polling suggestion: Video generation takes several minutes. Use a polling mechanism and set a reasonable query interval, such as 15 seconds, to retrieve the result.
Task status transition: PENDING (In queue) → RUNNING (Processing) → SUCCEEDED (Successful) or FAILED (Failed).
Result link: After the task is successful, a video link is returned. The link is valid for 24 hours. After you retrieve the link, immediately download and save the video to a permanent storage service, such as Alibaba Cloud OSS.
task_id validity: 24 hours. After this period, you cannot query the result, and the API returns a task status of
UNKNOWN.
Request parameters | Query task resultsReplace The API keys for the Singapore and Beijing regions are different. Obtain an API key. The following code provides the base_url for the Singapore region. If you use a model in the Beijing region, replace the base_url with https://dashscope.aliyuncs.com/api/v1/tasks/{task_id} |
Headers | |
Authorization The identity authentication credentials for the request. This API uses an Model Studio API key for identity authentication. Example: Bearer sk-xxxx. | |
Path parameters | |
task_id The task ID. |
Response parameters | Task succeededVideo URLs are retained for only 24 hours and are automatically purged after this period. You must save the generated videos promptly. Task failedIf a task fails, task_status is set to FAILED, and an error code and message are provided. For more information, see Error messages to resolve the issue. Task query expiredThe task_id is valid for 24 hours. After this period, the query fails and the following error message is returned. |
output The task output information. | |
usage The statistics for the output. Only successful tasks are counted. | |
request_id The unique request ID. You can use this ID to trace and troubleshoot issues. |
DashScope SDK
The parameter naming for the DashScope SDK is consistent with the HTTP API, and the parameter structure is encapsulated according to language-specific features.
Because image-to-video tasks are time-consuming, typically taking 1 to 5 minutes, the SDK encapsulates the HTTP asynchronous call process. It supports both synchronous and asynchronous invocation methods.
The actual time required depends on the number of tasks in the queue and the service's execution conditions. Please be patient while waiting for the result.
Python SDK
The Python SDK supports two image input methods: an Internet URL or a local file path (absolute or relative). For more information, see Input Image.
Install the latest version of the DashScope Python SDK. Otherwise, a runtime error may occur: Install or upgrade the SDK.
Synchronous call
This example shows how to make a synchronous call using two image input methods: an Internet URL and a local file path.
Sample request
import os
from http import HTTPStatus
# dashscope sdk >= 1.23.4
from dashscope import VideoSynthesis
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
# Get the DashScope API key (that is, the API key of Alibaba Cloud Model Studio) from the environment variable.
api_key = os.getenv("DASHSCOPE_API_KEY")
# ========== Image input method (choose one) ==========
# [Method 1] Use a public image URL.
first_frame_url = "https://wanx.alicdn.com/material/20250318/first_frame.png"
last_frame_url = "https://wanx.alicdn.com/material/20250318/last_frame.png"
# [Method 2] Use a local file path (file://+file path).
# Use an absolute path.
# first_frame_url = "file://" + "/path/to/your/first_frame.png" # Linux/macOS
# last_frame_url = "file://" + "C:/path/to/your/last_frame.png" # Windows
# Or use a relative path.
# first_frame_url = "file://" + "./first_frame.png" # Use the actual path.
# last_frame_url = "file://" + "./last_frame.png" # Use the actual path.
def sample_sync_call_kf2v():
print('please wait...')
rsp = VideoSynthesis.call(api_key=api_key,
model="wan2.2-kf2v-flash",
prompt="Realistic style, a black kitten looks up at the sky curiously, the camera gradually rises from eye level, ending with a top-down shot of the kitten'\''s curious eyes.",
first_frame_url=first_frame_url,
last_frame_url=last_frame_url,
resolution="720P",
prompt_extend=True)
print(rsp)
if rsp.status_code == HTTPStatus.OK:
print(rsp.output.video_url)
else:
print('Failed, status_code: %s, code: %s, message: %s' %
(rsp.status_code, rsp.code, rsp.message))
if __name__ == '__main__':
sample_sync_call_kf2v()Sample response
The video_url is valid for 24 hours. Download the video promptly.
{
"status_code": 200,
"request_id": "a37fafc3-907c-96f3-95a6-5b2a8268a3fd",
"code": null,
"message": "",
"output": {
"task_id": "4dba0092-da13-42b2-afb1-0f7b8a0f4643",
"task_status": "SUCCEEDED",
"video_url": "https://dashscope-result-wlcb-acdr-1.oss-cn-wulanchabu-acdr-1.aliyuncs.com/xxx.mp4?xxxxx",
"submit_time": "2025-05-23 15:50:12.404",
"scheduled_time": "2025-05-23 15:50:12.443",
"end_time": "2025-05-23 15:54:56.502",
"orig_prompt": "Realistic style, a black kitten looks up at the sky curiously, the camera gradually rises from eye level, ending with a top-down shot of the kitten'\''s curious eyes.",
"actual_prompt": "Realistic style, a black kitten looks up at the sky curiously, the camera gradually rises from eye level, ending with a top-down shot of the kitten'\''s curious eyes. The kitten'\''s yellow eyes are bright and expressive, its ears are pricked up, and its whiskers are clearly visible. The background is a simple, light-colored wall, which highlights the kitten'\''s black fur and focused expression. A close-up shot emphasizes the change in the kitten'\''s eyes and posture."
},
"usage": {
"video_count": 1,
"video_duration": 5,
"video_ratio": "standard"
}
}Asynchronous call
This example shows how to make an asynchronous call. This method immediately returns a task ID, and you must then poll the service or wait for the task to complete.
Sample request
import os
from http import HTTPStatus
# dashscope sdk >= 1.23.4
from dashscope import VideoSynthesis
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
# Get the DashScope API key (that is, the API key of Alibaba Cloud Model Studio) from the environment variable.
api_key = os.getenv("DASHSCOPE_API_KEY")
# ========== Image input method (choose one) ==========
# [Method 1] Use a public image URL.
first_frame_url = "https://wanx.alicdn.com/material/20250318/first_frame.png"
last_frame_url = "https://wanx.alicdn.com/material/20250318/last_frame.png"
# [Method 2] Use a local file path (file://+file path).
# Use an absolute path.
# first_frame_url = "file://" + "/path/to/your/first_frame.png" # Linux/macOS
# last_frame_url = "file://" + "C:/path/to/your/last_frame.png" # Windows
# Or use a relative path.
# first_frame_url = "file://" + "./first_frame.png" # Use the actual path.
# last_frame_url = "file://" + "./last_frame.png" # Use the actual path.
def sample_async_call_kf2v():
print('please wait...')
rsp = VideoSynthesis.async_call(api_key=api_key,
model="wan2.1-kf2v-plus",
prompt="Realistic style, a black kitten looks up at the sky curiously, the camera gradually rises from eye level, ending with a top-down shot of the kitten'\''s curious eyes.",
first_frame_url=first_frame_url,
last_frame_url=last_frame_url,
resolution="720P",
prompt_extend=True)
print(rsp)
if rsp.status_code == HTTPStatus.OK:
print("task_id: %s" % rsp.output.task_id)
else:
print('Failed, status_code: %s, code: %s, message: %s' %
(rsp.status_code, rsp.code, rsp.message))
# get the task information include the task status.
status = VideoSynthesis.fetch(rsp)
if status.status_code == HTTPStatus.OK:
print(status.output.task_status) # check the task status
else:
print('Failed, status_code: %s, code: %s, message: %s' %
(status.status_code, status.code, status.message))
# wait the task complete, will call fetch interval, and check it's in finished status.
rsp = VideoSynthesis.wait(rsp)
print(rsp)
if rsp.status_code == HTTPStatus.OK:
print(rsp.output.video_url)
else:
print('Failed, status_code: %s, code: %s, message: %s' %
(rsp.status_code, rsp.code, rsp.message))
if __name__ == '__main__':
sample_async_call_kf2v()Sample response
1. Sample response for creating a task
{
"status_code": 200,
"request_id": "c86ff7ba-8377-917a-90ed-xxxxxx",
"code": "",
"message": "",
"output": {
"task_id": "721164c6-8619-4a35-a6d9-xxxxxx",
"task_status": "PENDING",
"video_url": ""
},
"usage": null
}2. Sample response for querying the task result
The video_url is valid for 24 hours. Download the video promptly.
{
"status_code": 200,
"request_id": "efa545b3-f95c-9e3a-a3b6-xxxxxx",
"code": null,
"message": "",
"output": {
"task_id": "721164c6-8619-4a35-a6d9-xxxxxx",
"task_status": "SUCCEEDED",
"video_url": "https://dashscope-result-sh.oss-cn-shanghai.aliyuncs.com/xxx.mp4?xxxxx",
"submit_time": "2025-02-12 11:03:30.701",
"scheduled_time": "2025-02-12 11:06:05.378",
"end_time": "2025-02-12 11:12:18.853",
"orig_prompt": "Realistic style, a black kitten looks up at the sky curiously, the camera gradually rises from eye level, ending with a top-down shot of the kitten'\''s curious eyes.",
"actual_prompt": "Realistic style, a black kitten looks up at the sky curiously, the camera gradually rises from eye level, ending with a top-down shot of the kitten'\''s curious eyes. The kitten'\''s fur is black and shiny, its eyes are large and bright with golden pupils. It looks up with its ears pricked, looking particularly focused. After the camera moves up, the kitten turns its head to look directly at the camera, its eyes full of curiosity and alertness. The background is simple, highlighting the kitten'\''s detailed features. A close-up shot with soft natural light."
},
"usage": {
"video_count": 1,
"video_duration": 5,
"video_ratio": "standard"
}
}Java SDK
The Java SDK supports two image input methods: an Internet URL or a local file path (absolute path). For more information, see Input Image.
We recommend that you install the latest version of the DashScope Java SDK. Otherwise, a runtime error may occur. For more information, see Install or upgrade the SDK.
Synchronous call
This example shows how to make a synchronous call using two image input methods: an Internet URL and a local file path.
Sample request
// Copyright (c) Alibaba, Inc. and its affiliates.
// dashscope sdk >= 2.20.1
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesis;
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesisParam;
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesisResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;
import java.util.HashMap;
import java.util.Map;
public class Kf2vSyncIntl {
static {
Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
}
// Get the DashScope API key (that is, the API key of Alibaba Cloud Model Studio) from the environment variable.
static String apiKey = System.getenv("DASHSCOPE_API_KEY");
/**
* Image input method (choose one):
*
* [Method 1] Public URL
*/
static String firstFrameUrl = "https://wanx.alicdn.com/material/20250318/first_frame.png";
static String lastFrameUrl = "https://wanx.alicdn.com/material/20250318/last_frame.png";
/**
* [Method 2] Local file path (file://+absolute path or file:///+absolute path)
*/
// static String firstFrameUrl = "file://" + "/your/path/to/first_frame.png"; // Linux/macOS
// static String lastFrameUrl = "file:///" + "C:/path/to/your/img.png"; // Windows
public static void syncCall() {
Map<String, Object> parameters = new HashMap<>();
parameters.put("prompt_extend", true);
parameters.put("resolution", "720P");
VideoSynthesis videoSynthesis = new VideoSynthesis();
VideoSynthesisParam param =
VideoSynthesisParam.builder()
.apiKey(apiKey)
.model("wan2.1-kf2v-flash")
.prompt("Realistic style, a black kitten looks up at the sky curiously, the camera gradually rises from eye level, ending with a top-down shot of the kitten'\''s curious eyes.")
.firstFrameUrl(firstFrameUrl)
.lastFrameUrl(lastFrameUrl)
.parameters(parameters)
.build();
VideoSynthesisResult result = null;
try {
System.out.println("---sync call, please wait a moment----");
result = videoSynthesis.call(param);
} catch (ApiException | NoApiKeyException e){
throw new RuntimeException(e.getMessage());
} catch (InputRequiredException e) {
throw new RuntimeException(e);
}
System.out.println(JsonUtils.toJson(result));
}
public static void main(String[] args) {
syncCall();
}
}Sample response
The video_url is valid for 24 hours. Download the video promptly.
{
"request_id": "e6bb4517-c073-9c10-b748-dedb8c11bb41",
"output": {
"task_id": "984784fe-83c1-4fc4-88c7-52c2c1fa92a2",
"task_status": "SUCCEEDED",
"video_url": "https://dashscope-result-wlcb-acdr-1.oss-cn-wulanchabu-acdr-1.aliyuncs.com/xxx.mp4?xxxxx"
},
"usage": {
"video_count": 1,
"video_duration": 5,
"video_ratio": "standard"
}
}Asynchronous call
This example shows how to make an asynchronous call. This method immediately returns a task ID, and you must then poll the service or wait for the task to complete.
Sample request
// Copyright (c) Alibaba, Inc. and its affiliates.
// dashscope sdk >= 2.20.1
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesis;
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesisParam;
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesisResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.utils.JsonUtils;
import java.util.HashMap;
import java.util.Map;
public class Kf2vAsync {
static {
Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
}
// Get the DashScope API key (that is, the API key of Alibaba Cloud Model Studio) from the environment variable.
static String apiKey = System.getenv("DASHSCOPE_API_KEY");
/**
* Image input method (choose one)
*
* [Method 1] Public URL
*/
static String firstFrameUrl = "https://wanx.alicdn.com/material/20250318/first_frame.png";
static String lastFrameUrl = "https://wanx.alicdn.com/material/20250318/last_frame.png";
/**
* [Method 2] Local file path (file://+absolute path or file:///+absolute path)
*/
// static String firstFrameUrl = "file://" + "/your/path/to/first_frame.png"; // Linux/macOS
// static String lastFrameUrl = "file:///" + "C:/path/to/your/img.png"; // Windows
public static void asyncCall(){
// Set the parameters.
Map<String, Object> parameters = new HashMap<>();
parameters.put("prompt_extend", true);
parameters.put("resolution", "720P");
VideoSynthesis videoSynthesis = new VideoSynthesis();
VideoSynthesisParam param =
VideoSynthesisParam.builder()
.apiKey(apiKey)
.model("wan2.1-kf2v-flash")
.prompt("Realistic style, a black kitten looks up at the sky curiously, the camera gradually rises from eye level, ending with a top-down shot of the kitten'\''s curious eyes.")
.firstFrameUrl(firstFrameUrl)
.lastFrameUrl(lastFrameUrl)
.parameters(parameters)
.build();
VideoSynthesisResult result = null;
try {
System.out.println("---async call, please wait a moment----");
result = videoSynthesis.asyncCall(param);
} catch (ApiException | NoApiKeyException e){
throw new RuntimeException(e.getMessage());
} catch (InputRequiredException e) {
throw new RuntimeException(e);
}
System.out.println(JsonUtils.toJson(result));
String taskId = result.getOutput().getTaskId();
System.out.println("taskId=" + taskId);
try {
result = videoSynthesis.wait(taskId, apiKey);
} catch (ApiException | NoApiKeyException e){
throw new RuntimeException(e.getMessage());
}
System.out.println(JsonUtils.toJson(result));
System.out.println(JsonUtils.toJson(result.getOutput()));
}
public static void main(String[] args){
asyncCall();
}
}Sample response
1. Sample response for creating a task
{
"request_id": "5dbf9dc5-4f4c-9605-85ea-xxxxxxxx",
"output": {
"task_id": "7277e20e-aa01-4709-xxxxxxxx",
"task_status": "PENDING"
}
}2. Sample response for querying the task result
The video_url is valid for 24 hours. Download the video promptly.
{
"request_id": "1625235c-c13e-93ec-aff7-xxxxxxxx",
"output": {
"task_id": "464a5e46-79a6-46fd-9823-xxxxxxxx",
"task_status": "SUCCEEDED",
"video_url": "https://dashscope-result-sh.oss-cn-shanghai.aliyuncs.com/xxx.mp4?xxxxxx"
},
"usage": {
"video_count": 1,
"video_duration": 5,
"video_ratio": "standard"
}
}Limits
Data validity: The task_id and video URL are retained for only 24 hours. After this period, you cannot query or download them.
Audio support: Currently, the model only supports silent videos. Audio output is not supported. If you require audio, use speech synthesis.
Content moderation: The input prompt, images, and output video are all reviewed by Content Moderation. If prohibited content is detected, an "IPInfringementSuspect" or "DataInspectionFailed" error is returned. For more information, see Error messages.
Key parameters
Input image
The first_frame_url and last_frame_url parameters for the input image support the following methods:
Method 1: Public URL
A publicly accessible URL that supports HTTP or HTTPS.
Example:
https://example.com/images/cat.png.
Method 2: Local file path (SDK only)
Python SDK: Supports both absolute and relative file paths. The file path rules are as follows:
System
Input file path
Example (absolute path)
Example (relative path)
Linux or macOS
file://{absolute or relative path}
file:///home/images/test.png
file://./images/test.png
Windows
file://D:/images/test.png
file://./images/test.png
Java SDK: Supports only absolute file paths. The file path rules are as follows:
System
File path format
Example (absolute path)
Linux or macOS
file://{absolute path}
file:///home/images/test.png
Windows
file:///{absolute path}
file:///D:/images/test.png
Billing and rate limiting
For the model's free quota and pricing, see Models and pricing.
For rate limits, see Wan series.
Billing details:
You are billed for the duration in seconds of successfully generated videos. You are charged only when the API returns a
task_statusofSUCCEEDEDand a video is successfully generated.Model call failures or processing errors do not incur any fees or consume your free quota.
Error codes
If a model call returns an error, see Error messages.
FAQ
Quick access to video FAQs: FAQ.
Q: How to generate a video with a specific aspect ratio, such as 3:4?
A: The aspect ratio of the output video is determined by the input first frame image (img_url), but an exact ratio, such as a strict 3:4, cannot be guaranteed.
How it works: The model uses the aspect ratio of the input image as a baseline and then adapts it to a supported resolution based on the resolution parameter, such as 480p, 720p, or 1080p. Because the output resolution must meet technical requirements where the width and height must be divisible by 16, the final aspect ratio may have a slight deviation, for example, an adjustment from 0.75 to 0.739. This is normal behavior.
Example: An input image is 750 × 1000 (aspect ratio 3:4 = 0.75), and `resolution` is set to "720p" (target total pixels approx. 920,000). The actual output is 816 × 1104 (aspect ratio ≈ 0.739, total pixels approx. 900,000).
Note that the resolution parameter mainly controls the video's definition (total pixel count). The final video aspect ratio is still based on the input image, with only necessary minor adjustments.
Best practice: To strictly match a target aspect ratio, use an input image with that ratio and then post-process the output video by cropping or padding it. For example, you can use a video editing tool to crop the output video to the target ratio, or add black bars or a blurred background for padding.

