All Products
Search
Document Center

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

Last Updated:Nov 26, 2025

The Wan first-and-last-frame-to-video model generates a smooth transition video based on a first frame image, a last frame image, and a text prompt. The supported features include the following:

  • Video specifications: The video duration is fixed at 5 seconds, and the video resolution is fixed at 720P.

  • Intelligent prompt optimization: This feature automatically rewrites input prompts, which significantly improves the results for short prompts.

  • Other: You can choose whether to add an "AI Generated" watermark.

Quick links: Try it online on the Wan official website

Note

The features on the Wan official website may differ from the capabilities supported by the API. This document describes the actual capabilities of the API and will be updated as new features are released.

Model overview

Feature

Input example

Output video

First frame image

Last frame image

Prompt

Video generation from first and last frames

first_frame

last_frame

Realistic style, a black kitten looks up at the sky curiously. The camera starts at eye level, gradually rises, and ends with a top-down shot of its curious eyes.

Model name

Model description

Output video format

wan2.1-kf2v-plus

Wan 2.1 Professional Edition (silent video)

Complex motion, realistic physics, and detailed images.

Resolution options: 720P

Video duration: 5 seconds

Fixed specifications: 30 fps, MP4 (H.264 encoding)

Note

Before you make a call, check the model list and pricing for 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 take a long time to process (typically 1 to 5 minutes), the API uses asynchronous invocation. The entire process involves two core steps: Create a task -> Poll for the result.

The specific time required depends on the number of tasks in the queue and the service execution status. 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

Video generation from first and last frames

Generate a video based on the first frame, last frame, and 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.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 starts at eye level, gradually rises, and ends with a top-down shot of its curious eyes."
    },
    "parameters": {
        "resolution": "480P",
        "prompt_extend": true
    }
}'

Use a negative prompt

You can 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 starts at eye level, gradually rises, and ends with a top-down shot of its curious eyes.",
        "negative_prompt": "person"
    },
    "parameters": {
        "resolution": "720P",
        "prompt_extend": true
    }
}'
Request 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. This parameter supports Chinese and English. The length cannot exceed 800 characters. Each Chinese character or letter counts as one character. Any excess characters are automatically truncated.

If the subject and scene change significantly between the first and last frames, you should 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 captures a top-down shot of its curious eyes.

For more information, see Text-to-video/Image-to-video prompt guide.

negative_prompt string (Optional)

The negative prompt. You can use this parameter to describe content that you do not want to appear in the video. It can be used to constrain the video content.

This parameter supports Chinese and English. The length cannot exceed 500 characters. Any excess characters are automatically truncated.

Example: low resolution, error, worst quality, low quality, deformed, extra fingers, or bad proportions.

first_frame_url string (Required)

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

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

Image requirements:

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

  • Image resolution: The width and height of the image must be between 360 and 2000 pixels.

  • File size: Cannot exceed 10 MB.

last_frame_url string (Required)

The URL of the last frame image.

The URL must be a public endpoint that supports the HTTP or HTTPS protocol.

Image requirements:

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

  • Image resolution: The width and height of the image must be between 360 and 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: Cannot exceed 10 MB.

parameters object (Optional)

Video processing parameters.

Properties

resolution string (Optional)

Important

The resolution directly affects the cost. For the same model, a higher resolution is more expensive (1080P > 720P > 480P), so you should confirm the model pricing before you make a call.

The resolution level of the generated video. This parameter adjusts only the video's definition (total pixels) and does not change the aspect ratio. The video aspect ratio remains consistent with 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 described below:

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

Example: 720P.

duration integer (Optional)

Important

The duration directly affects the cost, and you are billed per second. Before you invoke the model, you should confirm the model pricing.

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

prompt_extend bool (Optional)

Specifies whether to enable prompt rewriting. When this feature is enabled, a large language model is used to rewrite the input prompt. This significantly improves results for shorter prompts but increases the processing time.

  • true (default)

  • false

Example: true.

watermark bool (Optional)

Specifies whether to add a watermark. The watermark is located in the lower-right corner of the video, saying "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 generation results, you can fix the seed value.

