Whiteboard Doodle

Description

This API processes requests to generate images from whiteboard doodles in the cloud. See the details below for information about its capabilities.

Version

1.0

Image Requirements

Supported image formats: JPG and PNG.

API URL

    Production host: https://openapi.meitu.com
    Task submission endpoint: https://openapi.meitu.com/api/v1/sdk/sync/push
    Task name (task): 426943
    Task type (task_type): formula

Method

POST

Content-Type: application/json

Authentication

Open Platform API Signature

Request Parameters

RequiredParameterTypeDescription
YesparamsstringAlgorithm parameters as a JSON string
Yesinit_imagesobject[]Input media list
YestaskstringFixed value: 426943
Yestask_typestringFixed value: formula
Nosync_timeoutintSynchronous timeout in seconds; default: 30

init_images item fields:

RequiredParameterTypeDescription
YesurlstringImage URL or base64-encoded image
YesprofileobjectMedia profile

profile fields:

RequiredParameterTypeDescription
Yesmedia_profilesobjectMedia attributes
YesversionstringFixed value: v1

media_profiles fields:

RequiredParameterTypeDescription
Yesmedia_data_typestringurl indicates an image URL; jpg indicates a base64-encoded image and is the default used by the original API

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

RequiredFieldTypeDescription
Norsp_media_typestringDefault: url; jpg indicates base64 output
YesparameterobjectAlgorithm-specific parameters

parameter fields:

RequiredParameterTypeDescription
Yesscribble_bg_typeintDoodle background type: 0 for a white background and 1 for a black background; default: black background
Yesscribble_style_typestringEffect style; contact your business representative for details
Nopadding_typeintWhether to expand the dimensions: 0 keeps them unchanged and 1 expands them; default: unchanged
NoheightintRecommended value: 1024. Takes precedence over the input image height and must be between 100 px and 2048 px
NowidthintRecommended value: 1024. Takes precedence over the input image width and must be between 100 px and 2048 px

Request Example

{
  "task": "426943",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://wheeai.meitudata.com/share/6667bcd7971600705hOla3ufuw3778.jpeg",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"scribble_bg_type\":0,\"scribble_style_type\":\"效果\",\"padding_type\":0,\"height\":1024,\"width\":1024}}",
  "sync_timeout": 30
}

Response Fields

Generated results are cleaned up periodically. Download and save them promptly.
FieldTypeDescription
request_idstringRequest identifier
trace_idstringTrace identifier
codeintBusiness status code; 0 means the request was accepted
error_codeintError code; 0 on success
messagestringBusiness message
tipsanyAdditional information; may be null
dataobjectTask status and algorithm result

data fields:

FieldTypeDescription
statusint-1: task not found; 0: created; 1: running; 2: failed; 9: timed out and requires the query API; 10: succeeded
resultobjectAlgorithm result
progressnumberTask progress
predict_elapsedintEstimated processing time in milliseconds
create_timeint64Creation timestamp in milliseconds
task_idstringTask ID
custom_task_idstringClient-supplied custom task ID
trace_idstringTrace identifier inside data
client_infostringClient information
init_imagesobject[]/nullEcho of input media

result fields:

FieldTypeDescription
idstringTask ID
urlsstring[]Image URLs

Response Examples

Success

Response Status: 200

Content-Type: application/json; charset=utf-8

{
  "request_id": "req_426943_success",
  "trace_id": "trace_426943_success",
  "code": 0,
  "error_code": 0,
  "message": "success",
  "tips": null,
  "data": {
    "status": 10,
    "result": {
      "id": "t_mt1a3i5n7b7e45698e-7212-4bae-ac7e-9766498c71a5",
      "urls": [
        "https://obs-large.mtlab.meitu.com/mtopen/23e48d1b186e4d75b5769628d98e0496/MTcxODE3MjAwMA==/d4772377-35b3-474b-53b9-674f992d53b0.jpeg"
      ]
    },
    "progress": 1,
    "predict_elapsed": 0,
    "create_time": 1718172000000,
    "task_id": "t_mt1a3i5n7b7e45698e-7212-4bae-ac7e-9766498c71a5",
    "custom_task_id": "",
    "trace_id": "trace_426943_success",
    "client_info": "",
    "init_images": null
  }
}

