Yunxiu Intelligent Photo Retouching API PRO

Submit an image to Yunxiu Intelligent Photo Retouching PRO and retrieve the processed image asynchronously.

Permissions

Obtain an AccessKey and SecretKey and sign each request as described in the Open Platform request signing guide.

Requests

Use POST with Content-Type: application/json.

OperationURLJSON body
Submit a presethttps://openapi.meitu.com/yunxiu/openapi/chain.jsonmedia_code (preset ID) and media_data (public image URL)
Submit raw parametershttps://openapi.meitu.com/yunxiu/openapi/chain.jsonmedia_data and parameter.all_params
Query a taskhttps://openapi.meitu.com/yunxiu/openapi/query.jsonchain_id from the submission response

For a preview of up to 1500 × 1500 pixels, submit the same JSON to https://openapi.meitu.com/yunxiu/openapi/preview_chain.json. The full-size endpoint accepts up to 15000 × 15000 pixels. Both accept JPEG and PNG.

Raw request body

Use a public image URL in the following sample.

{
    "repost_url": "https://www.example.com/callback.json",
    "media_data": "https://obs-open-platform-photo.obs.cn-north-4.myhuaweicloud.com/colorbyte_qt/photo/68760a99ed6616jv8vmfts2152.jpg",
    "parameter": {
        "all_params": {"exposure": 20}
    }
}

Results

Read data.chain_id from the submission response. Send it in the query request to check the task status. If you supply a repost_url, your callback can also receive the result.

SDK examples

Install the signing SDK for your language. Python also requires requests. For PHP, place signer.php alongside the script. Save the Java example as Main.java.

Enter your signing keys, preset ID and image URL to submit a task. Use the returned data.chain_id to query the result.

Python

import json
import requests
from sign_sdk import sign
def api_call_example():
    key = "your_access_key"
    secret = "your_secret_key"
    url = "https://openapi.meitu.com/yunxiu/openapi/chain.json"
    method = "POST"
    headers = {
        "Content-Type": "application/json",
        sign.HeaderHost: "openapi.meitu.com",
    }
    payload = {"media_code": "YOUR_PRESET_ID", "media_data": "https://example.com/portrait.jpg"}
    body = json.dumps(payload, ensure_ascii=False)
    signer = sign.Signer(key, secret)
    signed_request = signer.sign(url, method, headers, body)
    with requests.Session() as session:
        response = session.send(signed_request, timeout=60)
        print("Status:", response.status_code)
        print("Response:", response.text)
if __name__ == "__main__":
    api_call_example()

Go

package main

import (
	"fmt"
	"github.com/mtlab/api/signer"
	"io"
	"net/http"
	"time"
)

func main() {
	key := "your_access_key"
	secret := "your_secret_key"
	signObj := signer.NewSigner(key, secret)
	url := "https://openapi.meitu.com/yunxiu/openapi/chain.json"
	headers := make(http.Header)
	headers.Set(signer.HeaderHost, "openapi.meitu.com")
	headers.Set("Content-Type", "application/json")
	body := `{"media_code":"YOUR_PRESET_ID","media_data":"https://example.com/portrait.jpg"}`
	req, err := signObj.Sign(url, http.MethodPost, headers, body)
	if err != nil {
		fmt.Println("Failed to sign request:", err)
		return
	}
	client := &http.Client{Timeout: 60 * time.Second}
	resp, err := client.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("Failed to read response:", err)
		return
	}
	fmt.Println("Status:", resp.StatusCode)
	fmt.Println("Response:", string(responseBody))
}

PHP