Note that because of the probabilistic nature of model generation, using the same seed does not guarantee that the results will be 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

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 → RUNNING → SUCCEEDED or 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 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 result

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

The API keys for the Singapore and Beijing regions are different. Create an API key.
The following `base_url` is for the Singapore region. For models in the Beijing region, replace the `base_url` with `https://dashscope.aliyuncs.com/api/v1/tasks/86ecf553-d340-4e21-xxxxxxxxx`.
curl -X GET https://dashscope-intl.aliyuncs.com/api/v1/tasks/86ecf553-d340-4e21-xxxxxxxxx \
--header "Authorization: Bearer $DASHSCOPE_API_KEY"
Request 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 executed successfully

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 starts at eye level, gradually rises, and ends with a top-down shot of its curious eyes.",
        "actual_prompt": "Realistic style, a black kitten looks up at the sky curiously. The camera starts at eye level, gradually rises, and ends with a top-down shot of its curious eyes. its yellow eyes are bright and expressive, its fur is smooth, and its whiskers are clearly visible. The background is a simple light-colored wall, highlighting its black silhouette. Close-up shot, emphasizing the change in its expression and the details of its eyes."
    },
    "usage": {
        "video_duration": 5,
        "video_count": 1,
        "SR": 480
    }
}

Task execution 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

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 → RUNNING → SUCCEEDED or FAILED.

  • The status of the first query is usually PENDING or RUNNING.

  • 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 time is in the UTC+8 time zone. The format is YYYY-MM-DD HH:mm:ss.SSS.

scheduled_time string

The time when the task started running. The time is in the UTC+8 time zone. The format is YYYY-MM-DD HH:mm:ss.SSS.

end_time string

The time when the task was completed. The time is in the UTC+8 time zone. 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 on the output information. Only successful results 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. This value is fixed at 1.

video_ratio string

Currently, only the 2.1 model returns this value. The aspect ratio of the generated video is fixed at standard.

SR integer

Currently, only the 2.2 model returns this value. 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 SDK's parameter names are mostly consistent with those of the HTTP API, and the parameter structure is encapsulated according to language-specific features.

Because image-to-video tasks take a long time to process (typically 1 to 5 minutes), the SDK encapsulates the HTTP asynchronous invocation process at the underlying layer and supports both synchronous and asynchronous invocation methods.

The specific time required depends on the number of tasks in the queue and the service execution status. Please be patient while you wait 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 Images.

Note

We recommend that you install the latest version of the DashScope Python SDK. Otherwise, you may encounter runtime errors: Install or upgrade the SDK.

Synchronous invocation

This example shows the synchronous invocation method, which includes two image input methods: a public URL and a local file path.

Request example
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 from environment variables (i.e., the Alibaba Cloud Model Studio API key)
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"              # Based on the actual path
# last_frame_url = "file://" + "./last_frame.png"                # Based on the actual path

def sample_sync_call_kf2v():
    print('please wait...')
    rsp = VideoSynthesis.call(api_key=api_key,
                              model="wan2.1-kf2v-plus",
                              prompt="Realistic style, a black kitten looks up at the sky curiously. The camera starts at eye level, gradually rises, and ends with a top-down shot of its 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()
Response example
The video_url is valid for 24 hours. You should 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 starts at eye level, gradually rises, and ends with a top-down shot of its curious eyes.",
        "actual_prompt": "Realistic style, a black kitten looks up at the sky curiously. The camera starts at eye level, gradually rises, and ends with a top-down shot of its curious eyes. its yellow eyes are bright and expressive, its ears are pricked, and its whiskers are clearly visible. The background is a simple light-colored wall, highlighting its black fur and focused expression. Close-up shot, emphasizing the change in its gaze and posture."
    },
    "usage": {
        "video_count": 1,
        "video_duration": 5,
        "video_ratio": "standard"
    }
}

Asynchronous invocation

This example shows the asynchronous invocation method. This method immediately returns a task ID, and you need to poll for or wait for the task to complete on your own.

