AI Meme Generator
Description
This API generates AI memes in the cloud.
Version
1.0
Media Requirements
Video requirements:
- Format: MP4
- File size: Less than 3 GB
- A video featuring one real person, with the head area clearly visible, similar to the demo video
- Minimize shoulder movement whenever possible
- The first frame of the driving video should show a front-facing subject with a neutral expression
Image requirements:
- Formats: JPG, PNG
- File size: Less than 10 MB
The generated output dimensions depend solely on the input image dimensions. In image mode, the image is resized so that its longest side is 4096 pixels, and the returned image has a longest side of 4096 pixels. In video mode, the image is resized so that its longest side is 2048 pixels, and the returned video has a longest side of 2048 pixels.
API URL
Production environment: https://openapi.meitu.com
Task submission endpoint: https://openapi.meitu.com/api/v1/sdk/sync/push
Task name (task): /v1/AI_Emoji_Pack/487155
Task type (task_type): formulaMethod
POST
Content-Type: application/json
Authentication
Request Parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | params | string | Algorithm parameters (JSON string) |
| Yes | init_images | object[] | Media file list; pass the image first, followed by the driving video |
| Yes | task | string | Fixed value: /v1/AI_Emoji_Pack/487155 |
| Yes | task_type | string | Fixed value: formula |
| No | sync_timeout | int | Defaults to 30; synchronous timeout duration |
The structure of each media file object in init_images is described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | url | string | Image or video URL; Base64 data of the corresponding media type is also supported |
| Yes | profile | object | Media attribute information |
The structure of profile is described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_profiles | object | Media attribute information |
| Yes | version | string | Fixed value: v1 |
The structure of media_profiles is described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_data_type | string | url indicates a URL; a corresponding Base64 type such as jpg indicates Base64 data |
The params inference parameter is a JSON string with the following structure.
| Required | Field | Type | Description |
|---|---|---|---|
| No | rsp_media_type | string | Output media type. Defaults to url; jpg returns the generated image as Base64-encoded data, while url returns a URL |
| Yes | parameter | object | Core algorithm parameters |
Details of the algorithm parameters in parameter:
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | media_mode | int | Output media type: 0 returns an image and 1 returns a video. Default: 1 |
| No | animal_flag | int | Subject mode: 0 for a person and 1 for a cat or dog. Default: 0 |
Request Example
{
"task": "/v1/AI_Emoji_Pack/487155",
"task_type": "formula",
"init_images": [
{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTcyMTM2NTIwMA==/d8434efb-97c1-4b7f-7124-a04e1e80b3f0.jpeg",
"profile": {
"media_profiles": {
"media_data_type": "url"
},
"version": "v1"
}
},
{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTcyMTgxNTIwMA==/61c8c16f-018d-4c17-6270-d8fe6c2dce62.mp4",
"profile": {
"media_profiles": {
"media_data_type": "url"
},
"version": "v1"
}
}
],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"media_mode\":1,\"animal_flag\":0}}",
"sync_timeout": 30
}Response Fields
Generated results are periodically deleted. Download and save them promptly.| Field | Type | Description |
|---|---|---|
| request_id | string | Request identifier |
| trace_id | string | Distributed tracing identifier |
| code | int | Business status code; 0 means the request was accepted successfully |
| error_code | int | Error code; 0 on success |
| message | string | Business status message |
| tips | any | Additional information; may be null |
| data | object | Task status and algorithm result |
Fields in data:
| Field | Type | Description |
|---|---|---|
| status | int | Status code: -1 task not found; 0 created; 1 processing; 2 failed; 9 timed out—use the Query API; 10 succeeded |
| result | object | Algorithm result |
| progress | number | Task progress in the range 0–1; 1 indicates completion |
| predict_elapsed | int | Estimated processing time in milliseconds |
| create_time | int64 | Creation timestamp in milliseconds |
| task_id | string | Task ID |
| custom_task_id | string | Client-defined task ID |
| trace_id | string | Tracing identifier within data |
| client_info | string | Client information |
| init_images | object[]/null | Echo of the input media |
Fields in result:
| Field | Type | Description |
|---|---|---|
| id | string | Unique task identifier |
| urls | array | List of output media URLs |
| images | array | Output media list; equivalent to urls |
| parameters | object | Output parameter information |
| data | object | Detailed algorithm response data |
| msg | string | Response message |
| msg_id | string | Message ID |
| mtlab_res | object | Underlying algorithm result |
| media_info_list | array | Output media information list |
| error_code | int | Algorithm error code on failure; 20001 indicates a processing error |
| error_msg | string | Algorithm error message on failure; PROCESS_ERROR indicates a processing error |
Fields in result.parameters:
| Field | Type | Description |
|---|---|---|
| rsp_media_type | string | Output media type; url indicates that media URLs are returned |
| total_spend | string | Total task duration in milliseconds |
| version | string | Algorithm version |
Fields in result.data:
| Field | Type | Description |
|---|---|---|
| duration | object | Timing statistics for each processing stage |
| error_code | number | Algorithm error code; 0 indicates success |
| error_msg | string | Algorithm error message |
| extra | object | Additional fields |
| media_info_list | array | Media information list |
| msg_id | string | Message ID |
| parameter | object | Echo of the parameters |
Fields in duration:
| Field | Type | Description |
|---|---|---|
| alg_process_time | number | Algorithm processing time in milliseconds |
| created_timestamp | number | Task creation timestamp in seconds |
| pull_timestamp | number | Media retrieval timestamp in seconds |
| repost_time | number | Retry duration |
| upload_time | number | Upload duration in milliseconds |
| waiting_time | number | Queue wait time in milliseconds |
Fields in media_info_list:
| Field | Type | Description |
|---|---|---|
| media_data | string | Media data URL |
| media_extra | object | Additional media information |
| media_profiles | object | Media attribute information |
Fields in media_profiles:
| Field | Type | Description |
|---|---|---|
| media_data_type | string | Media data type; url indicates that the media data is a URL |
| media_data_width | number | Media width in pixels |
| media_data_height | number | Media height in pixels |
| media_data_fps | number | Video frame rate |
| media_data_size | number | Media file size in bytes |
Fields in mtlab_res:
| Field | Type | Description |
|---|---|---|
| ErrorCode | number | Underlying error code |
| ErrorMsg | string | Underlying error message |
| error_code | number | Backward-compatible error code field |
| error_msg | string | Backward-compatible error message field |
| media_info_list | array | Media information list |
| msg_id | string | Message ID |
| parameter | object | Parameter information |
Response Examples
Successful Response Example
{
"request_id": "",
"trace_id": "",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 10,
"result": {
"id": "t_mt1a3i5n7b3541aa08-xxxx-4cd2-9026-d1d03105afdb",
"urls": [
"https://obs-large.mtlab.meitu.com/mtopen/ff56d688358849259556be0f50065a60/123bd631-3f77-46ac-630e-6fb073979aa5.mp4"
],
"parameters": {
"rsp_media_type": "url",
"total_spend": "18357.871",
"version": "1.0.2-beta19"
},
"data": {
"duration": {
"alg_process_time": 18521,
"created_timestamp": 1770279407,
"pull_timestamp": 1770279407,
"repost_time": 0,
"upload_time": 1517,
"waiting_time": 176
},
"error_code": 0,
"error_msg": "success",
"extra": {},
"media_info_list": [
{
"media_data": "https://obs-large.mtlab.meitu.com/mtopen/ff56d688358849259556be0f50065a60/123bd631-3f77-46ac-630e-6fb073979aa5.mp4",
"media_extra": null,
"media_profiles": {
"media_data_fps": 30,
"media_data_height": 2048,
"media_data_size": 33299043,
"media_data_type": "url",
"media_data_width": 1536
}
}
],
"msg_id": "2ae5bd8d-0824-xxxx-70b8-r00930c732b5",
"parameter": {
"rsp_media_type": "url",
"total_spend": "18357.871",
"version": "1.0.2-beta19"
}
},
"msg": "success",
"msg_id": "2ae5bd8d-0824-xxxx-70b8-r00930c732b5",
"images": [
"https://obs-large.mtlab.meitu.com/mtopen/ff56d688358849259556be0f50065a60/123bd631-3f77-46ac-630e-6fb073979aa5.mp4"
],
"mtlab_res": {
"ErrorCode": 0,
"ErrorMsg": "",
"error_code": 0,
"error_msg": "",
"media_info_list": null,
"msg_id": "2ae5bd8d-xxxx-488a-70b8-r00930c732b5",
"parameter": null
},
"media_info_list": [
{
"media_data": "https://obs-large.mtlab.meitu.com/mtopen/ff56d688358849259556be0f50065a60/123bd631-3f77-46ac-630e-6fb073979aa5.mp4",
"media_extra": null,
"media_profiles": {
"media_data_fps": 30,
"media_data_height": 2048,
"media_data_size": 33299043,
"media_data_type": "url",
"media_data_width": 1536
}
}
]
},
"progress": 1,
"predict_elapsed": 10000,
"create_time": 1770279407088,
"task_id": "t_mt1a3i5n7b3541aa08-xxxx-4cd2-9026-d1d03105afdb",
"custom_task_id": "",
"trace_id": "",
"client_info": "",
"init_images": null
}
}Pending Response Example
Use the Query API to retrieve the result.
Response Status: 200
content-type: application/json; charset=utf-8
{
"request_id": "",
"trace_id": "",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 9,
"result": {
"id": "t_mt1a3i5n7b3541aa08-xxxx-4cd2-9026-d1d03105afdb"
},
"progress": 0,
"predict_elapsed": 10000,
"create_time": 1770279407088,
"task_id": "t_mt1a3i5n7b3541aa08-xxxx-4cd2-9026-d1d03105afdb",
"custom_task_id": "",
"trace_id": "7ebcda65-xxxx-4009-8573-ecc3555865b1",
"client_info": "",
"init_images": null
}
}Failed Response Example
Response Status: 400
content-type: application/json; charset=utf-8
{
"request_id": "",
"trace_id": "",
"code": 20001,
"error_code": 20001,
"message": "PROCESS_ERROR",
"tips": null,
"data": {
"status": 2,
"result": {
"error_code": 20001,
"error_msg": "PROCESS_ERROR"
},
"progress": 0,
"predict_elapsed": 0,
"create_time": 1770279407088,
"task_id": "t_mt1a3i5n7b3541aa08-xxxx-4cd2-9026-d1d03105afdb",
"custom_task_id": "",
"trace_id": "",
"client_info": "",
"init_images": null
}
}General Error Codes
API-specific error: 20001 (PROCESS_ERROR), which indicates a processing error.
For details, see API Error Codes.
SDK Examples
Python
import json
import requests
from sign_sdk import sign
def api_call_example():
key = "your_api_key"
secret = "your_api_secret"
url = "https://openapi.meitu.com/api/v1/sdk/sync/push"
method = "POST"
headers = {
"Content-Type": "application/json",
sign.HeaderHost: "openapi.meitu.com",
}
inner_params = {
"rsp_media_type": "url",
"parameter": {
"media_mode": 1,
"animal_flag": 0,
},
}
payload = {
"task": "/v1/AI_Emoji_Pack/487155",
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/input.jpg",
"profile": {
"media_profiles": {"media_data_type": "url"},
"version": "v1",
},
},
{
"url": "https://example.com/input.mp4",
"profile": {
"media_profiles": {"media_data_type": "url"},
"version": "v1",
},
},
],
"params": json.dumps(inner_params, ensure_ascii=False),
"sync_timeout": 30,
}
body = json.dumps(payload, ensure_ascii=False)
signer = sign.Signer(key, secret)
signed_request = signer.sign(url, method, headers, body)
response = requests.Session().send(signed_request)
print(f"Status: {response.status_code}")
print(f"Response: {response.text}")
if __name__ == "__main__":
api_call_example()Go
package main
import (
"fmt"
"io"
"net/http"
"github.com/mtlab/api/signer"
)
func main() {
key := "your_api_key"
secret := "your_api_secret"
signObj := signer.NewSigner(key, secret)
url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
method := http.MethodPost
headers := make(http.Header)
headers.Set(signer.HeaderHost, "openapi.meitu.com")
headers.Set("Content-Type", "application/json")
body := `{
"task": "/v1/AI_Emoji_Pack/487155",
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/input.jpg",
"profile": {
"media_profiles": {"media_data_type": "url"},
"version": "v1"
}
},
{
"url": "https://example.com/input.mp4",
"profile": {
"media_profiles": {"media_data_type": "url"},
"version": "v1"
}
}
],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"media_mode\":1,\"animal_flag\":0}}",
"sync_timeout": 30
}`
req, err := signObj.Sign(url, method, headers, body)
if err != nil {
fmt.Println("Failed to sign request:", err)
return
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("Failed to send request:", err)
return
}
defer resp.Body.Close()
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Read response failed:", err)
return
}
fmt.Println("Response:", resp.StatusCode, string(responseBody))
}PHP
<?php
require 'signer.php';
$key = 'your_api_key';
$secret = 'your_api_secret';
$signer = new Signer($key, $secret);
$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$method = 'POST';
$headers = ['Content-Type' => 'application/json'];
$innerParams = json_encode([
'rsp_media_type' => 'url',
'parameter' => [
'media_mode' => 1,
'animal_flag' => 0,
],
]);
$body = json_encode([
'task' => '/v1/AI_Emoji_Pack/487155',
'task_type' => 'formula',
'init_images' => [
[
'url' => 'https://example.com/input.jpg',
'profile' => [
'media_profiles' => ['media_data_type' => 'url'],
'version' => 'v1',
],
],
[
'url' => 'https://example.com/input.mp4',
'profile' => [
'media_profiles' => ['media_data_type' => 'url'],
'version' => 'v1',
],
],
],
'params' => $innerParams,
'sync_timeout' => 30,
]);
$curl = $signer->sign($url, $method, $headers, $body);
$response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status === 0) {
echo 'Error: ' . curl_error($curl);
} else {
echo "Status: {$status}\n";
echo "Response: {$response}\n";
}
curl_close($curl);
?>Java
package com.meitu.openai.common;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception {
Signer signer = new Signer("your_api_key", "your_api_secret");
String url = "https://openapi.meitu.com/api/v1/sdk/sync/push";
String method = "POST";
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put(Signer.HeaderHost, "openapi.meitu.com");
String body = "{\n" +
" \"task\": \"/v1/AI_Emoji_Pack/487155\",\n" +
" \"task_type\": \"formula\",\n" +
" \"init_images\": [\n" +
" {\n" +
" \"url\": \"https://example.com/input.jpg\",\n" +
" \"profile\": {\n" +
" \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
" \"version\": \"v1\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"url\": \"https://example.com/input.mp4\",\n" +
" \"profile\": {\n" +
" \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
" \"version\": \"v1\"\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"media_mode\\\":1,\\\"animal_flag\\\":0}}\",\n" +
" \"sync_timeout\": 30\n" +
"}";
Map<String, String> signedHeaders = signer.sign(url, method, headers, body);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod(method);
for (Map.Entry<String, String> entry : signedHeaders.entrySet()) {
connection.setRequestProperty(entry.getKey(), entry.getValue());
}
connection.setDoOutput(true);
connection.getOutputStream().write(body.getBytes(StandardCharsets.UTF_8));
int status = connection.getResponseCode();
InputStream stream = status >= 400
? connection.getErrorStream()
: connection.getInputStream();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
System.out.println("Response: " + status + " " + response);
}
}
}