All Products
Search
Document Center

RESTful API

Last Updated: Sep 09, 2020

The RESTful API of the long-text-to-speech synthesis service allows you to send HTTP or HTTPS POST requests to upload text to be synthesized to the server. Then, the server returns the speech synthesis result of the text.

Features

The following features are supported:

  • Converts the input text to audio files in pulse-code modulation (PCM), WAV, and MP3 formats.

  • Allows you to set the sampling rates of the synthesized audio files to 8,000 Hz or 16,000 Hz.

  • Provides multiple speaker types.

  • Allows you to set the speed, intonation, and volume of the speakers.

  • Supports two methods of receiving synthesized audio data: polling and callback.

Notice

  • To ensure constant improvement of the text-to-speech (TTS) synthesis effect, more and more complex algorithms are used. Therefore, the synthesis may take a longer time. In this case, we recommend that you use stream synthesis. For more information about the sample code of stream synthesis, see the sample code in this topic and the demo project provided in the SDK.

  • We provide you with a Java demo for the RESTful API of the long-text-to-speech synthesis service. To download the Java demo, click here.

Before you begin

Endpoints

Access types

Description

URL

Host

External access from the Internet

This endpoint allows you to access the long-text-to-speech synthesis service from any host by using the Internet.

https://nls-gateway.cn-shanghai.aliyuncs.com/rest/v1/tts/async

nls-gateway.cn-shanghai.aliyuncs.com

Internal access from an Elastic Compute Service (ECS) instance located in the China (Shanghai) region

This endpoint allows you to access the long-text-to-speech synthesis service from an ECS instance located in the China (Shanghai) region by using an internal network.

http://nls-gateway.cn-shanghai-internal.aliyuncs.com/rest/v1/tts/async

nls-gateway.cn-shanghai-internal.aliyuncs.com

Notice

This topic describes how to access the long-text-to-speech synthesis service by using the Internet. To use an ECS instance located in the China (Shanghai) region to access the long-text-to-speech synthesis service in an internal network, use HTTP instead of HTTPS. In addition, replace the URL and host for Internet access with those for internal access. In this topic, all demos except the Python demo support both HTTP and HTTPS. Read the relevant notes before you use the Python demo.

Interaction process

The client sends an HTTPS POST request containing the text to be synthesized to the server. Then, the server processes the text and returns the synthesis result. The client can obtain the synthesis result by using one of the following methods:

  • The client keeps polling the synthesis result until the synthesis task is completed.

  • The client waits for the server to return the synthesis result to the specified callback URL after the server completes the speech synthesis. Before the callback is completed, the client can proceed with subsequent processing.

Note

  • Different from the RESTful API of the speech synthesis service, the RESTful API of the long-text-to-speech synthesis service does not directly return the synthesized audio data to the client. Instead, the API returns an HTTP URL that points to the synthesized audio file. You can download the audio file or play the audio by using the URL.

  • The server adds the task_id parameter to all responses to indicate the ID of the synthesis task. We recommend that you record the value of this parameter. If an error occurs, you can submit a ticket and provide the task ID to Alibaba Cloud for troubleshooting.

Request parameters

The following table describes the request parameters required for long-text-to-speech synthesis. When you send an HTTP or HTTPS POST request, you must set the parameters in the HTTP or HTTPS request body.

Parameter

Type

Required

Description

appkey

String

Yes

The appkey of the application.

token

String

No

The token used for service authentication.

text

String

Yes

The text to be synthesized, which must be UTF-8 encoded.

format

String

Yes

The audio encoding format. Valid values: pcm, wav, and mp3. Default value: pcm.

sample_rate

Integer

Yes

The audio sampling rate, in Hz. Valid values: 16000 and 8000. Default value: 16000.

voice

String

No

The speaker type. Default value: xiaoyun. For more information about other available speaker types, see Overview.

volume

Integer

No

The volume of the speaker. Valid values: 0 to 100. Default value: 50.

speech_rate

Integer

No

The speed of the speaker. Valid values: -500 to 500. Default value: 0.

pitch_rate

Integer

No

The intonation of the speaker. Valid values: -500 to 500. Default value: 0.

enable_subtitle

Boolean

No

Specifies whether to enable the sentence-level timestamp function. Default value: false.

enable_notify

Boolean

Yes

Specifies whether to enable the callback method. Default value: false.

notify_url

String

No

