Whiteboard Drawing v3

Description

Generates an image in a specified style from an input sketch. You can specify the sketch background type, generation style, canvas expansion, and output dimensions.

Version

1.0

Image Requirements

Supports JPG and PNG. Supply the image as a URL or Base64-encoded data.

Request URL

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

HTTP Method

POST

Content-Type: application/json

Authentication

Sign requests with an Access Key (AK) and Secret Key (SK). See API Request Signing.

Credits cannot be used to pay for API calls. Please visit the MV console to activate this API and purchase or manage resource packages.

Request Parameters

RequiredParameterTypeDescription
YestaskstringFixed value: /v1/AI_Drawing_White_V3/426943.
Yestask_typestringFixed value: formula.
Yesinit_imagesobject[]Input sketch image list.
YesparamsstringAlgorithm parameters serialized as a JSON string. Decoded fields are described below.
Nosync_timeoutintSynchronous wait timeout in seconds. Default: 30. Query the task for results after the wait expires.

init_images Item

RequiredParameterTypeDescription
YesurlstringImage URL or Base64-encoded data. Do not Base64-encode a URL.
YesprofileobjectImage properties.

profile

RequiredParameterTypeDescription
Yesmedia_profilesobjectImage transmission information.
YesversionstringFixed value: v1.
Nomedia_extraobjectAdditional image information. Use {} when no additional information is needed.

media_profiles

RequiredParameterTypeDescription
Yesmedia_data_typestringurl for an image URL; jpg for Base64-encoded data. Set it explicitly for the input type; the algorithm default is jpg.

params

The following fields belong directly to the object decoded from params. Serialize this object first, then assign the resulting string to the request's params field.

RequiredParameterTypeDescription
Yesscribble_bg_typeintSketch background type: 0 for white, 1 for black. The algorithm defaults to black; provide the value explicitly.
Yesscribble_style_typestringGeneration style identifier. Contact your account representative for available values; replace the placeholder YOUR_STYLE_ID.
Nopadding_typeintCanvas expansion: 0 to leave unchanged, 1 to expand. Default: 0.
NoheightintOutput height in pixels. Range: [100, 2048]; recommended: 1024. Takes precedence over the input image height.
NowidthintOutput width in pixels. Range: [100, 2048]; recommended: 1024. Takes precedence over the input image width.

Request Example

The example uses a sketch with a white background, no canvas expansion, and a 1024 × 1024 output. Replace the image URL and YOUR_STYLE_ID before calling the API.

{
  "task": "/v1/AI_Drawing_White_V3/426943",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://example.com/input.png",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"scribble_bg_type\":0,\"scribble_style_type\":\"YOUR_STYLE_ID\",\"padding_type\":0,\"height\":1024,\"width\":1024}",
  "sync_timeout": 30
}

Response Fields

Generated results are cleaned up periodically. Download and save them promptly.

On success, read output image URLs from data.result.urls. A successful HTTP response does not necessarily mean the task has completed; also check data.status.

Successful Response Fields

FieldTypeDescription
error_codeintError code; 0 indicates normal request processing.
messagestringResponse message.
dataobjectTask status, progress, and result.

data

FieldTypeDescription
statusintTask status: -1 not found; 0 created; 1 running; 2 failed; 9 synchronous wait expired, query required; 10 succeeded.
resultobjectTask identifier and result.
progressnumberTask progress, for example 0.1, 0.85, or 1.

result

FieldTypeDescription
idstringGateway task ID. Pass it as task_id when querying the task.
urlsstring[]Output image URLs available when the task succeeds.

Failed Response Fields

FieldTypeDescription
ErrorCodeintError code.
ErrorMsgstringError message.
Datastring/nullError details; null in the example below.

Failure field names are case-sensitive. Preserve ErrorCode, ErrorMsg, and Data exactly as shown.

Response Examples

Successful Response

Response Status: 200

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

{
  "error_code": 0,
  "message": "success",
  "data": {
    "status": 10,
    "result": {
      "id": "example-task-id",
      "urls": [
        "https://example.com/result.jpeg"
      ]
    },
    "progress": 1
  }
}

When a Query Is Required

When data.status = 9, the synchronous wait has expired; this does not mean the task failed. Use the task ID with the Task Query API to retrieve the result.

The documented task ID field for this API is data.result.id. Query status 0 or 1 means the task is not yet complete; 10 means success and 2 means failure.

Failed Response

Response Status: 400

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

{
  "ErrorCode": 20001,
  "ErrorMsg": "PROCESS_ERROR",
  "Data": null
}

API-Specific Error Codes

CodeMessageDescription
20001PROCESS_ERRORProcessing error.
20014NOT_FOUNDImage not found.
20008UNSUITABLE_IMAGEImage does not meet the requirements.
20026NO_SUCH_MODESpecified mode does not exist.
20034NO_SUCH_STYLESpecified style does not exist.
21008BACKGROUND_IMAGE_LOSSBackground image is missing.
20025INIT_FAILInitialization failed.
21021MASK_LOSSMask is missing.
21022SKETCH_LOSSSketch is missing.

Common Error Codes and Messages

See API Error Codes.

SDK Examples

All examples use the request parameters above. Replace AK, SK, the image URL, and YOUR_STYLE_ID, and install or include the signing SDK following the guide for your language.

The examples print the response. If the task is not complete, retrieve results with the Task Query API.

Python

Python Signing SDK Guide

import json

import requests
from sign_sdk import sign

