All Products
Search
Document Center

Alibaba Cloud Model Studio:Wan - first-and-last-frame-to-video API reference

Last Updated:Nov 03, 2025

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

Note

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

first_frame

last_frame

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)

Note

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.

Important

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

Note
  • After the task is created, use the returned task_id to 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 frames

Generate a video based on the first frame, last frame, and a prompt.

curl --location 'https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis' \
    -H 'X-DashScope-Async: enable' \
    -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
    "model": "wan2.2-kf2v-flash",
    "input": {
        "first_frame_url": "https://wanx.alicdn.com/material/20250318/first_frame.png",
        "last_frame_url": "https://wanx.alicdn.com/material/20250318/last_frame.png",
        "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."
    },
    "parameters": {
        "resolution": "480P",
        "prompt_extend": true
    }
}'

Use a negative prompt

Use the negative_prompt parameter to prevent the "person" element from appearing in the generated video.

curl --location 'https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis' \
    -H 'X-DashScope-Async: enable' \
    -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
    "model": "wan2.1-kf2v-plus",
    "input": {
        "first_frame_url": "https://wanx.alicdn.com/material/20250318/first_frame.png",
        "last_frame_url": "https://wanx.alicdn.com/material/20250318/last_frame.png",
        "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.",
        "negative_prompt": "person"
    },
    "parameters": {
        "resolution": "720P",
        "prompt_extend": true
    }
}'
Headers

Content-Type string (Required)

The content type of the request. Set this parameter to application/json.

Authorization string (Required)

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 string (Required)

The asynchronous processing configuration parameter. HTTP requests support only asynchronous processing. You must set this parameter to enable.

Important

If this request header is missing, the error message "current user api does not support synchronous calls" is returned.

Request body

model string (Required)

The model name. Example: wan2.1-kf2v-plus.

For more information, see Models and pricing.

input object (Required)

The basic input information, such as the prompt.

Properties

prompt string (Optional)

The text prompt. It supports Chinese and English. The prompt can be up to 800 characters long. Each Chinese character or letter counts as one character. Text that exceeds the limit is automatically truncated.

If the subject and scene change significantly between the first and last frames, describe the transition process, such as camera movement (the camera moves to the left) or subject movement (a person runs forward).

Example: A black kitten looks up at the sky curiously, the camera gradually rises from eye level, and finally shoots from a top-down angle to capture the kitten's curious eyes.

For more information about how to use prompts, see the Text-to-video/image-to-video prompt guide.

negative_prompt string (Optional)

The negative prompt. Use it to describe content that you do not want to appear in the video. This can help you control the video content.

It supports Chinese and English. The prompt can be up to 500 characters long. Text that exceeds the limit is automatically truncated.

Example: low resolution, error, worst quality, low quality, incomplete, extra fingers, poor proportions.

first_frame_url string (Required)

The URL of the first frame image. The aspect ratio of the output video is the same as the first frame image.

The URL must be a publicly accessible address and support the HTTP or HTTPS protocol.

Image requirements:

  • Image format: JPEG, JPG, PNG (alpha channel not supported), BMP, or WEBP.

  • Image resolution: The width and height must be in the range of [360, 2000] pixels.

  • File size: No more than 10 MB.

last_frame_url string (Required)

The URL of the last frame image.

The URL must be publicly accessible and use the HTTP or HTTPS protocol.

Image requirements:

  • Image format: JPEG, JPG, PNG (alpha channel not supported), BMP, or WEBP.

  • Image resolution: The width and height must be in the range of [360, 2000] pixels. The resolution of the last frame image can be different from the first frame image. They do not need to be aligned.

  • File size: No more than 10 MB.

parameters object (Optional)

The video processing parameters.

Properties

resolution string (Optional)

Important

The resolution directly affects the cost. For the same model, a higher resolution incurs a higher cost (1080P > 720P > 480P). Before you make a call, confirm the model pricing.

The resolution level of the generated video. This is used only to adjust the video's definition (total pixels) and does not change the aspect ratio. The video's aspect ratio is the same as the aspect ratio of the first frame image (first_frame_url).

The default value and available enumeration values for this parameter depend on the model parameter, as follows:

  • wan2.1-kf2v-plus: The only optional value is 720P. The default value is 720P.

Example: 720P.

duration integer (Optional)

Important

The duration parameter directly affects the cost, which is billed per second. Confirm the model pricing before you call the model.

The duration of the generated video in seconds. This parameter is fixed at 5 and cannot be changed. The model always generates a 5-second video.

prompt_extend bool (Optional)

Specifies whether to enable intelligent prompt rewriting. If enabled, a large language model rewrites the input prompt. This significantly improves the generation results for short prompts but increases the processing time.

  • true (default)

  • false

Example: true.

watermark bool (Optional)

Specifies whether to add a watermark. The watermark is in the lower-right corner of the video and says "AI-generated".

  • false (default)

  • true

Example: false.

seed integer (Optional)

The random number seed. The value must be in the range of [0, 2147483647].

If this parameter is not specified, the system automatically generates a random seed. To improve the reproducibility of the generated results, use a fixed seed value.

Note that because model generation is probabilistic, using the same seed does not guarantee that the generated results are identical every time.

Example: 12345.

Response parameters

