Speech Synthesis

Description

This API starts a speech synthesis task. After the task is submitted successfully, it is executed asynchronously. You can actively query the algorithm result through the query API or receive the result at the callback URL configured in the request.

Version

1.0

Media Requirements

The speech synthesis algorithm itself does not require an input image or other media file. The unified gateway requires the init_images field to contain a media element; the example uses the JPG format listed in the original image-format field. This media element is not used as an algorithm parameter for speech synthesis.

API URL

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

Method

POST

Content-Type: application/json

Authentication

Open Platform API Signature

Request Parameters

RequiredParameterTypeDescription
YesparamsstringAlgorithm parameters (JSON string)
Yesinit_imagesobject[]Media file list. The unified gateway requires a media element, but the algorithm itself does not use it
YestaskstringFixed value: /v1/tts_synthesis/481979
Yestask_typestringFixed value: formula
Nosync_timeoutintDefault: 30. -1 means do not wait. When synchronous execution times out, status is 9; use the query API to retrieve the result

The init_images media-file parameter has the following structure. The speech synthesis algorithm itself does not require media input, but the unified gateway requires a media element.

RequiredParameterTypeDescription
YesurlstringMedia URL or base64 data; the example uses a JPG URL
YesprofileobjectAttribute information

The profile attribute information has the following structure.

RequiredParameterTypeDescription
Yesmedia_profilesobjectMedia attributes
YesversionstringFixed value: v1

The media_profiles media attributes have the following structure.

RequiredParameterTypeDescription
Yesmedia_data_typestringurl indicates a URL; a type such as jpg indicates base64 data

The params inference parameter is a JSON string with the following structure.

RequiredFieldTypeDescription
Norsp_media_typestringDefault: url; jpg indicates base64 data
YesparameterobjectCore algorithm parameter object

Details of the parameter algorithm parameters:

RequiredFieldTypeDescription
Yestimbre_idIntegerVoice ID
YestextStringSource text to synthesize into speech
NospeedStringSpeech rate. Supports 0.5–2.0 with one decimal place. This feature is available only for voices that support SSML tags
NostyleStringEmotional style. This feature is available only for voices that support SSML tags
Noemotion_scaleIntegerEmotional intensity. Must be an integer from 1 to 5

Request Example

{
  "task": "/v1/tts_synthesis/481979",
  "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\":{\"timbre_id\":17,\"text\":\"测试接口连通性\"}}",
  "sync_timeout": 30
}

Response Fields

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

Fields in data:

FieldTypeDescription
statusintStatus code: -1 task not found; 0 created successfully; 1 running; 2 failed; 9 timed out—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_idstringCustom task ID supplied by the client
trace_idstringTrace identifier within data
client_infostringClient information
init_imagesobject[]/nullEchoed input media

Fields in result:

FieldTypeDescription
idstringAlgorithm task ID
urlsstring[]List of synthesized speech URLs
parametersobjectParameters returned by the algorithm
dataobjectData object returned by the algorithm
msgstringAlgorithm processing message
msg_idstringAlgorithm message ID
imagesstring[]List of media URLs returned by the algorithm; in this API's example, these are synthesized speech URLs
media_info_listobject[]List of media information returned by the algorithm
codeintAlgorithm error code, returned on failure

Fields in parameters:

FieldTypeDescription
bypass_cacheintReturned bypass_cache parameter
channelstringReturned channel parameter
client_idintReturned client_id parameter
emotion_scaleintReturned emotion_scale parameter
ext_voice_idstringReturned ext_voice_id parameter
idintReturned id parameter
is_emointReturned is_emo parameter
is_support_ssmlintReturned is_support_ssml parameter
is_syncintReturned is_sync parameter
repost_urlstringReturned repost_url parameter
speedstringReturned speed parameter
stat_gidintReturned stat_gid parameter
stylestringReturned style parameter
textstringSource text synthesized into speech
timbre_idintVoice ID
uidintReturned uid parameter
versionstringReturned version parameter
volumeintReturned volume parameter
with_timestampintReturned with_timestamp parameter

Fields in each media_info_list element:

FieldTypeDescription
media_datastringSynthesized speech URL
media_extraobjectExtended media information
media_profilesobjectMedia attributes; media_data_type is url in the example

Algorithm-specific error codes and messages:

Error CodeError MessageDescription
20001PROCESS_ERRORProcessing 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_mt1a3i5n7ba95988c3-7e15-427e-b7e3-ad599217c282",
      "urls": [
        "http://voice.meitudata.com/audio/1759221923c5584b63582de6cb639aa97392454f4b100.mp3"
      ],
      "parameters": {
        "bypass_cache": 0,
        "channel": "",
        "client_id": 0,
        "emotion_scale": 0,
        "ext_voice_id": "",
        "id": 0,
        "is_emo": 0,
        "is_support_ssml": 0,
        "is_sync": 0,
        "repost_url": "https://koios-gateway-api.meitu.com/api/v1/task/notify?task_id=t_mt1a3i5n7ba95988c3-7e15-427e-b7e3-ad599217c282\u0026trace_id=a71d1ea3-874c-47b8-8f9c-da5a972af8c1",
        "speed": "",
        "stat_gid": 0,
        "style": "",
        "text": "测试接口连通性",
        "timbre_id": 17,
        "uid": 0,
        "version": "",
        "volume": 0,
        "with_timestamp": 0
      },
      "data": {},
      "msg": "success",
      "msg_id": "voice-cf80bdff-c0bc-4579-aac9-15bad1b97bb8",
      "images": [
        "http://voice.meitudata.com/audio/1759221923c5584b63582de6cb639aa97392454f4b100.mp3"
      ],
      "media_info_list": [
        {
          "media_data": "http://voice.meitudata.com/audio/1759221923c5584b63582de6cb639aa97392454f4b100.mp3",
          "media_extra": {},
          "media_profiles": {
            "media_data_type": "url"
          }
        }
      ]
    },
    "progress": 1,
    "predict_elapsed": 10000,
    "create_time": 1759222172863,
    "task_id": "t_mt1a3i5n7ba95988c3-7e15-427e-b7e3-ad599217c282",
    "custom_task_id": "",
    "trace_id": "a71d1ea3-874c-47b8-8f9c-da5a972af8c1",
    "client_info": "",
    "init_images": null
  }
}

Pending Query 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_mt1a3i5n7b3da6d589-46b5-4f66-a0bb-8dd22f2a172e"
    },
    "progress": 0,
    "predict_elapsed": 10000,
    "create_time": 1759202368761,
    "task_id": "t_mt1a3i5n7b3da6d589-46b5-4f66-a0bb-8dd22f2a172e",
    "custom_task_id": "",
    "trace_id": "9129a3a2-99c4-46ce-8731-0e100e2fbee7",
    "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": "ALGO_MODEL_CRASH",
  "tips": null,
  "data": {
    "status": 2,
    "result": {
      "id": "t_mt1a3i5n7be8d575cc-2ffb-4e0c-85a8-1824110e31b8",
      "code": 20001,
      "data": {
        "duration": {
          "alg_process_time": 0,
          "created_timestamp": 1759201989,
          "pull_timestamp": 1759201989,
          "repost_time": 0,
          "upload_time": 0,
          "waiting_time": 0
        },
        "error_code": 20001,
        "error_msg": "ALGO_MODEL_CRASH",
        "extra": {},
        "media_info_list": [],
        "msg_id": "c1b09cb2-6e05-4d21-55ab-r007b1f21bec",
        "parameter": null
      },
      "msg": "ALGO_MODEL_CRASH",
      "msg_id": "c1b09cb2-6e05-4d21-55ab-r007b1f21bec"
    },
    "progress": 1,
    "predict_elapsed": 10000,
    "create_time": 1759201989444,
    "task_id": "t_mt1a3i5n7be8d575cc-2ffb-4e0c-85a8-1824110e31b8",
    "custom_task_id": "",
    "trace_id": "",
    "client_info": "",
    "init_images": null
  }
}

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": {
            "timbre_id": 17,
            "text": "测试接口连通性",
        },
    }
    payload = {
        "task": "/v1/tts_synthesis/481979",
        "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)

    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/tts_synthesis/481979",
  "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\":{\"timbre_id\":17,\"text\":\"测试接口连通性\"}}",
  "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' => [
        'timbre_id' => 17,
        'text' => '测试接口连通性',
    ],
]);

$body = json_encode([
    'task' => '/v1/tts_synthesis/481979',
    '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);

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/tts_synthesis/481979\",\n" +
                "  \"task_type\": \"formula\",\n" +
                "  \"init_images\": [{\n" +
                "    \"url\": \"https://example.com/input.jpg\",\n" +
                "    \"profile\": {\n" +
                "      \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
                "      \"version\": \"v1\"\n" +
                "    }\n" +
                "  }],\n" +
                "  \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"timbre_id\\\":17,\\\"text\\\":\\\"测试接口连通性\\\"}}\",\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);
        }
    }
}