Image Quality Restoration V3

Description

This API submits an image quality restoration task. After a task is successfully submitted, the algorithm runs asynchronously. The caller can actively query the algorithm result through the query API or receive the result at the callback URL supplied in the request.

Image Requirements

  • Image formats: JPG, JPEG, and BMP.
  • Maximum image file size: 30 MB.
  • Images can currently be supplied only as URLs.

Endpoint

    Production environment: https://openapi.meitu.com
    Task submission endpoint: https://openapi.meitu.com/api/v1/sdk/sync/push
    Synchronous task name (task): /v1/High_Definition_V3/466658
    Asynchronous task name (task): /v1/High_Definition_V3/466659
    Task type (task_type): formula

Method

POST

Content-Type: application/json

Authorization

Open Platform API Signing

Request Parameters

The request body always consists of the following five top-level fields:

RequiredParameterTypeDescription
YesparamsstringInference parameters serialized as a JSON string
Yesinit_imagesobject[]List of image files; only URL input is currently supported
YestaskstringFixed at /v1/High_Definition_V3/466658 for a synchronous task or /v1/High_Definition_V3/466659 for an asynchronous task
Yestask_typestringFixed at formula
Nosync_timeoutintDefault: 30. -1 means do not wait. If synchronous waiting times out, status 9 is returned; use the query API to retrieve the result

init_images image parameters

RequiredParameterTypeDescription
YesurlstringImage address; only URLs are currently supported
NoprofileobjectMedia parameters

profile media parameters

RequiredParameterTypeDescription
Nomedia_extraobjectAdditional media parameters; the source document does not define its inner fields
Nomedia_profilesobjectMedia description
NoversionstringThe request example in the source document uses v1

media_profiles media description

RequiredParameterTypeDescription
Nomedia_data_typestringurl means transmission by URL; jpg means transmission as JPG base64. This API currently supports URL input only, so use url in requests

params is a JSON string. After deserialization, it has the following structure:

RequiredFieldTypeDescription
Norsp_media_typestringCommon response media type. Default: url. jpg returns the result image as base64; url returns it as a URL
YesparameterobjectImage Quality Restoration V3 algorithm parameter object

rsp_media_type is at the same level as parameter, and all algorithm fields are placed only inside parameter. The parameter table in the source document placed rsp_media_type inside parameter and used the value name base64 in one location. The same source document uses jpg/url in its top-level field description, request semantics, and returned media fields. This document normalizes the field as a common unified-gateway field and uses jpg/url, for which complete input and output mappings are available.

parameter algorithm details

RequiredParameterTypeDescription
Noir_modeintEffect mode. Default: 3. 3 selects Wink HD mode (V3); 4 selects Meitu HD and Wink portrait enhancement
Nosave_photo_formatintSaved image format. Default: 1. 1 means JPG; 2 means PNG
Nouse_denoiseintWhether to enable background restoration. Default: 1. 1 enables it; 0 disables it
Nouse_hd_face_optintWhether to enable upgraded portrait restoration. Default: 0. 1 enables it; 0 disables it
Nomax_widthintMaximum width of the returned image. Default: -1
Nomax_heightintMaximum height of the returned image. Default: -1
Norepost_urlstringPOST callback URL provided by the client
Nosr_numintDefault: 4
Noreturn_format_typestringReturned image format. Default: png. Options: jpeg, jpg, png, and webp. Any other string is treated as png

Request Example

{
  "task": "/v1/High_Definition_V3/466658",
  "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\":{\"ir_mode\":3}}",
  "sync_timeout": 30
}

To call the asynchronous task, change only task to /v1/High_Definition_V3/466659.

Response Fields

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 tips; may be null
dataobjectTask status and algorithm result

data fields

FieldTypeDescription
statusint-1: task not found; 0: created; 1: running; 2: failed; 9: use the query API; 10: succeeded
resultobjectAlgorithm result
progressnumberTask progress
predict_elapsedintEstimated duration 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 fields on success

FieldTypeDescription
idstringTask ID; can be used to query task status
media_info_listobject[]List of media results
parameterobjectReturned information type indicator

A single media_info_list element

FieldTypeDescription
media_datastringJPG base64 when media_data_type is jpg; an image URL when it is url
media_profilesobjectMedia file attributes

Returned parameter fields

FieldTypeDescription
rsp_media_typestringjpg means media_data is JPG base64; url means it is an image URL

Returned media_profiles fields

FieldTypeDescription
media_data_typestringjpg means media_data is JPG base64; url means it is an image URL

result fields on failure

FieldTypeDescription
ErrorCodeintAlgorithm error code
ErrorMsgstringAlgorithm error message
Datastring/nullDetailed error information; null when no data is available

Response Examples

Successful Response (status=10)

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": "task_1234567890",
      "parameter": {"rsp_media_type": "url"},
      "media_info_list": [
        {
          "media_data": "https://example.com/result.jpg",
          "media_profiles": {"media_data_type": "url"}
        }
      ]
    },
    "progress": 1,
    "predict_elapsed": 0,
    "create_time": 1718172000000,
    "task_id": "task_1234567890",
    "custom_task_id": "",
    "trace_id": "trace_1234567890",
    "client_info": "",
    "init_images": null
  }
}

Query Required (status=9)

