All Products
Search
Document Center

Alibaba Cloud Model Studio:EMO video generation API reference

Last Updated:Nov 10, 2025

The EMO model generates animated videos of faces using portrait images and voice audio.

Important

This document applies only to the China (Beijing) region. To use the model, you must use an API key from the China (Beijing) region.

Performance showcase

Sample input

Sample output

Portrait:

上春山

Voice audio:

Action style strength: The style_level parameter is set to 'active'.

For more examples, see Performance showcase.

Note

Ensure that all uploaded images and audio files are from a legally compliant source and that you have the necessary permissions for their use.

Prerequisites

HTTP

Step 1: Create a task and get a task ID

POST https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis
Note
  • After you create the task, the system immediately returns a task_id. You can use this ID in Step 2 to query the task result. The task_id is valid for 24 hours after it is created.

Request parameters

curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis' \
--header 'X-DashScope-Async: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "model": "emo-v1",
    "input": {
        "image_url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250911/yhdvfg/emo-image.png",
        "audio_url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250825/aejgyj/input_audio.mp3",
        "face_bbox":[302,286,610,593],
        "ext_bbox":[71,9,840,778]
        },
    "parameters": {
        "style_level": "normal"
        }
    }'
import requests
import os

# 1. Get the API key from the environment variable.
api_key = os.getenv("DASHSCOPE_API_KEY")

# 2. Prepare the request information.
url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis'

headers = {
    'X-DashScope-Async': 'enable',
    'Authorization': f'Bearer {api_key}',
}

payload = {
    "model": "emo-v1",
    "input": {
        "image_url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250911/yhdvfg/emo-image.png",
        "audio_url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250825/aejgyj/input_audio.mp3",
        "face_bbox": [302, 286, 610, 593],
        "ext_bbox": [71, 9, 840, 778]
    },
    "parameters": {
        "style_level": "normal"
    }
}

# 3. Send a POST request.
#    Using the 'json' parameter, requests automatically handles JSON serialization and the 'Content-Type' header.
response = requests.post(url, headers=headers, json=payload)

# 4. Print the original JSON response from the server.
#    If the request is successful, it prints the task ID and other information.
#    If the request fails, it prints the error message returned by the server.
print(response.json())
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
/**
 * Requirements:
 * - Java 8 or later.
 * - The DASHSCOPE_API_KEY environment variable must be set at runtime.
 **/
public class DashScopeApiDemo {

    public static void main(String[] args) throws IOException {
        // 1. Get the API key from the environment variable.
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        // 2. Prepare the request information.
        String urlString = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis";
        String payload = "{"
                + "\"model\": \"emo-v1\","
                + "\"input\": {"
                +     "\"image_url\": \"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250911/yhdvfg/emo-image.png\","
                +     "\"audio_url\": \"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250825/aejgyj/input_audio.mp3\","
                +     "\"face_bbox\": [302, 286, 610, 593],"
                +     "\"ext_bbox\": [71, 9, 840, 778]"
                + "},"
                + "\"parameters\": {"
                +     "\"style_level\": \"normal\""
                + "}"
                + "}";
        // 3. Send a POST request.
        URL url = new URL(urlString);
        // noinspection StartSSRFNetHookCheckingInspection
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Authorization", "Bearer " + apiKey);
        connection.setRequestProperty("X-DashScope-Async", "enable");
        connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        connection.setRequestProperty("Accept", "application/json");
        connection.setDoOutput(true);
        // Get the output stream and write the request body data.
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = payload.getBytes(StandardCharsets.UTF_8);
            os.write(input, 0, input.length);
        }
        // 4. Get and print the server response.
        int statusCode = connection.getResponseCode();
        System.out.println("Status Code: " + statusCode);
        // Select the input stream (normal or error stream) based on the status code.
        InputStream inputStream = (statusCode >= 200 && statusCode < 300)
                ? connection.getInputStream()
                : connection.getErrorStream();
        String responseBody;
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
            responseBody = reader.lines().collect(Collectors.joining("\n"));
        }
        System.out.println("Response Body: " + responseBody);
        connection.disconnect();
    }
}
// The node-fetch package is required.
// npm install node-fetch@2

// Import the node-fetch library.
const fetch = require('node-fetch');
// 1. Get the API key from the environment variable.
const apiKey = process.env.DASHSCOPE_API_KEY;
// 2. Prepare the request information.
const url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis';

const headers = {
    'X-DashScope-Async': 'enable',
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json' // This must be specified when using fetch.
};