The callback URL. You must specify this parameter if you set the enable_notify parameter to true. The callback URL can be an HTTP or HTTPS URL. It can contain the domain name, but not the IP address.

Text upload by using the POST method

A complete POST request of the RESTful API of the long-text-to-speech synthesis service contains the following elements:

  • URL

    Protocol

    URL

    Method

    HTTPS

    https://nls-gateway.cn-shanghai.aliyuncs.com/rest/v1/tts/async

    POST

  • HTTPS POST request body

    The HTTP POST request body is a JSON string consisting of request parameters. Therefore, you must set the Content-Type parameter in the HTTP POST request header to application/json. The following code displays a sample request:

    {
        "payload":{
            "tts_request":{
                "voice":"xiaoyun",
                "sample_rate":16000,
                "format":"wav",
                "text":"It's sunny today.",
                "enable_subtitle": true
            },
            "enable_notify":false
        },
        "context":{
            "device_id":"my_device_id"
        },
        "header":{
            "appkey":"yourAppkey",
            "token":"yourToken"
        }
    }

Responses

After a request is sent, the server returns the response to the client in an HTTPS response body regardless of the request status. Check the returned data carefully. The responses to an HTTPS GET request and an HTTPS POST request are the same. The response is included in the HTTPS response body. Whether a request succeeds or fails depends on the value of the Content-Type parameter in the HTTPS response header.

  • Sample success response

    • If the synthesis is successful, the value of the Content-Type parameter in the HTTPS response header is audio/mpeg, and the synthesized audio data is included in the response body.

    • The value of the X-NLS-RequestId parameter in the HTTPS response header is the ID of the synthesis task, which can be used for debugging and troubleshooting.

    • The content of the response body is the binary data of the synthesized audio file.

  • Sample error response

    • If the synthesis fails, the HTTPS response header does not contain the Content-Type parameter or the value of the Content-Type parameter is application/json. The response body includes the error message.

    • The value of the X-NLS-RequestId parameter in the HTTPS response header is the ID of the synthesis task, which can be used for debugging and troubleshooting.

    • The response body includes the error message, which is a JSON string.

      The following table describes the parameters in the error message of a response.

      Parameter

      Type

      Description

      task_id

      String

      The 32-bit task ID. Record this value for troubleshooting.

      error_code

      Integer

      The service status code.

      error_message

      String

      The description of the service status.

The following code displays three sample responses:

  • The response to a successful request

    {
      "status":200,
      "error_code":20000000,
      "error_message":"SUCCESS",
      "request_id":"f0a9e2c49e9049e78730a3bf0b32****",
      "data":{
          "task_id":"35d9f813e00b11e9a2ce9ba0d6a2****"
      }
    }
  • The response to a failed request

    {
      "error_message":"Meta:ACCESS_DENIED:The token 'fdf' is invalid!",
      "error_code":40000001,
      "request_id":"0d8c0eea55824aada9a374aec650****",
      "url":"/rest/v1/tts/async",
      "status":400
    }
  • The success response to a request to poll the synthesis result from the server

    // Receive the intermediate synthesis result returned by the server during the polling.
    {
        "status":200,
        "error_code":20000000,
        "error_message":"RUNNING",
        "request_id":"a3370c49a29148e78b39978f98ba****",
        "data":{
            "task_id":"35d9f813e00b11e9a2ce9ba0d6a2****",
            "audio_address":null,
            "notify_custom":null
        }
    }
    // Receive the final synthesis result.
    {
        "status":200,
        "error_code":20000000,
        "error_message":"SUCCESS",
        "request_id":"c541eae489af48d69dae2d2e203a****",
        "data":{
            "sentences":[
                {
                    "text":"longtext and speech synthesis",
                    "begin_time":"0",
                    "end_time":"2239"
                },
                {
                    "text":"returns audio for all text at once. Now you need to add timestamp information at the sentence level ",
                    "begin_time":"2239",
                    "end_time":"8499"
                },
                {
                    "text":"The client can use this information to control the playback",
                    "begin_time":"8499",
                    "end_time":"12058"
                }
            ],
            "task_id":"f4e9bf53cb1611eab327b15f61b4****",
            "audio_address":"The generated url",
            "notify_custom":""
        }
    }

    Note

    The audio_address parameter indicates the HTTP URL used to download the synthesized audio file. The HTTP URL is valid for only three days.

Service Status Code

Service status code

Service status description

Solution