Query Required

Use the query API to retrieve the task result.

Response Status: 200

Content-Type: application/json; charset=utf-8

{
  "request_id": "req_426943_pending",
  "trace_id": "trace_426943_pending",
  "code": 0,
  "error_code": 0,
  "message": "success",
  "tips": null,
  "data": {
    "status": 9,
    "result": {},
    "progress": 0.85,
    "predict_elapsed": 1000,
    "create_time": 1718172000000,
    "task_id": "t_mt1a3i5n7b7e45698e-7212-4bae-ac7e-9766498c71a5",
    "custom_task_id": "",
    "trace_id": "trace_426943_pending",
    "client_info": "",
    "init_images": null
  }
}

Failure

Response Status: 400

Content-Type: application/json; charset=utf-8

{
  "request_id": "req_426943_failure",
  "trace_id": "trace_426943_failure",
  "code": 20001,
  "error_code": 20001,
  "message": "PROCESS_ERROR",
  "tips": null,
  "data": {
    "status": 2,
    "result": {
      "ErrorCode": 20001,
      "ErrorMsg": "PROCESS_ERROR",
      "Data": null
    },
    "progress": 0,
    "predict_elapsed": 0,
    "create_time": 1718172000000,
    "task_id": "",
    "custom_task_id": "",
    "trace_id": "trace_426943_failure",
    "client_info": "",
    "init_images": null
  }
}

API-Specific Error Codes and Messages

ErrorCodeErrorDescription
20001PROCESS_ERRORProcessing error
20014NOT_FOUNDImage not found
20008UNSUITABLE_IMAGEThe image does not meet the requirements
20026NO_SUCH_MODEThe specified mode does not exist
20034NO_SUCH_STYLEThe specified style does not exist
21008BACKGROUND_IMAGE_LOSSBackground image missing
20025INIT_FAILInitialization failed
21021MASK_LOSSMask missing
21022SKETCH_LOSSSketch missing

General Error Codes

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": {
            "scribble_bg_type": 0,
            "scribble_style_type": "效果",
            "padding_type": 0,
            "height": 1024,
            "width": 1024,
        },
    }
    payload = {
        "task": "426943",
        "task_type": "formula",
        "init_images": [
            {
                "url": "https://wheeai.meitudata.com/share/6667bcd7971600705hOla3ufuw3778.jpeg",
                "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": "426943",
  "task_type": "formula",
  "init_images": [{
    "url": "https://wheeai.meitudata.com/share/6667bcd7971600705hOla3ufuw3778.jpeg",
    "profile": {
      "media_profiles": {"media_data_type": "url"},
      "version": "v1"
    }
  }],
  "params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"scribble_bg_type\":0,\"scribble_style_type\":\"效果\",\"padding_type\":0,\"height\":1024,\"width\":1024}}",
  "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' => [
        'scribble_bg_type' => 0,
        'scribble_style_type' => '效果',
        'padding_type' => 0,
        'height' => 1024,
        'width' => 1024,
    ],
]);

$body = json_encode([
    'task' => '426943',
    'task_type' => 'formula',
    'init_images' => [
        [
            'url' => 'https://wheeai.meitudata.com/share/6667bcd7971600705hOla3ufuw3778.jpeg',
            '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\": \"426943\",\n" +
                "  \"task_type\": \"formula\",\n" +
                "  \"init_images\": [{\n" +
                "    \"url\": \"https://wheeai.meitudata.com/share/6667bcd7971600705hOla3ufuw3778.jpeg\",\n" +
                "    \"profile\": {\n" +
                "      \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
                "      \"version\": \"v1\"\n" +
                "    }\n" +
                "  }],\n" +
                "  \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"scribble_bg_type\\\":0,\\\"scribble_style_type\\\":\\\"效果\\\",\\\"padding_type\\\":0,\\\"height\\\":1024,\\\"width\\\":1024}}\",\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);
        }
    }
}