const payload = {
    "model": "emo-v1",
    "input": {
        "image_url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250911/yhdvfg/emo-image.png",
        "audio_url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250825/aejgyj/input_audio.mp3",
        "face_bbox": [302, 286, 610, 593],
        "ext_bbox": [71, 9, 840, 778]
    },
    "parameters": {
        "style_level": "normal"
    }
};

// 3. Send a POST request and process the response.
fetch(url, {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(payload) // The JavaScript object must be converted to a JSON string.
})
.then(response => response.json()) // Parse the response body as JSON.
.then(data => {
    // 4. Print the JSON data returned by the server.
    console.log(data);
});
Headers

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.

Authorization string (Required)

This header is used for identity authentication. The API authenticates requests using a Model Studio API key. Example: Bearer sk-xxxx.

Content-Type string (Required)

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

Request Body

model string (Required)

The model name. Example: emo-v1.

input object (Required)

Specifies the basic input information.

Properties

image_url string (Required)

The URL of the uploaded image. The model crops the original image based on the ext_bbox parameter returned by the EMO image detection API. The aspect ratio of the cropped area directly determines the aspect ratio and resolution of the output video.

  • If the aspect ratio of `ext_bbox` is 1:1, a 512 × 512 profile picture video is generated. If the aspect ratio is 3:4, a 512 × 704 half-body portrait video is generated.

  • The minimum side length of the image must be at least 400 pixels. The maximum side length cannot exceed 7,000 pixels.

  • Supported formats: JPG, JPEG, PNG, BMP, and WebP.

  • Example: https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250911/yhdvfg/emo-image.png.

  • You can upload files using HTTP or HTTPS links. Local file paths are not supported.

audio_url string (Required)

The URL of the uploaded audio file. This audio file is used as the input for EMO model inference.

  • The audio must contain a clear human voice. For best results, remove background noise, background music, and other interference.

  • The file size must be 15 MB or less. The duration must be 60 s or less.

  • Supported formats: WAV and MP3.

  • Example: https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250825/aejgyj/input_audio.mp3.

  • You can upload files using HTTP or HTTPS links. Local file paths are not supported.

face_bbox array (Required)

The pixel coordinates of the bounding box (bbox) for the face area in the image. You can obtain this value from the `face_bbox` field in the response of the EMO image detection API. The coordinate format is `[x1, y1, x2, y2]`, which represents the coordinates of the top-left and bottom-right points. Example: `[302,286,610,593]`.

The top-left corner of the image is the origin (0,0). The x-axis extends to the right, and the y-axis extends downward.

ext_bbox array (Required)

The pixel coordinates of the bounding box (bbox) for the dynamic area. You can obtain this value from the `ext_bbox` field in the response of the EMO image detection API. The aspect ratio of this area is 1:1 or 3:4. The coordinate format is `[x1, y1, x2, y2]`, which represents the coordinates of the top-left and bottom-right points. Example: `[71, 9, 840, 778]`.

parameters object (Optional)

Properties

style_level string (Optional) Default value: normal

Controls the character's motion and amplitude. Three styles are supported: `normal` for moderate motion, `calm` for calm motion, and `active` for active motion. The default value is `normal`.

Response parameters

Sample success response

{
    "output": {
        "task_id": "a8532587-fa8c-4ef8-82be-xxxxxx", 
        "task_status": "PENDING"
    },
    "request_id": "7574ee8f-38a3-4b1e-9280-11c33ab46e51"
}

Sample error response

{
    "request_id":"4d687387-580a-4b49-a1f8-4691289e09a3",
    "code":"InvalidParameter",
    "message":"The request is missing required parameters or in a wrong format, please check the parameters that you send.."
}

output object

Contains the task output information.

Properties

task_id string

The ID of the submitted asynchronous task. The actual task result must be retrieved using the asynchronous task query API. Example: a8532587-fa8c-4ef8-82be-xxxxxx.

task_status string

The status of the task after it is submitted. Example: "PENDING".

request_id string

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

code string

The error code returned when the request fails. For more information, see Error codes.

message string

The detailed error message returned when the request fails. For more information, see Error codes.

Step 2: Query the result based on the task ID

Use the task_id from the previous step to poll for the task status and result. Replace {task_id} in the URL with your actual task ID.

GET https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}
Note
  • `task_id` validity: The ID is valid for 24 hours after it is created. After this period, you can no longer query the result. The API returns a task status of UNKNOWN.

  • Task status flow: A task that is processed normally transitions through the following statuses: `PENDING`, `RUNNING`, and `SUCCEEDED` or `FAILED`.

  • Result retrieval: Video generation takes several minutes. The query API has a default limit of 20 QPS. Use a polling mechanism with a reasonable query interval, such as 15 seconds, to retrieve the result.

  • video_url validity: After the task succeeds, the URL is valid for 24 hours. You must download the video and transfer it to permanent storage immediately after you retrieve the link (such as Object Storage Service (OSS)).