Successful response

Save the task_id to query the task status and result.

{
    "output": {
        "task_status": "PENDING",
        "task_id": "0385dc79-5ff8-4d82-bcb6-xxxxxx"
    },
    "request_id": "4909100c-7b5a-9f92-bfe5-xxxxxx"
}

Error response

The task creation failed. For more information, see Error messages to resolve the issue.

{
    "code":"InvalidApiKey",
    "message":"Invalid API-key provided.",
    "request_id":"fb53c4ec-1c12-4fc4-a580-xxxxxx"
}

output object

The task output information.

Properties

task_id string

The task ID. The query is valid for 24 hours.

task_status string

The task status.

Enumeration

  • PENDING

  • RUNNING

  • SUCCEEDED

  • FAILED

  • CANCELED

  • UNKNOWN

request_id string

The unique request ID. You can use this ID to trace and troubleshoot issues.

code string

The error code for a failed request. This parameter is not returned if the request is successful. For more information, see Error messages.

message string

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}

Note
  • 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 results

Replace 86ecf553-d340-4e21-xxxxxxxxx with the actual task ID.

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}
curl -X GET https://dashscope-intl.aliyuncs.com/api/v1/tasks/86ecf553-d340-4e21-xxxxxxxxx \
--header "Authorization: Bearer $DASHSCOPE_API_KEY"
Headers

Authorization string (Required)

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 string (Required)

The task ID.

Response parameters

Task succeeded

Video URLs are retained for only 24 hours and are automatically purged after this period. You must save the generated videos promptly.

{
    "request_id": "ec016349-6b14-9ad6-8009-xxxxxx",
    "output": {
        "task_id": "3f21a745-9f4b-4588-b643-xxxxxx",
        "task_status": "SUCCEEDED",
        "submit_time": "2025-04-18 10:36:58.394",
        "scheduled_time": "2025-04-18 10:37:13.802",
        "end_time": "2025-04-18 10:45:23.004",
        "video_url": "https://dashscope-result-wlcb.oss-cn-wulanchabu.aliyuncs.com/xxx.mp4?xxxxx",
        "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 fur is smooth, and its whiskers are clearly visible. The background is a simple, light-colored wall, which highlights the kitten'\''s black silhouette. A close-up shot emphasizes the changes in the kitten'\''s expression and the details of its eyes."
    },
    "usage": {
        "video_duration": 5,
        "video_count": 1,
        "SR": 480
    }
}

Task failed

If 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.

{
    "request_id": "e5d70b02-ebd3-98ce-9fe8-759d7d7b107d",
    "output": {
        "task_id": "86ecf553-d340-4e21-af6e-a0c6a421c010",
        "task_status": "FAILED",
        "code": "InvalidParameter",
        "message": "The size is not match xxxxxx"
    }
}

Task query expired

The task_id is valid for 24 hours. After this period, the query fails and the following error message is returned.

{
    "request_id": "a4de7c32-7057-9f82-8581-xxxxxx",
    "output": {
        "task_id": "502a00b1-19d9-4839-a82f-xxxxxx",
        "task_status": "UNKNOWN"
    }
}

output object

The task output information.

Properties

task_id string

The task ID. The query is valid for 24 hours.

task_status string

The task status.

Enumeration

  • PENDING

  • RUNNING

  • SUCCEEDED

  • FAILED

  • CANCELED

  • UNKNOWN

Status transitions during polling:

  • PENDING (In queue) → RUNNING (Processing) → SUCCEEDED (Successful) or FAILED (Failed).

  • The status of the first query is usually PENDING (In queue) or RUNNING (Processing).

  • If the status changes to SUCCEEDED, the response contains the generated video URL.

  • If the status is FAILED, check the error message and retry.

submit_time string

The time when the task was submitted. The format is YYYY-MM-DD HH:mm:ss.SSS.

scheduled_time string

The time when the task started running. The format is YYYY-MM-DD HH:mm:ss.SSS.

end_time string

The time when the task was completed. The format is YYYY-MM-DD HH:mm:ss.SSS.

video_url string

The video URL. This parameter is returned only if task_status is SUCCEEDED.

The link is valid for 24 hours. You can use this URL to download the video. The video is in MP4 format with H.264 encoding.

orig_prompt string

The original input prompt. This corresponds to the prompt request parameter.

actual_prompt string

If prompt rewriting is enabled, this parameter returns the actual optimized prompt that is used. If this feature is disabled, this parameter is not returned.

code string

The error code for a failed request. This parameter is not returned if the request is successful. For more information, see Error messages.

message string

The detailed information about a failed request. This parameter is not returned if the request is successful. For more information, see Error messages.

usage object

The statistics for the output. Only successful tasks are counted.

Properties

video_duration integer

The duration of the generated video in seconds. The enumeration value is 5. Billing formula: Cost = Video seconds × Unit price.

video_count integer

The number of generated videos. The value is fixed at 1.

video_ratio string

This value is currently returned only by the 2.1 model. The aspect ratio of the generated video. The value is fixed at standard.

SR integer

This value is currently returned only by the 2.2 model. The resolution level of the generated video. The enumeration values are 480, 720, and 1080.

request_id string

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.

Note

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.

Note

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_status of SUCCEEDED and 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.