Request example
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 from environment variables (i.e., the Alibaba Cloud Model Studio API key)
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"              # Based on the actual path
# last_frame_url = "file://" + "./last_frame.png"                # Based on 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 starts at eye level, gradually rises, and ends with a top-down shot of its 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(task=rsp, api_key=api_key)
    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(task=rsp, api_key=api_key)
    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()
Response example

1. Response example 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. Response example for querying a task result

The video_url is valid for 24 hours. You should 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 starts at eye level, gradually rises, and ends with a top-down shot of its curious eyes.",
        "actual_prompt": "Realistic style, a black kitten looks up at the sky curiously. The camera starts at eye level, gradually rises, and ends with a top-down shot of its curious eyes. its fur is jet black and shiny, its eyes are large and bright with golden pupils. It looks up with its ears pricked, appearing exceptionally focused. After the camera moves up, the kitten turns to look directly at the camera, its eyes full of curiosity and alertness. The background is simple, highlighting its detailed features. 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 images.

Note

We recommend that you install the latest version of the DashScope Java SDK. Otherwise, a runtime error may occur: Install or upgrade the SDK.

Synchronous invocation

This example shows the synchronous invocation method, which includes two image input methods: a public URL and a local file path.

Request example
// 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 from environment variables (i.e., the Alibaba Cloud Model Studio API key)
    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-plus")
                        .prompt("Realistic style, a black kitten looks up at the sky curiously. The camera starts at eye level, gradually rises, and ends with a top-down shot of its 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();
    }
}
Response example
The video_url is valid for 24 hours. You should 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 invocation

This example shows the asynchronous invocation method. This method immediately returns a task ID, and you need to poll for or wait for the task to complete on your own.

Request example
// 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 from environment variables (i.e., the Alibaba Cloud Model Studio API key)
    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 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-plus")
                        .prompt("Realistic style, a black kitten looks up at the sky curiously. The camera starts at eye level, gradually rises, and ends with a top-down shot of its 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();
    }
}
Response example

1. Response example for creating a task

{
    "request_id": "5dbf9dc5-4f4c-9605-85ea-xxxxxxxx",
    "output": {
        "task_id": "7277e20e-aa01-4709-xxxxxxxx",
        "task_status": "PENDING"
    }
}

2. Response example for querying a task result

The video_url is valid for 24 hours. You should 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"
    }
}

Limitations

  • Data validity: The task_id and video URL are retained for only 24 hours. After this period, they cannot be queried or downloaded.

  • Audio support: This feature supports generating silent videos only. Audio output is not supported. To add audio, you can generate it using speech synthesis.

  • Content moderation: The input prompt, input image, and output video are subject to content moderation. If the content is non-compliant, an "IPInfringementSuspect" or "DataInspectionFailed" error is returned. For more information, see Error messages.

Key parameter descriptions

Input image

The input image parameters first_frame_url and last_frame_url both support the following input methods:

Method 1: Public URL

  • A publicly accessible URL that supports the HTTP or HTTPS protocol.

  • Example: https://example.com/images/cat.png.

Method 2: Local file path (SDK only)

  • Python SDK: Supports passing the absolute and relative paths of the file. The file path rules are as follows:

    System

    Passed file path

    Example (absolute path)

    Example (relative path)

    Linux or macOS

    file://{absolute or relative path of the file}

    file:///home/images/test.png

    file://./images/test.png

    Windows

    file://D:/images/test.png

    file://./images/test.png

  • Java SDK: Only supports passing the absolute path of the file. The file path rules are as follows:

    System

    Passed file path

    Example (absolute path)

    Linux or macOS

    file://{absolute path of the file}

    file:///home/images/test.png

    Windows

    file:///{absolute path of the file}

    file:///D:/images/test.png

Billing and rate limiting

  • For free quotas and pricing, see Models.

  • For rate limits, see Wan series.

  • Billing description:

    • Billing is based on the number of seconds of a successfully generated video. You are charged only when the query result API returns a task_status of SUCCEEDED and a video is successfully generated.

    • Failed model calls or processing errors do not incur fees or consume the free quota.

Error codes

If a model call fails and returns an error message, see Error messages to resolve the issue.

FAQ

Video FAQ quick link: FAQ.

Q: How do I 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.