<?php
require_once __DIR__ . '/signer.php';
$key = 'your_access_key';
$secret = 'your_secret_key';
$url = 'https://openapi.meitu.com/yunxiu/openapi/chain.json';
$headers = [
    'Content-Type' => 'application/json',
    'Host' => 'openapi.meitu.com',
];
$payload = ['media_code' => 'YOUR_PRESET_ID', 'media_data' => 'https://example.com/portrait.jpg'];
$body = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
$signer = new Signer($key, $secret);
$curl = $signer->sign($url, 'POST', $headers, $body);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
$response = curl_exec($curl);
if ($response === false) {
    echo 'Error: ' . curl_error($curl);
} 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 {
        Signer signer = new Signer("your_access_key", "your_secret_key");
        String url = "https://openapi.meitu.com/yunxiu/openapi/chain.json";
        String method = "POST";
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put(Signer.HeaderHost, "openapi.meitu.com");
        String body = "{\"media_code\": \"YOUR_PRESET_ID\", \"media_data\": \"https://example.com/portrait.jpg\"}";
        Map<String, String> signedHeaders = signer.sign(url, method, headers, body);
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        try {
            connection.setRequestMethod(method);
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(60000);
            connection.setInstanceFollowRedirects(false);
            for (Map.Entry<String, String> header : signedHeaders.entrySet()) {
                connection.setRequestProperty(header.getKey(), header.getValue());
            }
            connection.setDoOutput(true);
            try (OutputStream output = connection.getOutputStream()) {
                output.write(body.getBytes(StandardCharsets.UTF_8));
            }
            int status = connection.getResponseCode();
            InputStream stream = status >= 400
                    ? connection.getErrorStream()
                    : connection.getInputStream();
            System.out.println("Status: " + status);
            if (stream != null) {
                try (InputStream input = stream;
                     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();
        }
    }
}

Submit raw parameters

Save the complete raw request body above as params.json and set the image URL and processing parameters.

Python

import json
import requests
from sign_sdk import sign
def api_call_example():
    key = "your_access_key"
    secret = "your_secret_key"
    url = "https://openapi.meitu.com/yunxiu/openapi/chain.json"
    method = "POST"
    headers = {
        "Content-Type": "application/json",
        sign.HeaderHost: "openapi.meitu.com",
    }
    with open("params.json", encoding="utf-8") as source:
        body = source.read()
    signer = sign.Signer(key, secret)
    signed_request = signer.sign(url, method, headers, body)
    with requests.Session() as session:
        response = session.send(signed_request, timeout=60)
        print("Status:", response.status_code)
        print("Response:", response.text)
if __name__ == "__main__":
    api_call_example()

Go

package main

import (
	"fmt"
	"github.com/mtlab/api/signer"
	"io"
	"net/http"
	"os"
	"time"
)

func main() {
	key := "your_access_key"
	secret := "your_secret_key"
	signObj := signer.NewSigner(key, secret)
	url := "https://openapi.meitu.com/yunxiu/openapi/chain.json"
	headers := make(http.Header)
	headers.Set(signer.HeaderHost, "openapi.meitu.com")
	headers.Set("Content-Type", "application/json")
	data, err := os.ReadFile("params.json")
	if err != nil { panic(err) }
	body := string(data)
	req, err := signObj.Sign(url, http.MethodPost, headers, body)
	if err != nil {
		fmt.Println("Failed to sign request:", err)
		return
	}
	client := &http.Client{Timeout: 60 * time.Second}
	resp, err := client.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("Failed to read response:", err)
		return
	}
	fmt.Println("Status:", resp.StatusCode)
	fmt.Println("Response:", string(responseBody))
}

PHP

