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): formulaMethod
POST
Content-Type: application/json
Authorization
Request Parameters
The request body always consists of the following five top-level fields:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | params | string | Inference parameters serialized as a JSON string |
| Yes | init_images | object[] | List of image files; only URL input is currently supported |
| Yes | task | string | Fixed at /v1/High_Definition_V3/466658 for a synchronous task or /v1/High_Definition_V3/466659 for an asynchronous task |
| Yes | task_type | string | Fixed at formula |
| No | sync_timeout | int | Default: 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
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | url | string | Image address; only URLs are currently supported |
| No | profile | object | Media parameters |
profile media parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | media_extra | object | Additional media parameters; the source document does not define its inner fields |
| No | media_profiles | object | Media description |
| No | version | string | The request example in the source document uses v1 |
media_profiles media description
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | media_data_type | string | url 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:
| Required | Field | Type | Description |
|---|---|---|---|
| No | rsp_media_type | string | Common response media type. Default: url. jpg returns the result image as base64; url returns it as a URL |
| Yes | parameter | object | Image 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
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | ir_mode | int | Effect mode. Default: 3. 3 selects Wink HD mode (V3); 4 selects Meitu HD and Wink portrait enhancement |
| No | save_photo_format | int | Saved image format. Default: 1. 1 means JPG; 2 means PNG |
| No | use_denoise | int | Whether to enable background restoration. Default: 1. 1 enables it; 0 disables it |
| No | use_hd_face_opt | int | Whether to enable upgraded portrait restoration. Default: 0. 1 enables it; 0 disables it |
| No | max_width | int | Maximum width of the returned image. Default: -1 |
| No | max_height | int | Maximum height of the returned image. Default: -1 |
| No | repost_url | string | POST callback URL provided by the client |
| No | sr_num | int | Default: 4 |
| No | return_format_type | string | Returned 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
| Field | Type | Description |
|---|---|---|
| request_id | string | Request identifier |
| trace_id | string | Trace identifier |
| code | int | Business status code; 0 means the request was accepted successfully |
| error_code | int | Error code; 0 on success |
| message | string | Business or error message |
| tips | any | Additional tips; may be null |
| data | object | Task status and algorithm result |
data fields
| Field | Type | Description |
|---|---|---|
| status | int | -1: task not found; 0: created; 1: running; 2: failed; 9: use the query API; 10: succeeded |
| result | object | Algorithm result |
| progress | number | Task progress |
| predict_elapsed | int | Estimated duration in milliseconds |
| create_time | int64 | Creation timestamp in milliseconds |
| task_id | string | Task ID |
| custom_task_id | string | Client-defined task ID |
| trace_id | string | Trace identifier |
| client_info | string | Client information |
| init_images | object[]/null | Echoed input media |
result fields on success
| Field | Type | Description |
|---|---|---|
| id | string | Task ID; can be used to query task status |
| media_info_list | object[] | List of media results |
| parameter | object | Returned information type indicator |
A single media_info_list element
| Field | Type | Description |
|---|---|---|
| media_data | string | JPG base64 when media_data_type is jpg; an image URL when it is url |
| media_profiles | object | Media file attributes |
Returned parameter fields
| Field | Type | Description |
|---|---|---|
| rsp_media_type | string | jpg means media_data is JPG base64; url means it is an image URL |
Returned media_profiles fields
| Field | Type | Description |
|---|---|---|
| media_data_type | string | jpg means media_data is JPG base64; url means it is an image URL |
result fields on failure
| Field | Type | Description |
|---|---|---|
| ErrorCode | int | Algorithm error code |
| ErrorMsg | string | Algorithm error message |
| Data | string/null | Detailed 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
| ErrorCode | Error Message | Description |
|---|---|---|
| 20001 | PROCESS_ERROR | Processing error |
| 20003 | DETECT_NOT_FACE | No face detected |
| 20004 | MORE_THAN_ONE_FACE | More than one face detected |
| 20007 | MISSING_LANDMARK_ARGUMENTS | Facial landmark points were not provided |
| 20008 | UNSUITABLE_IMAGE | The photo does not meet the requirements |
| 20009 | UNSUPPORT_TYPE | Unsupported type |
| 20010 | DETECT_NOT_FACE | No face detected in the second image |
| 20011 | UNSUITABLE_VERTICAL_IMAGE | Vertical height requirement not met |
| 20012 | UNSUITABLE_HORIZONTAL_IMAGE | Horizontal width requirement not met |
| 20013 | RESOLUTION_TOO_LARGE_ERROR | Resolution is too high |
| 20014 | NOT_FOUND | Image not found |
| 20015 | PICTURE_OVERRUN_ERROR | Image exceeds the limit |
| 20020 | DETECT_FACE_OUTOFIMAGE | Facial features are missing |
| 20021 | DETECT_FACE_PITCHANGLE_BIG | The face is not frontal; nodding or pitch angle is too large |
| 20022 | DETECT_FACE_YAWANGLE_BIG | The face is not frontal; head turn or rotation angle is too large |
| 20023 | DETECT_FACE_LOWAREA | Face area is too small or pixel count is too low |
| 21001 | LOAD_MODEL_ERROR | Failed to load the model |
| 21002 | HAIR_MASK_LOSS | Hair mask is missing |
| 21003 | FACE_NUM_ERROR | Invalid number of faces |
| 21004 | AR_PARSE_FAULT | Failed to parse the plist in AR |
| 21005 | AR_EEEOR_COUNT | AR face error |
| 21006 | AR_FACE_OUT | AR exceeds the face range |
| 21007 | JSON_ERROR | Invalid JSON content |
| 21008 | BACKGROUND_IMAGE_LOSS | Background image is missing |
| 21009 | BODY_MASK_LOSS | Body mask is missing |
| 21010 | FACE_ANGLE_ERROR | Invalid face angle |
| 21011 | SKIN_MASK_LOSS | Skin mask is missing |
| 21012 | BODY_INFO_LOSS | Skeleton points or outer contour points are missing |
| 21013 | RECT_OUT_IMAGE | Rectangle exceeds the image bounds |
| 30001 | GEN_ERROR | Generation 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));
}
}