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): formula

Method

POST

Content-Type: application/json

Authentication

Open Platform API Signature

Request Parameters

RequiredParameterTypeDescription
YesparamsstringAlgorithm parameters (JSON string)
Yesinit_imagesobject[]Media file list; pass the image first, followed by the driving video
YestaskstringFixed value: /v1/AI_Emoji_Pack/487155
Yestask_typestringFixed value: formula
Nosync_timeoutintDefaults to 30; synchronous timeout duration

The structure of each media file object in init_images is described below.

RequiredParameterTypeDescription
YesurlstringImage or video URL; Base64 data of the corresponding media type is also supported
YesprofileobjectMedia attribute information

The structure of profile is described below.

RequiredParameterTypeDescription
Yesmedia_profilesobjectMedia attribute information
YesversionstringFixed value: v1

The structure of media_profiles is described below.

RequiredParameterTypeDescription
Yesmedia_data_typestringurl 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.

RequiredFieldTypeDescription
Norsp_media_typestringOutput media type. Defaults to url; jpg returns the generated image as Base64-encoded data, while url returns a URL
YesparameterobjectCore algorithm parameters

Details of the algorithm parameters in parameter:

RequiredParameterTypeDescription
Nomedia_modeintOutput media type: 0 returns an image and 1 returns a video. Default: 1
Noanimal_flagintSubject 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.
FieldTypeDescription
request_idstringRequest identifier
trace_idstringDistributed tracing identifier
codeintBusiness status code; 0 means the request was accepted successfully
error_codeintError code; 0 on success
messagestringBusiness status message
tipsanyAdditional information; may be null
dataobjectTask status and algorithm result

Fields in data:

FieldTypeDescription
statusintStatus code: -1 task not found; 0 created; 1 processing; 2 failed; 9 timed out—use the Query API; 10 succeeded
resultobjectAlgorithm result
progressnumberTask progress in the range 0–1; 1 indicates completion
predict_elapsedintEstimated processing time in milliseconds
create_timeint64Creation timestamp in milliseconds
task_idstringTask ID
custom_task_idstringClient-defined task ID
trace_idstringTracing identifier within data
client_infostringClient information
init_imagesobject[]/nullEcho of the input media

Fields in result:

FieldTypeDescription
idstringUnique task identifier
urlsarrayList of output media URLs
imagesarrayOutput media list; equivalent to urls
parametersobjectOutput parameter information
dataobjectDetailed algorithm response data
msgstringResponse message
msg_idstringMessage ID
mtlab_resobjectUnderlying algorithm result
media_info_listarrayOutput media information list
error_codeintAlgorithm error code on failure; 20001 indicates a processing error
error_msgstringAlgorithm error message on failure; PROCESS_ERROR indicates a processing error

Fields in result.parameters:

FieldTypeDescription
rsp_media_typestringOutput media type; url indicates that media URLs are returned
total_spendstringTotal task duration in milliseconds
versionstringAlgorithm version

Fields in result.data:

FieldTypeDescription
durationobjectTiming statistics for each processing stage
error_codenumberAlgorithm error code; 0 indicates success
error_msgstringAlgorithm error message
extraobjectAdditional fields
media_info_listarrayMedia information list
msg_idstringMessage ID
parameterobjectEcho of the parameters

Fields in duration:

FieldTypeDescription
alg_process_timenumberAlgorithm processing time in milliseconds
created_timestampnumberTask creation timestamp in seconds
pull_timestampnumberMedia retrieval timestamp in seconds
repost_timenumberRetry duration
upload_timenumberUpload duration in milliseconds
waiting_timenumberQueue wait time in milliseconds

Fields in media_info_list:

FieldTypeDescription
media_datastringMedia data URL
media_extraobjectAdditional media information
media_profilesobjectMedia attribute information

Fields in media_profiles:

FieldTypeDescription
media_data_typestringMedia data type; url indicates that the media data is a URL
media_data_widthnumberMedia width in pixels
media_data_heightnumberMedia height in pixels
media_data_fpsnumberVideo frame rate
media_data_sizenumberMedia file size in bytes

Fields in mtlab_res:

FieldTypeDescription
ErrorCodenumberUnderlying error code
ErrorMsgstringUnderlying error message
error_codenumberBackward-compatible error code field
error_msgstringBackward-compatible error message field
media_info_listarrayMedia information list
msg_idstringMessage ID
parameterobjectParameter 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);
        }
    }
}