Intelligent Removal 2.0
Description
This API submits an intelligent removal task. After successful submission, the algorithm runs asynchronously. You can proactively retrieve the algorithm result through the query API or receive it through the callback URL specified in the request.
Version
2.0
Image Requirements
- Image formats: JPG, JPEG, PNG, BMP, and HEIF.
- Image file size: 30 MB.
- This API requires two images in order: the original image followed by the mask image.
Endpoint
Production environment: https://openapi.meitu.com
Task submission endpoint: https://openapi.meitu.com/api/v1/sdk/sync/push
Task name (task): /v1/AI_Remove2/477119
Task type (task_type): formulaRequest Method
POST
Content-Type: application/json
Authorization
Request Parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| Required | params | string | Inference parameters as a JSON string |
| Required | init_images | object[] | Image list; two images are required in order: the original image followed by the mask image |
| Required | task | string | Fixed value: /v1/AI_Remove2/477119 |
| Required | task_type | string | Fixed value: formula |
| Optional | sync_timeout | int | Default: 30; -1 means do not wait. If synchronous waiting times out, status 9 is returned and the result must be retrieved through the query API |
The init_images image object has the following structure:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Required | url | string | Image URL or base64; the first item is the original image and the second item is the mask image |
| Optional | profile | object | Media parameters |
The profile object has the following structure:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Optional | media_extra | object | Additional media parameters |
| Optional | media_profiles | object | Media description |
| Optional | version | string | The source example uses v1 |
The media_profiles object has the following structure:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Optional | media_data_type | string | url transmits the media file as a URL; jpg transmits the media file as base64 |
The params inference parameters are a JSON string. After deserialization, the object has the following structure:
| Required | Field | Type | Description |
|---|---|---|---|
| Optional | rsp_media_type | string | Default: url; jpg returns the result image as base64, while url returns the result image as a URL |
| Optional | parameter | object | Removal algorithm parameter object |
Under the unified gateway's five-field request structure, rsp_media_type is placed in the object obtained by deserializing the params string and is a sibling of parameter; removal algorithm fields are placed only inside parameter.
parameter algorithm parameters:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Optional | text_remove_param | object | Special parameters for text and watermark removal |
text_remove_param parameters:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Optional | is_text | bool | Whether the input is a document-type image; default: false |
| Optional | is_translucent_watermark | bool | Whether the watermark in the input image is translucent; default: false |
When both is_text and is_translucent_watermark are true, the API directly performs a translucent-watermark removal task. This feature is designed specifically for translucent-watermark scenarios and may not work well in other scenarios.
Request Example
{
"task": "/v1/AI_Remove2/477119",
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/original.jpg",
"profile": {
"media_profiles": {
"media_data_type": "url"
},
"version": "v1"
}
},
{
"url": "https://example.com/mask.jpg",
"profile": {
"media_profiles": {
"media_data_type": "url"
},
"version": "v1"
}
}
],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"text_remove_param\":{\"is_text\":false,\"is_translucent_watermark\":false}}}",
"sync_timeout": 30
}Response Fields
Note: Generated result images are periodically deleted. Download and save them promptly.| Field | Type | Description |
|---|---|---|
| request_id | string | Request identifier |
| trace_id | string | Trace identifier |
| code | int | Business status code; 0 means the request was accepted successfully |
| error_code | int | Error code; 0 on success |
| message | string | Business or error message |
| tips | any | Additional information; may be null |
| data | object | Task status and algorithm result |
data fields:
| Field | Type | Description |
|---|---|---|
| status | int | Status code: -1 task not found; 0 created; 1 processing; 2 failed; 9 timed out and must be queried through the query API; 10 succeeded |
| result | object | Algorithm result |
| progress | number | Task progress, for example 0.1, 0.85, or 1 |
| predict_elapsed | int | Estimated processing time in milliseconds |
| create_time | int64 | Creation timestamp in milliseconds |
| task_id | string | Task ID |
| custom_task_id | string | Custom task ID |
| trace_id | string | Trace identifier |
| client_info | string | Client information |
| init_images | object[]/null | Echo of the input media |
result fields:
| Field | Type | Description |
|---|---|---|
| id | string | Task ID |
| urls | string[] | Result image URL list |
Response Examples
Successful Response Example
Response Status: 200
Content-Type: application/json; charset=utf-8
{
"request_id": "req_1234567890",
"trace_id": "trace_1234567890",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 10,
"result": {
"id": "t_mt1a3i5n7bdb4183fe-8f91-4b1c-ae95-402b6f48613b",
"urls": [
"https://aigcp.meitudata.com/effect/sys_kfpt/xiuxiu/67af4645-0f48-4fad-8999-748af70b30dc.png"
]
},
"progress": 1,
"predict_elapsed": 0,
"create_time": 1718172000000,
"task_id": "t_mt1a3i5n7bdb4183fe-8f91-4b1c-ae95-402b6f48613b",
"custom_task_id": "",
"trace_id": "trace_1234567890",
"client_info": "",
"init_images": null
}
}Query-Required Response Example
When data.status is 9, use the returned task ID with the query API to retrieve the result.
Response Status: 200
Content-Type: application/json; charset=utf-8
{
"request_id": "req_1234567890",
"trace_id": "trace_1234567890",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 9,
"result": {
"id": "task_1234567890"
},
"progress": 0,
"predict_elapsed": 10000,
"create_time": 1718172000000,
"task_id": "task_1234567890",
"custom_task_id": "",
"trace_id": "trace_1234567890",
"client_info": "",
"init_images": null
}
}Failed Response Example
Response Status: 400
Content-Type: application/json; charset=utf-8
{
"request_id": "req_1234567890",
"trace_id": "trace_1234567890",
"code": 20001,
"error_code": 20001,
"message": "PROCESS_ERROR",
"tips": null,
"data": {
"status": 2,
"result": {
"ErrorCode": 20001,
"ErrorMsg": "PROCESS_ERROR",
"Data": null
},
"progress": 0,
"predict_elapsed": 0,
"create_time": 1718172000000,
"task_id": "",
"custom_task_id": "",
"trace_id": "trace_1234567890",
"client_info": "",
"init_images": null
}
}API-Specific Error Codes
| ErrorCode | Error Message | Description |
|---|---|---|
| 20001 | PROCESS_ERROR | Processing error |
Common Error Codes
See API Error Codes.
SDK Examples
All SDK examples sign and send the same actual request body. The first item in init_images is the original image, and the second item is the mask image.
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": {
"text_remove_param": {
"is_text": False,
"is_translucent_watermark": False,
}
},
}
payload = {
"task": "/v1/AI_Remove2/477119",
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/original.jpg",
"profile": {
"media_profiles": {"media_data_type": "url"},
"version": "v1",
},
},
{
"url": "https://example.com/mask.jpg",
"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_Remove2/477119",
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/original.jpg",
"profile": {
"media_profiles": {"media_data_type": "url"},
"version": "v1"
}
},
{
"url": "https://example.com/mask.jpg",
"profile": {
"media_profiles": {"media_data_type": "url"},
"version": "v1"
}
}
],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"text_remove_param\":{\"is_text\":false,\"is_translucent_watermark\":false}}}",
"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' => [
'text_remove_param' => [
'is_text' => false,
'is_translucent_watermark' => false,
],
],
]);
$body = json_encode([
'task' => '/v1/AI_Remove2/477119',
'task_type' => 'formula',
'init_images' => [
[
'url' => 'https://example.com/original.jpg',
'profile' => [
'media_profiles' => ['media_data_type' => 'url'],
'version' => 'v1',
],
],
[
'url' => 'https://example.com/mask.jpg',
'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_Remove2/477119\",\n" +
" \"task_type\": \"formula\",\n" +
" \"init_images\": [\n" +
" {\n" +
" \"url\": \"https://example.com/original.jpg\",\n" +
" \"profile\": {\n" +
" \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
" \"version\": \"v1\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"url\": \"https://example.com/mask.jpg\",\n" +
" \"profile\": {\n" +
" \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
" \"version\": \"v1\"\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"text_remove_param\\\":{\\\"is_text\\\":false,\\\"is_translucent_watermark\\\":false}}}\",\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);
}
}
}