Intelligent Removal
Description
Remove content from a selected image region and fill the area using an inpainting model. Two input methods are supported:
- Mask-based removal: provide the original image first, then a mask marking the removal area.
- Box-based removal: provide the original image and relative-coordinate regions through
userboxes.
In mask-based mode, userboxes and use_sod have no effect.
Version
1.0
Image Requirements
JPG and PNG are supported, supplied by image URL. Mask-based removal requires two images in this order: original image, then mask.
Request URL
https://openapi.meitu.com/api/v1/sdk/sync/pushTask name (task): /v1/smart_eraser/488142
Task type (task_type): formula
HTTP Method
POST
Content-Type: application/json
Authentication
Use an AK/SK pair with access to this capability and sign requests using the signing SDK. See API Request Signing.
Request Parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | sync_timeout | integer | Synchronous waiting period in seconds. The examples use 10; the source specifies no default. |
| Yes | task_type | string | Fixed value: formula. |
| Yes | init_images | object[] | Input images. Box mode takes the original image; mask mode takes the original image followed by the mask. |
| Yes | task | string | Fixed value: /v1/smart_eraser/488142. |
| Yes | params | string | JSON-serialized algorithm parameter object. |
init_images Element
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | url | string | Accessible image URL. |
params
The decoded object contains parameter, whose fields are described below. The HTTP body is a JSON object; only the params value is a JSON string. Do not encode the entire request body a second time as a string.
parameter
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | rsp_media_type | string | url: return a short-lived result image URL. Download and save it promptly. |
| No | userboxes | string | JSON string of selected regions. The outer array contains boxes, each with four relative-coordinate points ordered top-left, top-right, bottom-right, bottom-left. Ignored in mask mode. |
| No | use_sod | string | Whether to apply salient-object segmentation within selected boxes. The source example uses the string "true", not a boolean. Ignored in mask mode. |
| No | model_type | string | Inpainting model: lama or fcf. The source specifies no default. |
Example userboxes string for one box:
[[[0.1,0.1],[0.4,0.1],[0.4,0.4],[0.1,0.4]]]Request Examples
Mask-Based Removal
Replace the original image and mask URLs. The example omits use_sod because it has no effect in mask mode.
{
"sync_timeout": 10,
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/input.png"
},
{
"url": "https://example.com/mask.png"
}
],
"task": "/v1/smart_eraser/488142",
"params": "{\"parameter\":{\"rsp_media_type\":\"url\",\"model_type\":\"lama\"}}"
}Box-Based Removal
Replace the image URL and coordinates. After decoding params, userboxes is still a string.
{
"sync_timeout": 10,
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/input.png"
}
],
"task": "/v1/smart_eraser/488142",
"params": "{\"parameter\":{\"rsp_media_type\":\"url\",\"model_type\":\"lama\",\"userboxes\":\"[[[0.1,0.1],[0.4,0.1],[0.4,0.4],[0.1,0.4]]]\",\"use_sod\":\"true\"}}"
}Decoded params for box mode:
{
"parameter": {
"rsp_media_type": "url",
"model_type": "lama",
"userboxes": "[[[0.1,0.1],[0.4,0.1],[0.4,0.4],[0.1,0.4]]]",
"use_sod": "true"
}
}Response Fields
code = 0 indicates normal request processing; also check data.status. The fields below follow the legacy API documentation, which uses data.result.urls[0] for the result image. This path has not yet been verified for the new formula.
| Field | Type | Description |
|---|---|---|
| code | integer | 0 indicates a successful request; nonzero indicates a business error. |
| message | string | Response message. PROCESS_ERROR in the source error example; absent from its success example. |
| data | object | Task details. |
| data.status | integer | The source defines 9 as synchronous wait timeout, 2 as failure, and 10 as success. |
| data.result | object | Task result. |
| data.progress | number | Task progress; 1 in the source example. |
| data.predict_elapsed | number | Estimated processing time. The source does not specify units. |
data.result
| Field | Type | Description |
|---|---|---|
| id | string | Gateway task ID. |
| urls | string[] | Result image URLs. Index 0 contains the processed result. |
| code | integer | Algorithm status code in the source error example. |
Response Examples
The structures below are retained from the legacy API documentation for reference. The actual response of /v1/smart_eraser/488142 has not been verified. Confirm result field paths and the query ID location against the formula's actual response; these are not live results.
Success Example
HTTP 200.
{
"code": 0,
"data": {
"status": 10,
"result": {
"id": "example-task-id",
"urls": [
"https://example.com/output.jpg"
]
},
"progress": 1,
"predict_elapsed": 10000
}
}When to Query
data.status = 9 indicates that synchronous waiting timed out, not that the task failed. Use the source's data.result.id as the task ID with Task Query, rather than resubmitting.
Common query states also include -1 (not found), 0 (created), and 1 (running), as defined in the query documentation.
Error Example
The source example uses HTTP 200. The business error is indicated by code and data.status; HTTP status alone does not establish task success.
{
"code": 20001,
"message": "PROCESS_ERROR",
"data": {
"status": 2,
"result": {
"id": "example-task-id",
"code": 20001
},
"progress": 1
}
}Common Error Codes
20001 / PROCESS_ERROR indicates a processing error. See API Error Codes for the complete common error-code reference.
SDK Examples
All four examples use the mask-based request above and embed the entire request body; no separate JSON file is required. Set up the SDK for your language, then replace the AK, SK, original image URL, and mask URL.
Each example submits once and prints the response. For box-based removal, adapt the body using the box-mode JSON above. Sign and send the same final request body.
Python
import json
import requests
from sign_sdk import sign
def main():
key = "YOUR_ACCESS_KEY"
secret = "YOUR_SECRET_KEY"
url = "https://openapi.meitu.com/api/v1/sdk/sync/push"
inner_params = {
"parameter": {
"rsp_media_type": "url",
"model_type": "lama"
}
}
payload = {
"sync_timeout": 10,
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/input.png"
},
{
"url": "https://example.com/mask.png"
}
],
"task": "/v1/smart_eraser/488142",
"params": json.dumps(inner_params, ensure_ascii=True)
}
body = json.dumps(payload, ensure_ascii=True)
headers = {
"Content-Type": "application/json",
sign.HeaderHost: "openapi.meitu.com",
}
signer = sign.Signer(key, secret)
signed_request = signer.sign(url, "POST", headers, body)
with requests.Session() as session:
response = session.send(
signed_request, timeout=(10, 60), verify=True, allow_redirects=False
)
print("Status:", response.status_code)
print("Response:", response.text)
if __name__ == "__main__":
main()
Go
package main
import (
"fmt"
"io"
"net/http"
"time"
"github.com/formula/api/signer"
)
func main() {
body := `{
"sync_timeout": 10,
"task_type": "formula",
"init_images": [
{
"url": "https://example.com/input.png"
},
{
"url": "https://example.com/mask.png"
}
],
"task": "/v1/smart_eraser/488142",
"params": "{\"parameter\":{\"rsp_media_type\":\"url\",\"model_type\":\"lama\"}}"
}`
url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
headers := make(http.Header)
headers.Set("Content-Type", "application/json")
headers.Set(signer.HeaderHost, "openapi.meitu.com")
signObj := signer.NewSigner("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY")
req, err := signObj.Sign(url, http.MethodPost, headers, body)
if err != nil {
fmt.Println("Sign request failed:", err)
return
}
client := &http.Client{
Timeout: 60 * time.Second,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Send request failed:", err)
return
}
defer resp.Body.Close()
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Read response failed:", err)
return
}
fmt.Println("Status:", resp.StatusCode)
fmt.Println("Response:", string(responseBody))
}
PHP
<?php
require_once __DIR__ . '/signer.php';
$innerParams = json_encode([
'parameter' => [
'rsp_media_type' => 'url',
'model_type' => 'lama'
]
], JSON_UNESCAPED_SLASHES);
$body = json_encode([
'sync_timeout' => 10,
'task_type' => 'formula',
'init_images' => [
[
'url' => 'https://example.com/input.png'
],
[
'url' => 'https://example.com/mask.png'
]
],
'task' => '/v1/smart_eraser/488142',
'params' => $innerParams
], JSON_UNESCAPED_SLASHES);
$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$headers = [
'Content-Type' => 'application/json',
'Host' => 'openapi.meitu.com',
];
$signer = new Signer('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');
$curl = $signer->sign($url, 'POST', $headers, $body);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
$response = curl_exec($curl);
if ($response === false) {
echo 'Error: ' . curl_error($curl) . PHP_EOL;
} else {
echo 'Status: ' . curl_getinfo($curl, CURLINFO_HTTP_CODE) . PHP_EOL;
echo 'Response: ' . $response . PHP_EOL;
}
curl_close($curl);
Java
import com.meitu.openai.common.Signer;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
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 {
String body =
"{\n" +
" \"sync_timeout\": 10,\n" +
" \"task_type\": \"formula\",\n" +
" \"init_images\": [\n" +
" {\n" +
" \"url\": \"https://example.com/input.png\"\n" +
" },\n" +
" {\n" +
" \"url\": \"https://example.com/mask.png\"\n" +
" }\n" +
" ],\n" +
" \"task\": \"/v1/smart_eraser/488142\",\n" +
" \"params\": \"{\\\"parameter\\\":{\\\"rsp_media_type\\\":\\\"url\\\",\\\"model_type\\\":\\\"lama\\\"}}\"\n" +
"}";
String url = "https://openapi.meitu.com/api/v1/sdk/sync/push";
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put(Signer.HeaderHost, "openapi.meitu.com");
Signer signer = new Signer("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");
Map<String, String> signedHeaders = signer.sign(url, "POST", headers, body);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
try {
connection.setRequestMethod("POST");
connection.setConnectTimeout(10000);
connection.setReadTimeout(60000);
connection.setInstanceFollowRedirects(false);
connection.setDoOutput(true);
for (Map.Entry<String, String> entry : signedHeaders.entrySet()) {
connection.setRequestProperty(entry.getKey(), entry.getValue());
}
byte[] bodyBytes = body.getBytes(StandardCharsets.UTF_8);
connection.setFixedLengthStreamingMode(bodyBytes.length);
try (OutputStream output = connection.getOutputStream()) {
output.write(bodyBytes);
}
int status = connection.getResponseCode();
System.out.println("Status: " + status);
InputStream responseStream = status >= 400
? connection.getErrorStream() : connection.getInputStream();
if (responseStream != null) {
try (InputStream input = responseStream;
ByteArrayOutputStream output = new ByteArrayOutputStream()) {
byte[] buffer = new byte[4096];
int length;
while ((length = input.read(buffer)) != -1) {
output.write(buffer, 0, length);
}
System.out.println("Response: " + output.toString("UTF-8"));
}
}
} finally {
connection.disconnect();
}
}
}