AI Outfit Change

Description

This API processes an input image in the cloud using a specified outfit template and generates an AI outfit-change image.

Version

1.0

Image Requirements

Image formats: JPG and PNG.

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_Change_Clothes/change_clothes_default/477312
    Task type (task_type): formula

The last segment of task is the outfit template ID. The request and SDK examples in this document use the “Butter Moonlight” outfit template ID 477312 from the source document. To use another outfit template, replace the last segment with the corresponding outfit template ID.

Method

POST

Content-Type: application/json

Authentication

Open Platform API Signature

Request Parameters

RequiredParameterTypeDescription
YesparamsstringAlgorithm parameters (JSON string). The original API has no algorithm parameters by default, so parameter is an empty object after unified wrapping.
Yesinit_imagesobject[]List of image files
YestaskstringFixed to /v1/AI_Change_Clothes/change_clothes_default/477312 in this document's examples; the last segment is the outfit template ID
Yestask_typestringFixed to formula
Nosync_timeoutintDefault: 30; -1 means do not wait. If the synchronous request times out and status is 9, use the query API.

The structure of each multimedia file in init_images is described below.

RequiredParameterTypeDescription
YesurlstringImage URL or base64 data
YesprofileobjectAttribute information

The profile attribute structure is described below.

RequiredParameterTypeDescription
Yesmedia_profilesobjectImage attribute information
YesversionstringFixed to v1

The media_profiles structure is described below.

RequiredParameterTypeDescription
Yesmedia_data_typestringurl indicates an image URL; jpg indicates a base64-encoded JPG image

The params inference parameter is a JSON string with the following structure.

RequiredFieldTypeDescription
Norsp_media_typestringDefault: url; jpg returns the result image as base64 data, while url returns an image URL
YesparameterobjectCore algorithm parameter object; pass an empty object {} for this API

Algorithm parameters in parameter:

RequiredFieldTypeDescription
The original API has no core algorithm parameters

Outfit Template Asset IDs

NameOutfit Template ID
Butter Moonlight477312
Ink-Dyed Kimono477307

For more outfit assets, visit the Meitu AI Open Platform and contact customer service using the contact details in the lower-right corner of the page.

Request Example

{
  "task": "/v1/AI_Change_Clothes/change_clothes_default/477312",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://example.com/input.jpg",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{}}",
  "sync_timeout": 30
}

Response Fields

Generated results 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 message
tipsanyAdditional information; may be null
dataobjectTask status and algorithm result

Fields in data:

FieldTypeDescription
statusintStatus code: -1 task not found; 0 created successfully; 1 processing; 2 failed; 9 timed out—use the query API; 10 succeeded
resultobjectAlgorithm result; fields from the original response are mapped into this object
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_idstringCustomer-defined task ID
trace_idstringTrace identifier within data
client_infostringClient information
init_imagesobject[]/nullEchoed input media

Fields in result:

FieldTypeDescription
idstringAlgorithm task ID
urlsstring[]URLs of generated images
msgstringMultimedia-file-related attribute information returned by the original API
error_codeintAlgorithm error code; may be 20001 on failure
error_messagestringAlgorithm error message; 20001 corresponds to PROCESS_ERROR

Response Examples

Successful Response Example

Response Status: 200

content-type: application/json; charset=utf-8

{
  "request_id": "req_50309bd5a827",
  "trace_id": "trace_50309bd5a827",
  "code": 0,
  "error_code": 0,
  "message": "",
  "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"
      ],
      "msg": ""
    },
    "progress": 1,
    "predict_elapsed": 0,
    "create_time": 1692853200000,
    "task_id": "50309bd5-a827-4125-bc96-62039c93770b",
    "custom_task_id": "",
    "trace_id": "trace_50309bd5a827",
    "client_info": "",
    "init_images": null
  }
}

Query-Required Response Example

Use the query API to retrieve the result.

Response Status: 200

content-type: application/json; charset=utf-8

{
  "request_id": "req_50309bd5a827",
  "trace_id": "trace_50309bd5a827",
  "code": 0,
  "error_code": 0,
  "message": "",
  "tips": null,
  "data": {
    "status": 9,
    "result": {},
    "progress": 0.85,
    "predict_elapsed": 1000,
    "create_time": 1692853200000,
    "task_id": "50309bd5-a827-4125-bc96-62039c93770b",
    "custom_task_id": "",
    "trace_id": "trace_50309bd5a827",
    "client_info": "",
    "init_images": null
  }
}

Failed Response Example

Response Status: 400

content-type: application/json; charset=utf-8

{
  "request_id": "req_50309bd5a827",
  "trace_id": "trace_50309bd5a827",
  "code": 0,
  "error_code": 0,
  "message": "",
  "tips": null,
  "data": {
    "status": 2,
    "result": {
      "error_code": 20001,
      "error_message": "PROCESS_ERROR"
    },
    "progress": 0,
    "predict_elapsed": 0,
    "create_time": 1692853200000,
    "task_id": "50309bd5-a827-4125-bc96-62039c93770b",
    "custom_task_id": "",
    "trace_id": "trace_50309bd5a827",
    "client_info": "",
    "init_images": null
  }
}

General Error Codes and Messages

See API Error Codes for details.

Error codes and messages specific to this API:

ErrorCodeError MessageDescription
20001PROCESS_ERRORProcessing error

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": {},
    }
    payload = {
        "task": "/v1/AI_Change_Clothes/change_clothes_default/477312",
        "task_type": "formula",
        "init_images": [
            {
                "url": "https://example.com/input.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_Change_Clothes/change_clothes_default/477312",
  "task_type": "formula",
  "init_images": [{
    "url": "https://example.com/input.jpg",
    "profile": {
      "media_profiles": {"media_data_type": "url"},
      "version": "v1"
    }
  }],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{}}",
  "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' => (object) [],
]);

$body = json_encode([
    'task' => '/v1/AI_Change_Clothes/change_clothes_default/477312',
    'task_type' => 'formula',
    'init_images' => [
        [
            'url' => 'https://example.com/input.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_Change_Clothes/change_clothes_default/477312\",\n" +
                "  \"task_type\": \"formula\",\n" +
                "  \"init_images\": [{\n" +
                "    \"url\": \"https://example.com/input.jpg\",\n" +
                "    \"profile\": {\n" +
                "      \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
                "      \"version\": \"v1\"\n" +
                "    }\n" +
                "  }],\n" +
                "  \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{}}\",\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);
        }
    }
}