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

Request Method

POST

Content-Type: application/json

Authorization

Open Platform API Signing

Request Parameters

RequiredParameterTypeDescription
RequiredparamsstringInference parameters as a JSON string
Requiredinit_imagesobject[]Image list; two images are required in order: the original image followed by the mask image
RequiredtaskstringFixed value: /v1/AI_Remove2/477119
Requiredtask_typestringFixed value: formula
Optionalsync_timeoutintDefault: 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:

RequiredParameterTypeDescription
RequiredurlstringImage URL or base64; the first item is the original image and the second item is the mask image
OptionalprofileobjectMedia parameters

The profile object has the following structure:

RequiredParameterTypeDescription
Optionalmedia_extraobjectAdditional media parameters
Optionalmedia_profilesobjectMedia description
OptionalversionstringThe source example uses v1

The media_profiles object has the following structure:

RequiredParameterTypeDescription
Optionalmedia_data_typestringurl 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:

RequiredFieldTypeDescription
Optionalrsp_media_typestringDefault: url; jpg returns the result image as base64, while url returns the result image as a URL
OptionalparameterobjectRemoval 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:

RequiredParameterTypeDescription
Optionaltext_remove_paramobjectSpecial parameters for text and watermark removal

text_remove_param parameters:

RequiredParameterTypeDescription
Optionalis_textboolWhether the input is a document-type image; default: false
Optionalis_translucent_watermarkboolWhether 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.
FieldTypeDescription
request_idstringRequest identifier
trace_idstringTrace identifier
codeintBusiness status code; 0 means the request was accepted successfully
error_codeintError code; 0 on success
messagestringBusiness or error message
tipsanyAdditional information; may be null
dataobjectTask status and algorithm result

data fields:

FieldTypeDescription
statusintStatus code: -1 task not found; 0 created; 1 processing; 2 failed; 9 timed out and must be queried through the query API; 10 succeeded
resultobjectAlgorithm result
progressnumberTask progress, for example 0.1, 0.85, or 1
predict_elapsedintEstimated processing time in milliseconds
create_timeint64Creation timestamp in milliseconds
task_idstringTask ID
custom_task_idstringCustom task ID
trace_idstringTrace identifier
client_infostringClient information
init_imagesobject[]/nullEcho of the input media

result fields:

FieldTypeDescription
idstringTask ID
urlsstring[]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

ErrorCodeError MessageDescription
20001PROCESS_ERRORProcessing 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);
        }
    }
}