AI Seamless Removal

Description

This API submits an AI seamless removal task. It processes the painted region in an image and generates a plausible result for an improved generative removal effect.

Version

1.0

Example Results

Input ImageOutput Image
SampleResult

Image Requirements

  • JPG and PNG formats are supported.
  • Exactly two images must be provided in order: the first is the original image, and the second is the mask that marks the painted region to remove.
  • The current unified upper limit for both image width and height is 4096. If the original image exceeds this limit, the algorithm result is scaled before it is returned.

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_Seamless_Elimination/467915
    Task type (task_type): formula

Method

POST

Content-Type: application/json

Authentication

Open Platform API Signature

Request Parameters

RequiredParameterTypeDescription
YesparamsstringInference parameters as a JSON string
Yesinit_imagesobject[]Image file list. Two images are required: the first is the original image and the second is the mask image
YestaskstringFixed value: /v1/AI_Seamless_Elimination/467915
Yestask_typestringFixed value: formula
Nosync_timeoutintDefault: 30. Set to -1 to return immediately without waiting. If the synchronous wait times out, status 9 is returned; use the status API to retrieve the result

init_images image parameter structure

RequiredParameterTypeDescription
YesurlstringImage URL or base64 data
NoprofileobjectMedia parameters

profile media parameter structure

RequiredParameterTypeDescription
Nomedia_extraobjectAdditional media parameters. The source document does not define its internal fields
Nomedia_profilesobjectMedia description
NoversionstringThe source request example uses v1

media_profiles media description structure

RequiredParameterTypeDescription
Nomedia_data_typestringurl transmits the media file by URL; jpg transmits it as JPG base64 data

params is a JSON string with the following structure

RequiredFieldTypeDescription
Norsp_media_typestringDefault: url. jpg returns the result image as base64 data; url returns it as a URL
YesparameterobjectRemoval algorithm parameter object

parameter algorithm parameters

RequiredParameterTypeDescription
Nogenerate_numintNumber of images to return. Default: 4; range: 1 to 10
NoseedintRandom seed in [-1,65535]. If omitted, the API uses 0. A fixed seed produces the same result on each request. Callers are advised to generate and pass their own random seed so that bad cases can be reproduced. -1 uses a random seed and produces a different result each time
NoschedulerstringSampler type. Supported values: DDIM, DEIS-M, KDPM-2D, KDPM-2AD, Euler-AD, Euler-D, Heun-D, LMS-D, DPM-SM, PNDM, DPM-SS, and UniPC-M. Default: DDIM
NostepintNumber of sampling steps. Default: 25; range: 1 to 1000
Noauto_adjust_mask_edgeboolWhether the algorithm adaptively adjusts the input mask and performs removal with the adjusted mask. Default: true. Enabling this option is recommended when the mask comes from a segmentation algorithm, to prevent incompletely segmented edge pixels from affecting the result. It is also recommended when a visible shadow surrounds the subject to be removed, so that the result looks more natural
Noreturn_modified_maskboolWhether to return the mask actually used for removal. Default: false. Because auto_adjust_mask_edge may modify the mask, this parameter can return the modified mask for debugging or post-processing. When true, the API returns both RGB result images and single-channel mask images, for a total of generate_num * 2 images. The returned mask image includes is_mask=true in media_profiles
Nohigh_quality_encodeboolWhether to encode and return the result image with high quality and a low compression rate. Default: false. The image content does not change and quality is improved, but processing takes longer
Noglobal_instances_maskobjectDedicated subject-protection field for removal. It contains media_data and media_profiles, using the same format as the media definitions above, and supplies an additional full-image instance-segmentation mask. Instance pixel values are 1, 2, and so on; 0 represents the background. This mask protects subject regions in the original image from modification and has higher priority than auto_adjust_mask_edge. Protected pixels are not modified even when auto_adjust_mask_edge=true

Request Example

{
  "task": "/v1/AI_Seamless_Elimination/467915",
  "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.png",
      "profile": {
        "media_profiles": {"media_data_type": "url"},
        "version": "v1"
      }
    }
  ],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"generate_num\":1}}",
  "sync_timeout": 30
}

Response Fields

Note: Generated result images are periodically deleted after 24 hours. 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 field structure

FieldTypeDescription
statusintStatus code: -1 task not found; 0 task created; 1 processing; 2 failed; 9 requires a query through the status API; 10 succeeded
msgstringDescription of media-file-related attributes
resultobjectAlgorithm result
progressnumberTask progress, for example 0.1, 0.85, or 1
predict_elapsedintEstimated time in milliseconds
create_timeint64Creation timestamp in milliseconds
task_idstringTask ID
custom_task_idstringClient-defined task ID
trace_idstringTrace identifier
client_infostringClient information
init_imagesobject[]/nullEchoed input media

result field structure

FieldTypeDescription
idstringTask ID
urlsstring[]List of result image URLs. When rsp_media_type is jpg, the source document states that base64-encoded result images are returned

Response Examples

Successful Response

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": "50309bd5-a827-4125-bc96-62039c93770b",
      "urls": ["https://obs.mtlab.meitu.com/mtopen/rF5GIhp5ReLKgLV91CKj5BO1q2FTLMmc/MTY5Mjg1MzIwMA==/1c39ef92-04f1-40b4-5b7e-8fcfca0c11ea.png"]
    },
    "progress": 1,
    "predict_elapsed": 0,
    "create_time": 1718172000000,
    "task_id": "50309bd5-a827-4125-bc96-62039c93770b",
    "custom_task_id": "",
    "trace_id": "trace_1234567890",
    "client_info": "",
    "init_images": null
  }
}

Query-Required Response

When data.status is 9, retrieve the result from the status API using the returned task ID.

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

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": {
      "id": "t_mt1a3i5n7bac811796-59d6-4a00-bd59-8cfabc82df64",
      "msg": "ERROR msg"
    },
    "progress": 1,
    "predict_elapsed": 0,
    "create_time": 1718172000000,
    "task_id": "t_mt1a3i5n7bac811796-59d6-4a00-bd59-8cfabc82df64",
    "custom_task_id": "",
    "trace_id": "trace_1234567890",
    "client_info": "",
    "init_images": null
  }
}

General Error Codes and Messages

See API Error Codes.

SDK Examples

Each SDK example signs the complete final JSON body that is sent.

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": {"generate_num": 1},
    }
    payload = {
        "task": "/v1/AI_Seamless_Elimination/467915",
        "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.png",
                "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_Seamless_Elimination/467915",
  "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.png","profile":{"media_profiles":{"media_data_type":"url"},"version":"v1"}}
  ],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"generate_num\":1}}",
  "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' => ['generate_num' => 1],
]);
$body = json_encode([
    'task' => '/v1/AI_Seamless_Elimination/467915',
    '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.png',
            '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_Seamless_Elimination/467915\",\n" +
                "  \"task_type\": \"formula\",\n" +
                "  \"init_images\": [\n" +
                "    {\"url\":\"https://example.com/original.jpg\",\"profile\":{\"media_profiles\":{\"media_data_type\":\"url\"},\"version\":\"v1\"}},\n" +
                "    {\"url\":\"https://example.com/mask.png\",\"profile\":{\"media_profiles\":{\"media_data_type\":\"url\"},\"version\":\"v1\"}}\n" +
                "  ],\n" +
                "  \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"generate_num\\\":1}}\",\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);
        }
    }
}