Request parameters

curl -X GET \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}
import requests
import os

# 1. Get the API key from the environment variable.
api_key = os.getenv("DASHSCOPE_API_KEY")

# 2. Replace this with the actual ID of the task you want to query.
task_id = "a8532587-fa8c-4ef8-82be-xxxxxx"

# 3. Prepare the request information.
# Use an f-string to append the task_id to the URL.
url = f"https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}"

headers = {
    'Authorization': f'Bearer {api_key}'
}

# 4. Send a GET request.
response = requests.get(url, headers=headers)

# 5. Print the JSON response from the server.
# This displays the task status (such as "RUNNING", "SUCCEEDED", or "FAILED") and the result.
print(response.json())
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
/**
 * Requirements:
 * - Java 8 or later.
 * - The DASHSCOPE_API_KEY environment variable must be set at runtime.
 **/
public class TaskStatusChecker {

    public static void main(String[] args) throws IOException {
        // 1. Get the API key from the environment variable.
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        // 2. Replace this with the actual ID of the task you want to query.
        String taskId = "a8532587-fa8c-4ef8-82be-xxxxxx"; // Replace this with your task ID.
        // 3. Prepare the request information (dynamically construct the URL).
        String urlString = "https://dashscope.aliyuncs.com/api/v1/tasks/" + taskId;
        // 4. Create a connection and send a GET request.
        URL url = new URL(urlString);
        // noinspection StartSSRFNetHookCheckingInspection
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        // Set the request headers.
        connection.setRequestProperty("Authorization", "Bearer " + apiKey);
        // 5. Get and print the server response.
        int statusCode = connection.getResponseCode();
        System.out.println("Status Code: " + statusCode);
        InputStream inputStream = (statusCode >= 200 && statusCode < 300)
                ? connection.getInputStream()
                : connection.getErrorStream();
        String responseBody;
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
            responseBody = reader.lines().collect(Collectors.joining("\n"));
        }
        System.out.println("Response Body: " + responseBody);
        connection.disconnect();
    }
}
// The node-fetch package is required.
// npm install node-fetch@2

// Import the node-fetch library.
const fetch = require('node-fetch');
// 1. Get the API key from the environment variable.
const apiKey = process.env.DASHSCOPE_API_KEY;
// 2. Replace this with the actual ID of the task you want to query.
const taskId = "a8532587-fa8c-4ef8-82be-xxxxxx"; // <-- Replace this with your task ID.
// 3. Prepare the request information.
// Use a template literal to append the taskId to the URL. This is similar to an f-string in Python.
const url = `https://dashscope.aliyuncs.com/api/v1/tasks/${taskId}`;

const headers = {
    'Authorization': `Bearer ${apiKey}`
};

// 4. Send a GET request.
// The default request method for fetch is GET, so you can omit method: 'GET'.
fetch(url, {
    headers: headers
})
.then(response => response.json()) // Parse the response body as JSON.
.then(data => {
    // 5. Print the JSON response from the server.
    // This displays the task status (such as "RUNNING" or "SUCCEEDED") and the result.
    console.log(data);
});

Headers

Authorization string (Required)

Used for request identity authentication. The API uses Model Studio API key for authentication. Example: Bearer sk-xxxx.

URL path parameters

task_id string (Required)

The `task_id` of the task to query. Example: a8532587-fa8c-4ef8-82be-xxxxxx.

Response parameters

Sample success response

{
    "request_id": "8190395f-ca1b-4703-9656-xxxxxx",
    "output": {
        "task_id": "a8532587-fa8c-4ef8-82be-xxxxxx",
        "task_status": "SUCCEEDED",
        "submit_time": "2025-09-11 14:33:38.716",
        "scheduled_time": "2025-09-11 14:33:53.089",
        "end_time": "2025-09-11 14:35:51.541",
        "results": {
            "video_url": "http://dashscope-result-sh.oss-cn-shanghai.aliyuncs.com/xxx.mp4?Expires=xxxx"
        }
    },
    "usage": {
        "video_duration": 13.93,
        "video_ratio": "1:1"
    }
}

Sample error response

{
    "output": {
        "task_id": "a8532587-fa8c-4ef8-82be-xxxxxx", 
        "task_status": "FAILED",
        "code": "InvalidURL", 
        "message": "Required URL is missing or invalid, please check the request URL." 
    },
    "request_id": "4d687387-580a-4b49-a1f8-4691289e09a3" 
}

