Body Keypoint Detection
Description
This API processes body detection requests in the cloud and returns body keypoint detection information for people in an image.
Version
1.0
Image Requirements
Supported 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/Body_Keypoint_Detection/487158
Task type (task_type): formulaMethod
POST
Content-Type: application/json
Authentication
Request Parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | params | string | Algorithm parameters (JSON string) |
| Yes | init_images | object[] | Media file list |
| Yes | task | string | Fixed value: /v1/Body_Keypoint_Detection/487158 |
| Yes | task_type | string | Fixed value: formula |
| No | sync_timeout | int | Synchronization timeout; default: 30 |
The init_images media file parameters are described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | url | string | Image URL or Base64-encoded data |
| Yes | profile | object | Attribute information |
The profile attribute information is described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_profiles | object | Media attribute information |
| Yes | version | string | Fixed value: v1 |
The media_profiles media attribute information is described below.
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_data_type | string | url indicates a URL; formats such as jpg indicate Base64-encoded data |
The params inference parameter is a JSON string with the following structure.
| Required | Field | Type | Description |
|---|---|---|---|
| No | rsp_media_type | string | Default: url; jpg returns the resulting image in Base64-encoded format, while url returns it as a URL |
| Yes | parameter | object | Core algorithm parameter object |
Details of the parameter algorithm parameters:
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | version | string | Algorithm version; default: 1.0.0 |
Request Example
{
"task": "/v1/Body_Keypoint_Detection/487158",
"task_type": "formula",
"init_images": [
{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTcwOTE4MjgwMA==/58fdb25d-8e6f-4026-4a5e-45d9894190a4.png",
"profile": {
"media_profiles": {
"media_data_type": "url"
},
"version": "v1"
}
}
],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"version\":\"1.0.0\"}}",
"sync_timeout": 30
}Response Fields
Note: Generated results are periodically deleted. Download and save them promptly.| Field | Type | Description |
|---|---|---|
| request_id | string | Request identifier |
| trace_id | string | Trace identifier |
| code | int | Business status code; 0 indicates that the request was accepted successfully |
| error_code | int | Error code; 0 indicates success |
| message | string | Business message |
| tips | any | Additional information; may be null |
| data | object | Task status and algorithm result |
Fields in data are described below.
| Field | Type | Description |
|---|---|---|
| status | int | Status code: -1, task not found; 0, created successfully; 1, processing; 2, failed; 9, timed out—use the Query API; 10, succeeded |
| result | object | Algorithm result |
| progress | number | Task progress |
| predict_elapsed | int | Estimated processing time, 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 |
Fields in result are described below.
| Field | Type | Description |
|---|---|---|
| id | string | Unique task identifier |
| urls | string[] | Result resource URL list |
| images | string[] | Returned image resources |
| parameters | object | Algorithm parameter information, including the string-type version |
| data | object | Raw algorithm response data |
| mtlab_res | object | Raw MTLab result |
| media_info_list | object[] | Media result information list |
Fields in result.data and result.mtlab_res are described below.
| Field | Type | Description |
|---|---|---|
| ErrorCode | int | Algorithm error code; 0 indicates success |
| ErrorMsg | string | Algorithm error message |
| error_code | int | Same as ErrorCode |
| error_msg | string | Same as ErrorMsg |
| media_info_list | object[] | Media result information list |
| msg_id | string | Message ID |
| parameter | object | Algorithm parameters, including the string-type version |
Fields in media_info_list are described below.
| Field | Type | Description |
|---|---|---|
| media_data | string | Media data, such as an image URL or Base64-encoded data |
| media_extra | object | Additional algorithm result |
| media_profiles | object/null | Media configuration parameters |
Fields in media_extra are described below.
| Field | Type | Description |
|---|---|---|
| body_pose | array | Body detection information containing body keypoints for N people in the image. Each person has 14 points, and each point is represented as [x, y, score]. See Body Keypoint Index Reference for the keypoint order. |
Fields for each keypoint in body_pose are described below.
| Field | Type | Description |
|---|---|---|
| x | float | Horizontal coordinate of the keypoint, using the top-left corner of the image as (0, 0); the example value range is 0~1 |
| y | float | Vertical coordinate of the keypoint, using the top-left corner of the image as (0, 0); the example value range is 0~1 |
| score | float | Keypoint confidence score in the range [0, 1]; a higher value indicates greater confidence in the predicted point |
Each triplet represents one keypoint. [0, 0, 0] indicates that the keypoint was not detected. The array order follows the keypoint order defined by the algorithm.
API-specific error codes and messages:
| ErrorCode Status Code | Error Message | Description |
|---|---|---|
| 20001 | PROCESS_ERROR | Processing error |
Response Examples
Successful Response Example
{
"request_id": "",
"trace_id": "",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 10,
"result": {
"id": "t_mt1a3i5n7bfb3cb4d5-xxxx-416c-aca2-4ea85e2392d0",
"urls": [""],
"images": [""],
"parameters": {
"version": "1.0.0"
},
"data": {
"ErrorCode": 0,
"ErrorMsg": "",
"error_code": 0,
"error_msg": "",
"media_info_list": [
{
"media_data": "",
"media_extra": {
"body_pose": [
[
[0.382604, 0.237499, 0.960717],
[0.397724, 0.353015, 0.89843],
[0.313316, 0.413948, 0.875583],
[0.5135, 0.376142, 0.862831],
[0.31644, 0.526003, 0.829664],
[0.600144, 0.489705, 0.841293],
[0.480908, 0.576402, 0.791474],
[0.602069, 0.600498, 0.751575],
[0.415567, 0.600929, 0.638177],
[0.550402, 0.588666, 0.609929],
[0.31724, 0.587703, 0.800953],
[0.617525, 0.65204, 0.0674782],
[0.433666, 0.826302, 0.819607],
[0, 0, 0]
]
]
},
"media_profiles": null
}
],
"msg_id": "",
"parameter": {
"version": "1.0.0"
}
},
"mtlab_res": {
"ErrorCode": 0,
"ErrorMsg": "",
"error_code": 0,
"error_msg": "",
"media_info_list": [
{
"media_data": "",
"media_extra": {
"body_pose": [
[
[0.382604, 0.237499, 0.960717],
[0.397724, 0.353015, 0.89843],
[0.313316, 0.413948, 0.875583],
[0.5135, 0.376142, 0.862831],
[0.31644, 0.526003, 0.829664],
[0.600144, 0.489705, 0.841293],
[0.480908, 0.576402, 0.791474],
[0.602069, 0.600498, 0.751575],
[0.415567, 0.600929, 0.638177],
[0.550402, 0.588666, 0.609929],
[0.31724, 0.587703, 0.800953],
[0.617525, 0.65204, 0.0674782],
[0.433666, 0.826302, 0.819607],
[0, 0, 0]
]
]
},
"media_profiles": null
}
],
"msg_id": "",
"parameter": {
"version": "1.0.0"
}
},
"media_info_list": [
{
"media_data": "",
"media_extra": {
"body_pose": [
[
[0.382604, 0.237499, 0.960717],
[0.397724, 0.353015, 0.89843],
[0.313316, 0.413948, 0.875583],
[0.5135, 0.376142, 0.862831],
[0.31644, 0.526003, 0.829664],
[0.600144, 0.489705, 0.841293],
[0.480908, 0.576402, 0.791474],
[0.602069, 0.600498, 0.751575],
[0.415567, 0.600929, 0.638177],
[0.550402, 0.588666, 0.609929],
[0.31724, 0.587703, 0.800953],
[0.617525, 0.65204, 0.0674782],
[0.433666, 0.826302, 0.819607],
[0, 0, 0]
]
]
},
"media_profiles": null
}
]
},
"progress": 0,
"predict_elapsed": 10000,
"create_time": 1770357763826,
"task_id": "t_mt1a3i5n7bfb3cb4d5-xxxx-416c-aca2-4ea85e2392d0",
"custom_task_id": "",
"trace_id": "",
"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": "",
"trace_id": "",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 9,
"result": {
"id": "t_mt1a3i5n7b7a7ba41b-xxxx-4cdb-a0be-1fd951bd1ffc"
},
"progress": 0,
"predict_elapsed": 10000,
"create_time": 1770283596272,
"task_id": "t_mt1a3i5n7b7a7ba41b-xxxx-4cdb-a0be-1fd951bd1ffc",
"custom_task_id": "",
"trace_id": "1e106f37-xxxx-4f2c-8bb2-f480ebae4dda",
"client_info": "",
"init_images": null
}
}Failed Response Example
Response Status: 400
Content-Type: application/json; charset=utf-8
{
"request_id": "",
"trace_id": "",
"code": 20001,
"error_code": 20001,
"message": "PROCESS_ERROR",
"tips": null,
"data": {
"status": 2,
"result": {
"ErrorCode": 20001,
"ErrorMsg": "PROCESS_ERROR"
},
"progress": 0,
"predict_elapsed": 0,
"create_time": 0,
"task_id": "",
"custom_task_id": "",
"trace_id": "",
"client_info": "",
"init_images": null
}
}General Error Codes and Messages
For details, see API Error Codes.
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": {"version": "1.0.0"},
}
payload = {
"task": "/v1/Body_Keypoint_Detection/487158",
"task_type": "formula",
"init_images": [
{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTcwOTE4MjgwMA==/58fdb25d-8e6f-4026-4a5e-45d9894190a4.png",
"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/Body_Keypoint_Detection/487158",
"task_type": "formula",
"init_images": [{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTcwOTE4MjgwMA==/58fdb25d-8e6f-4026-4a5e-45d9894190a4.png",
"profile": {
"media_profiles": {"media_data_type": "url"},
"version": "v1"
}
}],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"version\":\"1.0.0\"}}",
"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' => ['version' => '1.0.0'],
]);
$body = json_encode([
'task' => '/v1/Body_Keypoint_Detection/487158',
'task_type' => 'formula',
'init_images' => [
[
'url' => 'https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTcwOTE4MjgwMA==/58fdb25d-8e6f-4026-4a5e-45d9894190a4.png',
'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/Body_Keypoint_Detection/487158\",\n" +
" \"task_type\": \"formula\",\n" +
" \"init_images\": [{\n" +
" \"url\": \"https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTcwOTE4MjgwMA==/58fdb25d-8e6f-4026-4a5e-45d9894190a4.png\",\n" +
" \"profile\": {\n" +
" \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
" \"version\": \"v1\"\n" +
" }\n" +
" }],\n" +
" \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"version\\\":\\\"1.0.0\\\"}}\",\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);
}
}
}