Use the query API and the returned task ID 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 (status=2)

Response Status: 400

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

{
  "request_id": "req_1234567890",
  "trace_id": "trace_1234567890",
  "code": 20003,
  "error_code": 20003,
  "message": "DETECT_NOT_FACE",
  "tips": null,
  "data": {
    "status": 2,
    "result": {
      "ErrorCode": 20003,
      "ErrorMsg": "DETECT_NOT_FACE",
      "Data": null
    },
    "progress": 1,
    "predict_elapsed": 0,
    "create_time": 1718172000000,
    "task_id": "task_1234567890",
    "custom_task_id": "",
    "trace_id": "trace_1234567890",
    "client_info": "",
    "init_images": null
  }
}

API-Specific Error Codes and Messages

ErrorCodeError MessageDescription
20001PROCESS_ERRORProcessing error
20003DETECT_NOT_FACENo face detected
20004MORE_THAN_ONE_FACEMore than one face detected
20007MISSING_LANDMARK_ARGUMENTSFacial landmark points were not provided
20008UNSUITABLE_IMAGEThe photo does not meet the requirements
20009UNSUPPORT_TYPEUnsupported type
20010DETECT_NOT_FACENo face detected in the second image
20011UNSUITABLE_VERTICAL_IMAGEVertical height requirement not met
20012UNSUITABLE_HORIZONTAL_IMAGEHorizontal width requirement not met
20013RESOLUTION_TOO_LARGE_ERRORResolution is too high
20014NOT_FOUNDImage not found
20015PICTURE_OVERRUN_ERRORImage exceeds the limit
20020DETECT_FACE_OUTOFIMAGEFacial features are missing
20021DETECT_FACE_PITCHANGLE_BIGThe face is not frontal; nodding or pitch angle is too large
20022DETECT_FACE_YAWANGLE_BIGThe face is not frontal; head turn or rotation angle is too large
20023DETECT_FACE_LOWAREAFace area is too small or pixel count is too low
21001LOAD_MODEL_ERRORFailed to load the model
21002HAIR_MASK_LOSSHair mask is missing
21003FACE_NUM_ERRORInvalid number of faces
21004AR_PARSE_FAULTFailed to parse the plist in AR
21005AR_EEEOR_COUNTAR face error
21006AR_FACE_OUTAR exceeds the face range
21007JSON_ERRORInvalid JSON content
21008BACKGROUND_IMAGE_LOSSBackground image is missing
21009BODY_MASK_LOSSBody mask is missing
21010FACE_ANGLE_ERRORInvalid face angle
21011SKIN_MASK_LOSSSkin mask is missing
21012BODY_INFO_LOSSSkeleton points or outer contour points are missing
21013RECT_OUT_IMAGERectangle exceeds the image bounds
30001GEN_ERRORGeneration error

Common Error Codes and Messages

See API Error Codes.

SDK Examples

Each example signs the complete JSON body that is actually sent. The actual body contains exactly five top-level fields: task, task_type, init_images, params, and sync_timeout.

Python

import json
import requests
from sign_sdk import sign

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": {"ir_mode": 3}}
payload = {
    "task": "/v1/High_Definition_V3/466658",
    "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)
signed_request = sign.Signer(key, secret).sign(url, method, headers, body)
response = requests.Session().send(signed_request)
print(response.status_code, response.text)

Go

package main

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

func main() {
    signObj := signer.NewSigner("your_api_key", "your_api_secret")
    url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
    headers := make(http.Header)
    headers.Set(signer.HeaderHost, "openapi.meitu.com")
    headers.Set("Content-Type", "application/json")
    body := `{
  "task": "/v1/High_Definition_V3/466658",
  "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\":{\"ir_mode\":3}}",
  "sync_timeout": 30
}`
    req, err := signObj.Sign(url, http.MethodPost, headers, body)
    if err != nil { panic(err) }
    resp, err := http.DefaultClient.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    responseBody, err := io.ReadAll(resp.Body)
    if err != nil { panic(err) }
    fmt.Println(resp.StatusCode, string(responseBody))
}

PHP

<?php
require 'signer.php';

$signer = new Signer('your_api_key', 'your_api_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' => ['ir_mode' => 3],
]);
$body = json_encode([
    'task' => '/v1/High_Definition_V3/466658',
    '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);
echo "Status: {$status}\nResponse: {$response}\n";
curl_close($curl);
?>

Java

package com.meitu.openai.common;

import java.io.InputStream;
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";
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put(Signer.HeaderHost, "openapi.meitu.com");
        String body = "{\n" +
                "  \"task\":\"/v1/High_Definition_V3/466658\",\n" +
                "  \"task_type\":\"formula\",\n" +
                "  \"init_images\":[{\"url\":\"https://example.com/input.jpg\",\"profile\":{\"media_profiles\":{\"media_data_type\":\"url\"},\"version\":\"v1\"}}],\n" +
                "  \"params\":\"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"ir_mode\\\":3}}\",\n" +
                "  \"sync_timeout\":30\n" +
                "}";
        Map<String, String> signedHeaders = signer.sign(url, "POST", headers, body);
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setRequestMethod("POST");
        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();
        System.out.println("Response: " + status + " " + new String(stream.readAllBytes(), StandardCharsets.UTF_8));
    }
}