<?php
require_once __DIR__ . '/signer.php';
$key = 'your_access_key';
$secret = 'your_secret_key';
$url = 'https://openapi.meitu.com/yunxiu/openapi/chain.json';
$headers = [
    'Content-Type' => 'application/json',
    'Host' => 'openapi.meitu.com',
];
$body = file_get_contents(__DIR__ . '/params.json');
if ($body === false) { throw new RuntimeException('Cannot read params.json'); }
$signer = new Signer($key, $secret);
$curl = $signer->sign($url, 'POST', $headers, $body);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
$response = curl_exec($curl);
if ($response === false) {
    echo 'Error: ' . curl_error($curl);
} 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 {
        Signer signer = new Signer("your_access_key", "your_secret_key");
        String url = "https://openapi.meitu.com/yunxiu/openapi/chain.json";
        String method = "POST";
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put(Signer.HeaderHost, "openapi.meitu.com");
        String body = new String(java.nio.file.Files.readAllBytes(java.nio.file.Paths.get("params.json")), StandardCharsets.UTF_8);
        Map<String, String> signedHeaders = signer.sign(url, method, headers, body);
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        try {
            connection.setRequestMethod(method);
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(60000);
            connection.setInstanceFollowRedirects(false);
            for (Map.Entry<String, String> header : signedHeaders.entrySet()) {
                connection.setRequestProperty(header.getKey(), header.getValue());
            }
            connection.setDoOutput(true);
            try (OutputStream output = connection.getOutputStream()) {
                output.write(body.getBytes(StandardCharsets.UTF_8));
            }
            int status = connection.getResponseCode();
            InputStream stream = status >= 400
                    ? connection.getErrorStream()
                    : connection.getInputStream();
            System.out.println("Status: " + status);
            if (stream != null) {
                try (InputStream input = stream;
                     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();
        }
    }
}

Query the result

Set YOUR_CHAIN_ID to the data.chain_id returned by the submission request. Sign and send the POST request to retrieve the result.

Python

import json
import requests
from sign_sdk import sign
def api_call_example():
    key = "your_access_key"
    secret = "your_secret_key"
    url = "https://openapi.meitu.com/yunxiu/openapi/query.json"
    method = "POST"
    headers = {
        "Content-Type": "application/json",
        sign.HeaderHost: "openapi.meitu.com",
    }
    payload = {"chain_id": "YOUR_CHAIN_ID"}
    body = json.dumps(payload, ensure_ascii=False)
    signer = sign.Signer(key, secret)
    signed_request = signer.sign(url, method, headers, body)
    with requests.Session() as session:
        response = session.send(signed_request, timeout=60)
        print("Status:", response.status_code)
        print("Response:", response.text)
if __name__ == "__main__":
    api_call_example()

Go

package main

import (
	"fmt"
	"github.com/mtlab/api/signer"
	"io"
	"net/http"
	"time"
)

func main() {
	key := "your_access_key"
	secret := "your_secret_key"
	signObj := signer.NewSigner(key, secret)
	url := "https://openapi.meitu.com/yunxiu/openapi/query.json"
	headers := make(http.Header)
	headers.Set(signer.HeaderHost, "openapi.meitu.com")
	headers.Set("Content-Type", "application/json")
	body := `{"chain_id":"YOUR_CHAIN_ID"}`
	req, err := signObj.Sign(url, http.MethodPost, headers, body)
	if err != nil {
		fmt.Println("Failed to sign request:", err)
		return
	}
	client := &http.Client{Timeout: 60 * time.Second}
	resp, err := client.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("Failed to read response:", err)
		return
	}
	fmt.Println("Status:", resp.StatusCode)
	fmt.Println("Response:", string(responseBody))
}

PHP

<?php
require_once __DIR__ . '/signer.php';
$key = 'your_access_key';
$secret = 'your_secret_key';
$url = 'https://openapi.meitu.com/yunxiu/openapi/query.json';
$headers = [
    'Content-Type' => 'application/json',
    'Host' => 'openapi.meitu.com',
];
$payload = ['chain_id' => 'YOUR_CHAIN_ID'];
$body = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
$signer = new Signer($key, $secret);
$curl = $signer->sign($url, 'POST', $headers, $body);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
$response = curl_exec($curl);
if ($response === false) {
    echo 'Error: ' . curl_error($curl);
} 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 {
        Signer signer = new Signer("your_access_key", "your_secret_key");
        String url = "https://openapi.meitu.com/yunxiu/openapi/query.json";
        String method = "POST";
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put(Signer.HeaderHost, "openapi.meitu.com");
        String body = "{\"chain_id\":\"YOUR_CHAIN_ID\"}";
        Map<String, String> signedHeaders = signer.sign(url, method, headers, body);
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        try {
            connection.setRequestMethod(method);
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(60000);
            connection.setInstanceFollowRedirects(false);
            for (Map.Entry<String, String> header : signedHeaders.entrySet()) {
                connection.setRequestProperty(header.getKey(), header.getValue());
            }
            connection.setDoOutput(true);
            try (OutputStream output = connection.getOutputStream()) {
                output.write(body.getBytes(StandardCharsets.UTF_8));
            }
            int status = connection.getResponseCode();
            InputStream stream = status >= 400
                    ? connection.getErrorStream()
                    : connection.getInputStream();
            System.out.println("Status: " + status);
            if (stream != null) {
                try (InputStream input = stream;
                     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();
        }
    }
}