request_id string

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

output object

Contains the task output information.

Properties

task_id string

The `task_id` of the queried task. Example: a8532587-fa8c-4ef8-82be-xxxxxx.

task_status string

The task status.

Enumeration

  • PENDING

  • RUNNING

  • SUCCEEDED

  • FAILED

  • CANCELED

  • UNKNOWN

submit_time string

The time when the task was submitted. The time zone is UTC+8. Example: 2025-09-11 14:33:38.716.

scheduled_time string

The time when the task was scheduled to start. The time zone is UTC+8. Example: 2025-09-11 14:33:53.089.

end_time string

The time when the task finished. The time zone is UTC+8. Example: 2025-09-11 14:35:51.541.

results object

The task execution result.

Properties

video_url string

The URL of the video result that is generated by the platform. The `video_url` is valid for 24 hours after the task is completed. You must download and save the video file promptly. Example: http://dashscope-result-sh.oss-cn-shanghai.aliyuncs.com/xxx.mp4?Expires=xxxx.

code string

The error code returned when the request fails. For more information, see Error codes.

message string

The detailed error message returned when the request fails. For more information, see Error codes.

usage object

Properties

video_duration float

The duration of the video generated by this request, in seconds. Example: 13.93.

video_ratio string

The aspect ratio of the video generated by this request. The value is 1:1 or 3:4.

Billing and rate limits

Model

Unit price

Task submission QPS limit

Concurrent tasks

emo-v1

Pay-as-you-go. You are charged based on the actual duration of the output video:

  • 1:1 aspect ratio video: USD 0.011469 per second

  • 3:4 aspect ratio video: USD 0.022937 per second

5

1

(Excess tasks are queued.)

Error codes

For common status codes, see Error messages.

This model also has the following specific error codes:

HTTP return code

Code

Message

Description

400

InvalidParameter

The request is missing required parameters or in a wrong format, please check the parameters that you send.

The format of the input parameters is incorrect.

400

InvalidParameter

The style_level is invalid.

The value of `style_level` is not within the enumeration range.

400

InvalidParameter.DataInspection

Unable to download the media resource during the data inspection process. 

A timeout occurred when the system downloaded the image or audio file.

If you make a call from outside China, a resource download timeout may occur because of unstable cross-border networks. You can store the file in OSS in China and then call the model. You can also use the temporary storage space to upload files.

400

InvalidURL

The request URL is invalid, please check the request URL is available and the request image format is one of the following types: JPEG, JPG, PNG, BMP, and WEBP.

Failed to download the input image. Check the network or the input format. The following formats are supported: JPEG, JPG, PNG, BMP, and WEBP.

400

InvalidURL

Required URL is missing or invalid, please check the request URL.

The input URL is incorrect or missing.

400

InvalidURL

The input audio is longer than 60s!

The input audio file exceeds the maximum duration of 60 seconds.

400

InvalidURL

File size is larger than 15MB.

The input audio file exceeds the maximum size of 15 MB.

400

InvalidURL

File type is not supported. Allowed types are: .wav, .mp3.

The format of the input audio is invalid. The supported formats are WAV and MP3.

400

InvalidFile.Content

The input image has no human body. Please upload other image with single person.

No person is found in the input image. Upload an image that contains a person.

400

InvalidFile.Content

The input image has multi human bodies. Please upload other image with single person.

Multiple people are found in the input image. Upload an image that contains only one person.

400

InvalidFile.BodyProportion

The proportion of the detected person in the picture is too large or too small, please upload other image.

The proportion of the person in the input image does not meet the requirements.

400

InvalidFile.Resolution

The image resolution is invalid, please make sure that the largest length of image is smaller than 7000, and the smallest length of image is larger than 400.

The image resolution is invalid. The minimum side length must be at least 400 pixels, and the maximum side length must not exceed 7,000 pixels.

400

InvalidFile.Value

The value of the image is invalid, please upload other clearer image.

The input image is too dark and does not meet the requirements. Upload a clearer image.

400

InvalidFile.FrontBody

The pose of the detected person is invalid, please upload other image with the front view.

The person in the uploaded image is facing away from the camera, which does not meet the requirements. Upload an image with a front view of the person.

400

InvalidFile.FullFace

The pose of the detected face is invalid, please upload other image with whole face.

The facial pose of the person in the uploaded image does not meet the requirements. Upload an image where the face is visible.

400

InvalidFile.FacePose

The pose of the detected face is invalid, please upload other image with the expected orientation.

The facial pose of the person in the uploaded image does not meet the requirements. Upload an image where the face does not have a severe orientation offset.