20000000 The request is successful. N/A
40000000 The error message returned because a client error has occurred. This is the default client error code. Check the error message or submit a ticket.
40000001 The error message returned because the client fails authentication. Check whether the token that you use is correct or whether the token expires.
40000002 The error message returned because the text is invalid. Check whether the text that is sent meets the requirement.
40000003 The error message returned because a specified parameter value is invalid. Check whether the parameter value is correct.
40000004 The error message returned because the idle status of the client times out. Check whether the client has not sent data to the server for a long time.
40000005 The error message returned because the number of requests exceeds the upper limit. Check whether the number of concurrent connections or the queries per second (QPS) exceeds the upper limit.
50000000 The error message returned because a server error has occurred. This is the default server error code. If the error message is occasionally returned, ignore it. If the error code is returned multiple times, submit a ticket.
50000001 The error message returned because an internal gRPC call error has occurred. If the error message is occasionally returned, ignore it. If the error code is returned multiple times, submit a ticket.

Java Demo

Run the following commands to add dependencies:

<dependency>
    <groupId>com.squareup.okhttp3
    <artifactId>okhttp</artifactId>
    <version>3.9.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba
    <artifactId>fastjson</artifactId>
    <version>1.2.49</version>
</dependency>

Sample code:

package com.alibaba.nls.client;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This demo demonstrates how to use long-text-to-speech synthesis.
 */
public class SpeechLongSynthesizerRestfulDemo {
    private static Logger logger = LoggerFactory.getLogger(SpeechLongSynthesizerRestfulDemo.class);
    private String accessToken;
    private String appkey;
    public SpeechLongSynthesizerRestfulDemo(String appkey, String token) {
        this.appkey = appkey;
        this.accessToken = token;
    }