def main():
    key = "YOUR_ACCESS_KEY"
    secret = "YOUR_SECRET_KEY"
    url = "https://openapi.meitu.com/api/v1/sdk/sync/push"
    params = {
        "scribble_bg_type": 0,
        "scribble_style_type": "YOUR_STYLE_ID",
        "padding_type": 0,
        "height": 1024,
        "width": 1024
    }
    payload = {
        "task": "/v1/AI_Drawing_White_V3/426943",
        "task_type": "formula",
        "init_images": [{
            "url": "https://example.com/input.png",
            "profile": {
                "media_profiles": {"media_data_type": "url"},
                "version": "v1",
            },
        }],
        "params": json.dumps(params, ensure_ascii=True),
        "sync_timeout": 30,
    }
    body = json.dumps(payload, ensure_ascii=True)
    headers = {
        "Content-Type": "application/json",
        sign.HeaderHost: "openapi.meitu.com",
    }
    signer = sign.Signer(key, secret)
    signed_request = signer.sign(url, "POST", headers, body)
    with requests.Session() as session:
        response = session.send(
            signed_request, timeout=(10, 60), verify=True, allow_redirects=False
        )
        print("Status:", response.status_code)
        print("Response:", response.text)

if __name__ == "__main__":
    main()

Go

Go Signing SDK Guide

package main

import (
    "fmt"
    "io"
    "net/http"
    "time"

    "github.com/mtlab/api/signer"
)

func main() {
    url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
    body := `{
  "task": "/v1/AI_Drawing_White_V3/426943",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://example.com/input.png",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"scribble_bg_type\":0,\"scribble_style_type\":\"YOUR_STYLE_ID\",\"padding_type\":0,\"height\":1024,\"width\":1024}",
  "sync_timeout": 30
}`
    headers := make(http.Header)
    headers.Set("Content-Type", "application/json")
    headers.Set(signer.HeaderHost, "openapi.meitu.com")
    signObj := signer.NewSigner("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY")
    req, err := signObj.Sign(url, http.MethodPost, headers, body)
    if err != nil {
        fmt.Println("Sign request failed:", err)
        return
    }
    client := &http.Client{
        Timeout: 60 * time.Second,
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            return http.ErrUseLastResponse
        },
    }
    resp, err := client.Do(req)
    if err != nil {
        fmt.Println("Send request failed:", err)
        return
    }
    defer resp.Body.Close()
    responseBody, err := io.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Read response failed:", err)
        return
    }
    fmt.Println("Status:", resp.StatusCode)
    fmt.Println("Response:", string(responseBody))
}

PHP

PHP Signing SDK Guide

<?php
require_once __DIR__ . '/signer.php';

$params = json_encode([
    'scribble_bg_type' => 0,
    'scribble_style_type' => 'YOUR_STYLE_ID',
    'padding_type' => 0,
    'height' => 1024,
    'width' => 1024,
]);
$body = json_encode([
    'task' => '/v1/AI_Drawing_White_V3/426943',
    'task_type' => 'formula',
    'init_images' => [[
        'url' => 'https://example.com/input.png',
        'profile' => [
            'media_profiles' => ['media_data_type' => 'url'],
            'version' => 'v1',
        ],
    ]],
    'params' => $params,
    'sync_timeout' => 30,
], JSON_UNESCAPED_SLASHES);
$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$headers = [
    'Content-Type' => 'application/json',
    'Host' => 'openapi.meitu.com',
];
$signer = new Signer('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');
$curl = $signer->sign($url, 'POST', $headers, $body);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
$response = curl_exec($curl);
if ($response === false) {
    echo 'Error: ' . curl_error($curl) . PHP_EOL;
} else {
    echo 'Status: ' . curl_getinfo($curl, CURLINFO_HTTP_CODE) . PHP_EOL;
    echo 'Response: ' . $response . PHP_EOL;
}
curl_close($curl);

Java

Java Signing SDK Guide

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 {
        String body =
                "{\n" +
                "  \"task\": \"/v1/AI_Drawing_White_V3/426943\",\n" +
                "  \"task_type\": \"formula\",\n" +
                "  \"init_images\": [\n" +
                "    {\n" +
                "      \"url\": \"https://example.com/input.png\",\n" +
                "      \"profile\": {\n" +
                "        \"media_profiles\": {\n" +
                "          \"media_data_type\": \"url\"\n" +
                "        },\n" +
                "        \"version\": \"v1\"\n" +
                "      }\n" +
                "    }\n" +
                "  ],\n" +
                "  \"params\": \"{\\\"scribble_bg_type\\\":0,\\\"scribble_style_type\\\":\\\"YOUR_STYLE_ID\\\",\\\"padding_type\\\":0,\\\"height\\\":1024,\\\"width\\\":1024}\",\n" +
                "  \"sync_timeout\": 30\n" +
                "}";
        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");
        Signer signer = new Signer("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");
        Map<String, String> signedHeaders = signer.sign(url, "POST", headers, body);
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        try {
            connection.setRequestMethod("POST");
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(60000);
            connection.setInstanceFollowRedirects(false);
            connection.setDoOutput(true);
            for (Map.Entry<String, String> entry : signedHeaders.entrySet()) {
                connection.setRequestProperty(entry.getKey(), entry.getValue());
            }
            byte[] bodyBytes = body.getBytes(StandardCharsets.UTF_8);
            connection.setFixedLengthStreamingMode(bodyBytes.length);
            try (OutputStream output = connection.getOutputStream()) {
                output.write(bodyBytes);
            }
            int status = connection.getResponseCode();
            System.out.println("Status: " + status);
            InputStream stream = status >= 400
                    ? connection.getErrorStream() : connection.getInputStream();
            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();
        }
    }
}