    public void processPOSTRequest(String text, String format, int sampleRate, String voice) {
        String url = "https://nls-gateway.cn-shanghai.aliyuncs.com/rest/v1/tts/async";

        // Concatenate the content of the HTTP POST request body.
        JSONObject context = new JSONObject();
        // device_id: the ID of your local device or a custom string.
        context.put("device_id", "my_device_id");

        JSONObject header = new JSONObject();
        // appkey: Required. The appkey of your project.
        header.put("appkey", appkey);
        // token: Required. The token used for authentication.
        header.put("token", accessToken);

        // voice: Optional. The speaker type. Default value: xiaoyun.
        // volume: Optional. The volume of the speaker. Valid values: 0 to 100. Default value: 50.
        // speech_rate: Optional. The speed of the speaker. Valid values: -500 to 500. Default value: 0.
        // pitch_rate: Optional. The intonation of the speaker. Valid values: -500 to 500. Default value: 0.
        JSONObject tts = new JSONObject();
        tts.put("text", text);
        // Specify the speaker type.
        tts.put("voice", voice);
        // Specify the audio encoding format.
        tts.put("format", format);
        // Specify the audio sampling rate.
        tts.put("sample_rate", sampleRate);
        // Specify the volume of the speaker. This parameter is optional.
        //tts.put("volume", 100);
        // Specify the speed of the speaker. This parameter is optional.
        //tts.put("speech_rate", 200);

        JSONObject payload = new JSONObject();
        // Specify whether to enable callbacks. This configuration is optional. If you enable callbacks, the server returns the synthesis result to the specified callback URL after the synthesis task is completed.
        payload.put("enable_notify", false);
        payload.put("notify_url", "http://123.com");
        payload.put("tts_request", tts);

        JSONObject json = new JSONObject();
        json.put("context", context);
        json.put("header", header);
        json.put("payload", payload);
        String bodyContent = json.toJSONString();
        logger.info("POST Body Content: " + bodyContent);

        // Initiate a request.
        RequestBody reqBody = RequestBody.create(MediaType.parse("application/json"), bodyContent);
        Request request = new Request.Builder()
            .url(url)
            .header("Content-Type", "application/json")
            .post(reqBody)
            .build();
        try {
            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            String contentType = response.header("Content-Type");
            System.out.println("contentType = " + contentType);

            // Receive the synthesis result and process the data based on the response.
            String result = response.body().string();
            response.close();
            System.out.println("result = " + result);
            JSONObject resultJson = JSON.parseObject(result);
            if(resultJson.containsKey("error_code") && resultJson.getIntValue("error_code") == 20000000) {
                logger.info("Request Success! task_id = " + resultJson.getJSONObject("data").getString("task_id"));
                String task_id = resultJson.getJSONObject("data").getString("task_id");
                String request_id = resultJson.getString("request_id");

                // Poll and check the synthesis result from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
                waitLoop4Complete(url, appkey, accessToken, task_id, request_id);
            }else {
                logger.error("Request Error: status=" + resultJson.getIntValue("status")
                    + ", error_code=" + resultJson.getIntValue("error_code")
                    + ", error_message=" + resultJson.getString("error_message"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // Poll and check the synthesis result of a specific synthesis request from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
    private void waitLoop4Complete(String url, String appkey, String token, String task_id, String request_id) {
        String fullUrl = url + "?appkey=" + appkey + "&task_id=" + task_id + "&token=" + token + "&request_id=" + request_id;
        System.out.println("query url = " + fullUrl);
        while(true) {
            Request request = new Request.Builder().url(fullUrl).get().build();
            try {
                OkHttpClient client = new OkHttpClient();
                Response response = client.newCall(request).execute();
                String result = response.body().string();
                response.close();
                System.out.println("waitLoop4Complete = " + result);
                JSONObject resultJson = JSON.parseObject(result);
                if(resultJson.containsKey("error_code")
                    && resultJson.getIntValue("error_code") == 20000000
                    && resultJson.containsKey("data")
                    && resultJson.getJSONObject("data").getString("audio_address") != null) {
                    logger.info("Tts Finished! task_id = " + resultJson.getJSONObject("data").getString("task_id"));
                    logger.info("Tts Finished! audio_address = " + resultJson.getJSONObject("data").getString("audio_address"));
                    break;
                }else {
                    logger.info("Tts Queuing...");
                }
                // Poll the synthesis result at an interval of 3 seconds.
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("SpeechLongSynthesizerRestfulDemo need params: <token> <app-key>");
            System.exit(-1);
        }
        String token = args[0];
        String appkey = args[1];

        SpeechLongSynthesizerRestfulDemo demo = new SpeechLongSynthesizerRestfulDemo(appkey, token);
        String text = "Behind our house was a great garden known in our family as Hundred-Plant Garden. It has long since been sold, together with the house, to the descendants of Zhu Xi; and the last time I saw it, already seven or eight years ago. I am pretty sure there were only weeds growing there. But in my childhood it was my paradise." ;

        String format = "wav";
        int sampleRate = 16000;
        String voice = "siyue";
        demo.processPOSTRequest(text, format, sampleRate, voice);
    }
}

Python Demo

Note

  • Use the httplib module for Python 2.x, and use the http.client module for Python 3.x.

  • If you access the service by using an internal access URL, you must use HTTP and replace the HTTPSConnection method with the HTTPConnection method.

# -*- coding: UTF-8 -*-
# Python 2.x 
import httplib
import urllib
import urllib2
import json
import time

class TtsHeader:
    def __init__(self, appkey, token):
        self.appkey = appKey
        self.token = token
    def tojson(self, e):
        return {'appkey': e.appkey, 'token': e.token}
class TtsContext:
    def __init__(self, device_id):
        self.device_id = device_id
    # Define serialized functions to classes
    def tojson(self, e):
        return {'device_id': e.device_id}
class TtsRequest:
    def __init__(self, voice, sample_rate, format, enable_subtitle, text):
        self.voice = voice
        self.sample_rate = sample_rate
        self.format = format
        self.enable_subtitle = enable_subtitle
        self.text = text
    def tojson(self, e):
        return {'voice': e.voice, 'sample_rate': e.sample_rate, 'format': e.format, 'enable_subtitle': e.enable_subtitle, 'text': e.text}
class TtsPayload:
    def __init__(self, enable_notify, notify_url, tts_request):
        self.enable_notify = enable_notify
        self.notify_url = notify_url
        self.tts_request = tts_request
    def tojson(self, e):
        return {'enable_notify': e.enable_notify, 'notify_url': e.notify_url, 'tts_request': e.tts_request.tojson(e.tts_request)}
class TtsBody:
    def __init__(self, tts_header, tts_context, tts_payload):
        self.tts_header = tts_header
        self.tts_context = tts_context
        self.tts_payload = tts_payload
    def tojson(self, e):
        return {'header': e.tts_header.tojson(e.tts_header), 'context': e.tts_context.tojson(e.tts_context), 'payload': e.tts_payload.tojson(e.tts_payload)}

# Poll and check the synthesis result of a specific synthesis request from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
def waitLoop4Complete(url, appkey, token, task_id, request_id):
    fullUrl = url + "?appkey=" + appkey + "&task_id=" + task_id + "&token=" + token + "&request_id=" + request_id
    print "fullUrl=", fullUrl
    host = {"Host":"nls-gateway.cn-shanghai.aliyuncs.com", "Accept":"*/*", "Connection":"keep-alive",'Content-Type': 'application/json'}
    while True:
        req = urllib2.Request(url=fullUrl)
        result = urllib2.urlopen(req).read()
        print "query result = ", result
        jsonData = json.loads(result)
        if jsonData.has_key("error_code") and jsonData["error_code"] == 20000000 and jsonData.has_key("data") and (jsonData["data"]["audio_address"] != ""):
            print "Tts Finished! task_id = " + jsonData["data"]["task_id"]
            print "Tts Finished! audio_address = " + jsonData["data"]["audio_address"]
            break
        else:
            print "Tts Running..."
            time.sleep(3)

# The RESTful API of the long-text-to-speech synthesis service supports HTTP or HTTPS POST requests and does not support HTTP or HTTPS GET requests. You can specify whether to poll the synthesis result during the synthesis process or wait until the server returns the result to the URL that you specify after the synthesis task is completed.
def requestLongTts4Post(tts_body, appkey, token):
    host = 'nls-gateway.cn-shanghai.aliyuncs.com'
    url = 'https://' + host + '/rest/v1/tts/async'

    # Set the HTTP request header.
    http_headers = {'Content-Type': 'application/json'}

    print('The POST request body content: ' + tts_body)
    conn = httplib.HTTPSConnection(host)
    #conn = httplib.HTTPConnection(host)
    conn.request(method='POST', url=url, body=tts_body, headers=http_headers)
    response = conn.getresponse()
    print('Response status and response reason:')
    print(response.status ,response.reason)
    contentType = response.getheader('Content-Type')
    print(contentType)
    body = response.read()

    if response.status == 200:
        jsonData = json.loads(body)
        print 'The request succeed : ', jsonData
        print 'error_code = ', jsonData['error_code']
        task_id = jsonData['data']['task_id']
        request_id = jsonData['request_id']
        print 'task_id = ', task_id
        print 'request_id = ', request_id
        # Note: Poll and check the synthesis result from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
        waitLoop4Complete(url, appkey, token, task_id, request_id)
    else:
        print('The request failed: ' + str(body))
                
appKey = 'The appkey of your project'
token = 'The token used for authentication';
text = 'Today is Monday. It is a fine day.'

# Concatenate the content of the HTTP POST request body.
th = TtsHeader(appKey, token)
tc = TtsContext("mydevice")
# Specify the speaker type, the audio sampling rate, the audio encoding format, and the text to be synthesized.
tr = TtsRequest("xiaoyun", 16000, "wav", False, text)
# Specify whether to use a callback URL, the callback URL, and the TtsRequest object.
tp = TtsPayload(True, "http://134.com", tr)
tb = TtsBody(th, tc, tp)
body = json.dumps(tb, default=tb.tojson)
requestLongTts4Post(str(body), appKey, token)

PHP

Note

The PHP demo uses cURL methods. Ensure that you have installed PHP 4.0.2 or later and cURL extensions.

<?php
    // Poll and check the synthesis result of a specific synthesis request from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
    function waitLoop4Complete($url, $appkey, $token, $task_id, $request_id) {
        $fullUrl = $url . "?appkey=" . $appkey . "&task_id=" . $task_id . "&token=" . $token . "&request_id=" . $request_id;
        print "query url = " . $fullUrl . "\n";
        while(true) {
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($curl, CURLOPT_URL, $fullUrl);
            curl_setopt($curl, CURLOPT_HEADER, TRUE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
            $response = curl_exec($curl);
            if ($response == FALSE) {
                print "curl_exec failed!\n";
                curl_close($curl);
                return ;
            }

            // Process the response returned by the server.
            $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
            $headers = substr($response, 0, $headerSize);
            $bodyContent = substr($response, $headerSize);    
            print $bodyContent."\n";

            $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            if($http_code ! = 200) {     // Check the parameter settings of the method if the request fails.
                print "tts request failure, error code = " . $http_code . "\n";
                curl_close($curl);
                return ;
            }

            curl_close($curl);
            $data = json_decode($bodyContent, true);
            if(isset($data["error_code"]) && $data["error_code"] == 20000000
                && isset($data["data"]) && $data["data"]["audio_address"] != "") {
                print "Tts Finished! task_id = " . $data["data"]["task_id"] . "\n";
                print "Tts Finished! audio_address = " . $data["data"]["audio_address"] . "\n";
                break;
            } else {
                print "Tts Queuing..." . "\n";
            }
            // Poll the synthesis result at an interval of 3 seconds.
            sleep(3);
        }
    }

    // The RESTful API of the long-text-to-speech synthesis service supports HTTP or HTTPS POST requests and does not support HTTP or HTTPS GET requests. You can specify whether to poll the synthesis result during the synthesis process or wait until the server returns the result to the URL that you specify after the synthesis task is completed.
    function requestLongTts4Post($appkey, $token, $text, $voice, $format, $sampleRate) {
        $url = "https://nls-gateway.cn-shanghai.aliyuncs.com/rest/v1/tts/async";

        // Concatenate the content of the HTTP POST request body.
        $header = array("appkey" => $appkey, "token" => $token);
        $context = array("device_id" => "my_device_id");
        $tts_request = array("text" => $text, "format" => $format, "voice" => $voice, "sample_rate" => $sampleRate, "enable_subtitle" => false);
        $payload = array("enable_notify" => true, "notify_url" => "http://123.com", "tts_request" => $tts_request);
        $tts_body = array("context" => $context, "header" => $header, "payload" => $payload);
        $body = json_encode($tts_body);
        print "The POST request body content: " . $body . "\n";

        $httpHeaders = array("Content-Type: application/json");

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, TRUE);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $httpHeaders);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
        curl_setopt($curl, CURLOPT_HEADER, TRUE);
        $response = curl_exec($curl);
        if ($response == FALSE) {
            print "curl_exec failed!\n";
            curl_close($curl);
            return ;
        }

        $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
        $headers = substr($response, 0, $headerSize);
        $bodyContent = substr($response, $headerSize);

        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        if($http_code != 200) {
            print "tts request failure, error code = " . $http_code . "\n";
            print "tts request failure, response = " . $bodyContent . "\n";
            return ;
        }
        curl_close($curl);

        print $bodyContent . "\n";
        $data = json_decode($bodyContent, true);
        if( isset($data["error_code"]) && $data["error_code"] == 20000000) {
            $task_id = $data["data"]["task_id"];
            $request_id = $data["request_id"];
            print "Request Success! task_id = " . $task_id . "\n";
            print "Request Success! request_id = " . $request_id . "\n";
            
            // Note: Poll and check the synthesis result from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
            waitLoop4Complete($url, $appkey, $token, $task_id, $request_id);
        } else {
            print "Request Error: status=" . $data["status"] . "; error_code=" . $data["error_code"] . "; error_message=" . $data["error_message"] . "\n";
        }
    }

$appkey = "The appkey of your project";
$token = "The token used for authentication";
$text = "Today is Monday. It is a fine day." ;
$format = "wav";
$voice = "xiaogang";
$sampleRate = 16000;
requestLongTts4Post($appkey, $token, $text, $voice, $format, $sampleRate);
?>

Node.js Demo

Note

To configure the request dependencies, run the following command in the directory of your demo file:

npm install request --save
const request = require('request');
const fs = require('fs');

    // The RESTful API of the long-text-to-speech synthesis service supports HTTP or HTTPS POST requests and does not support HTTP or HTTPS GET requests. You can specify whether to poll the synthesis result during the synthesis process or wait until the server returns the result to the URL that you specify after the synthesis task is completed.
    function requestLongTts4Post(textValue, appkeyValue, tokenValue, voiceValue, formatValue, sampleRateValue) {
        var url = "https://nls-gateway.cn-shanghai.aliyuncs.com/rest/v1/tts/async"
        console.log(url);

        // Set request parameters in JSON format in the HTTPS POST request body.
        var context = {
            device_id : "device_id",
        };
        var header = {
            appkey : appkeyValue,
            token : tokenValue,
        };
        var tts_request = {
            text : textValue,
            voice : voiceValue,
            format : formatValue,
            "sample_rate" : sampleRateValue,
            "enable_subtitle" : false
        };

        var payload = {
            "enable_notify" : false,
            "notify_url": "http://123.com",
            "tts_request" : tts_request,
        };
        var tts_body = {
            "context" : context,
            "header" : header,
            "payload" : payload
        };

        var bodyContent = JSON.stringify(tts_body);
        console.log('The POST request body content: ' + bodyContent);

        // Set the HTTP POST request header.
        var httpHeaders = {'Content-type' : 'application/json'};

        // Set the HTTPS POST request.
        // Set the encoding parameter to null, and set the HTTPS response body to the binary buffer type.
        var options = {
            url: url,
            method: 'POST',
            headers: httpHeaders,
            body: bodyContent,
            encoding: null
        };

        request(options, function (error, response, body) {
            // Process the response returned by the server.
            if (error != null) {
                console.log(error);
            } else {
                if(response.statusCode != 200) {
                    console.log("Http Request Fail: " + response.statusCode + "; " + body.toString());
                    return;
                }
                console.log("response result: " + body.toString());
                var code = 0;
                var task_id = "";
                var request_id = "";
                var json = JSON.parse(body.toString());
                console.info(json);
                for(var key in json){  
                    if(key=='error_code'){
                        code = json[key]
                    } else if(key=='request_id'){
                        request_id = json[key]
                    } else if(key == "data") {
                        task_id = json[key]["task_id"];
                    }
                }
                if(code == 20000000) {
                    console.info("Request Success! task_id = " + task_id);
                    console.info("Request Success! request_id = " + request_id);
                    // Note: Poll and check the synthesis result from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
                    waitLoop4Complete(url, appkey, token, task_id, request_id);
                } else {
                    console.info("Request Error: status=" + $data["status"] + "; error_code=" + $data["error_code"] + "; error_message=" + $data["error_message"]);
                }
            }
        });
    }

    // Poll and check the synthesis result of a specific synthesis request from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
    function waitLoop4Complete(urlValue, appkeyValue, tokenValue, task_id_value, request_id_value) {
        var fullUrl = urlValue + "?appkey=" + appkeyValue + "&task_id=" + task_id_value + "&token=" + tokenValue + "&request_id=" + request_id_value;
        console.info("query url = " + fullUrl);

        //while(true) {
        var timer = setInterval(() => {
            var options = {
                url: fullUrl,
                method: 'GET'
            };
            console.info("query url = " + fullUrl);
            request(options, function (error, response, body) {
                // Process the response returned by the server.
                if (error != null) {
                    console.log(error);
                } else if(response.statusCode != 200) {
                    console.log("Http Request Fail: " + response.statusCode + "; " + body.toString());
                    return;
                } else {
                    console.log("query result: " + body.toString());
                    var code = 0;
                    var task_id = "";
                    var output_url = "";
                    var json = JSON.parse(body.toString());
                    console.info(json);
                    for(var key in json){  
                        if(key=='error_code'){
                            code = json[key]
                        } else if(key=='request_id'){
                            request_id = json[key]
                        } else if(key == "data" && json["data"] != null) {
                            task_id = json[key]["task_id"];
                            audio_address = json[key]["audio_address"];
                        }
                    }
                    if(code == 20000000 && audio_address != "") {
                        console.info("Tts Finished! task_id = " + task_id);
                        console.info("Tts Finished! audio_address = " + audio_address);
                        // End the polling.
                        clearInterval(timer);
                    } else {
                        console.info("Tts Queuing...");
                    }
                }
            }
            );
        }
    , 3000);
    }

var appkey = 'The appkey of your project';
var token = 'The token used for authentication';
var text = 'Today is Monday. It is a fine day.' ;
var voice = "xiaogang";
var format = 'wav';
var sampleRate = 16000;
requestLongTts4Post(text, appkey, token, voice, format, sampleRate);

Go Demo

package main
import (
    "fmt"
    "net/http"
    "io/ioutil"
    "encoding/json"
    "strconv"
    "bytes"
    "time"
)

// The RESTful API of the long-text-to-speech synthesis service supports HTTP or HTTPS POST requests and does not support HTTP or HTTPS GET requests. You can specify whether to poll the synthesis result during the synthesis process or wait until the server returns the result to the URL that you specify after the synthesis task is completed.
func requestLongTts4Post(text string, appkey string, token string) {
    // var url string= "http://pre-nls-gateway.aliyuncs.com:80/rest/v1/tts/async"
    var url string= "https://nls-gateway.cn-shanghai.aliyuncs.com/rest/v1/tts/async"

    // Concatenate the content of the HTTP POST request body.
    context := make(map[string]interface{})
    context["device_id"] = "test-device"

    header := make(map[string]interface{})
    header["appkey"] = appkey
    header["token"] = token

    tts_request := make(map[string]interface{})
    tts_request["text"] = text
    tts_request["format"] = "wav"
    tts_request["voice"] = "xiaogang"
    tts_request["sample_rate"] = 16000
    tts_request["enable_subtitle"] = false

    payload := make(map[string]interface{})
    payload["enable_notify"] = false
    payload["notify_url"] = "http://123.com"
    payload["tts_request"] = tts_request

    ttsBody := make(map[string]interface{})
    ttsBody["context"] = context
    ttsBody["header"] = header
    ttsBody["payload"] = payload
    
    ttsBodyJson, err := json.Marshal(ttsBody)
    if err != nil {
        panic(nil)
    }
    fmt.Println(string(ttsBodyJson))

    // Send the HTTPS POST request and process the response returned by the server.
    response, err := http.Post(url, "application/json;charset=utf-8", bytes.NewBuffer([]byte(ttsBodyJson)))
    if err != nil {
        panic(err)
    }
    defer response.Body.Close()
    contentType := response.Header.Get("Content-Type")
    body, _ := ioutil.ReadAll(response.Body)
    fmt.Println(string(contentType))
    fmt.Println(string(body))
    
    statusCode := response.StatusCode
    if(statusCode == 200) {
        fmt.Println("The POST request succeed!")
        var f interface{}
        err := json.Unmarshal(body, &f)
        if err != nil {
            fmt.Println(err)
        }
        // Obtain the task ID and request ID from the request body. The task ID is important, which facilitates troubleshooting.
        var taskId string = ""
        var requestId string = ""
        m := f.(map[string]interface{})
        for k, v := range m {
            if(k == "error_code") {
                fmt.Println("error_code = ", v)
            } else if(k == "request_id") {
                fmt.Println("request_id = ", v)
                requestId = v.(string)
            } else if(k == "data") {
                fmt.Println("data = ", v)
                data := v.(map[string]interface{})
                fmt.Println(data)
                taskId = data["task_id"].(string)
            }
        }

        // Note: Poll and check the synthesis result from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
        waitLoop4Complete(url, appkey, token, taskId, requestId)
    } else {
        fmt.Println("The POST request failed: " + string(body))
        fmt.Println("The HTTP statusCode: " + strconv.Itoa(statusCode))
    } 
}

// Poll and check the synthesis result of a specific synthesis request from the server during the synthesis process. The polling is optional. If you specify a callback URL, the server returns the synthesis result to the callback URL after the synthesis task is completed.
func waitLoop4Complete(url string, appkey string, token string, task_id string, request_id string) {
    var fullUrl string = url + "?appkey=" + appkey + "&task_id=" + task_id + "&token=" + token + "&request_id=" + request_id
    fmt.Println("fullUrl=" + fullUrl)
    for { 
        response, err := http.Get(fullUrl)
        if err != nil {
            fmt.Println("The GET request failed!")
            panic(err)
        }
        defer response.Body.Close()    
        body, _ := ioutil.ReadAll(response.Body)
        fmt.Println("waitLoop4Complete = ", string(body))

        var f interface{}
        json.Unmarshal(body, &f)
        if err != nil {
            fmt.Println(err)
        }

        // Obtain the task ID and request ID from the request body. The task ID is important, which facilitates troubleshooting.
        var code float64 = 0
        var taskId string = ""
        var audioAddress string = ""
        m := f.(map[string]interface{})
        for k, v := range m {
            if(k == "error_code") {
                code = v.(float64)
            } else if(k == "request_id") {
            } else if(k == "data") {
                if (v != nil) {
                    data := v.(map[string]interface{})
                    taskId = data["task_id"].(string)
                    audioAddress = data["audio_address"].(string)
                }
            }
        }

        if (code == 20000000 && audioAddress != "") {
            fmt.Println("Tts Finished! task_id = " + taskId);
            fmt.Println("Tts Finished! audio_address = " + audioAddress);
            break
        } else {
            time.Sleep(time.Duration(3)*time.Second)
        }
    }   
}

func main() {
    var appkey string = "The appkey of your project"
    var token  string = "The token used for authentication"
    var text string = "Today is Monday. It is a fine day."

    requestLongTts4Post(text, appkey, token)
}