All Products
Search
Document Center

Intelligent Speech Interaction:RESTful API

Last Updated:Sep 08, 2026

The speech synthesis RESTful API converts text to speech through HTTPS GET or POST requests and returns audio in the response body. It supports configurable audio formats, sample rates, voices, speech rates, pitch, and volume.

Features

The API supports PCM, WAV, and MP3 audio and a range of voices. Audio formats and sample rates are configured through request parameters.

Important
  • Each request accepts up to 300 characters. Excess characters are truncated. Split longer text into segments, synthesize each segment, and then concatenate the audio.

  • Synthesis time depends on the text and model. Stream the response to process audio as it arrives instead of waiting for the entire response. Keep the connection open until the response has been read completely.

Prerequisites

Endpoint

Use the AppKey and token for the service region. The examples use the public HTTPS endpoint.

Region

Request URL

Singapore

https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts

Examples

Replace the AppKey and token placeholders with valid credentials. Do not log tokens, complete URLs that contain tokens, or request bodies that contain tokens. Each language example demonstrates GET and POST requests. Java also includes a streaming example.

Java

Dependencies

Add the following dependencies to the Maven project's pom.xml:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.9.1</version>
</dependency>
<!-- http://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version>
</dependency>
<dependency>
    <groupId>org.asynchttpclient</groupId>
    <artifactId>async-http-client</artifactId>
    <version>2.5.4</version>
</dependency>

Standard requests

import java.io.File;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import com.alibaba.fastjson.JSONObject;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class SpeechSynthesizerRestfulDemo {
    private String accessToken;
    private String appkey;
    public SpeechSynthesizerRestfulDemo(String appkey, String token) {
        this.appkey = appkey;
        this.accessToken = token;
    }
    /**
     * HTTPS GET request
     */
    public void processGETRequet(String text, String audioSaveFile, String format, int sampleRate, String voice) {
        /**
         * Configure the HTTPS GET request:
         * 1. Use the HTTPS protocol.
         * 2. Speech Synthesis service domain name: nls-gateway-ap-southeast-1.aliyuncs.com
         * 3. Speech Synthesis API request path: /stream/v1/tts
         * 4. Set the parameters used in this example: appkey, token, text, format, and sample_rate.
         * 5. Set the optional request parameters: voice, volume, speech_rate, and pitch_rate.
         */
        String url = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts";
        url = url + "?appkey=" + appkey;
        url = url + "&token=" + accessToken;
        url = url + "&text=" + text;
        url = url + "&format=" + format;
        url = url + "&voice=" + voice;
        url = url + "&sample_rate=" + String.valueOf(sampleRate);
        // voice: The speaker's voice. Optional. Default value: xiaoyun.
        // url = url + "&voice=" + "xiaoyun";
        // volume: The volume. The value ranges from 0 to 100. Optional. Default value: 50.
        // url = url + "&volume=" + String.valueOf(50);
        // speech_rate: The speech rate. The value ranges from -500 to 500. Optional. Default value: 0.
        // url = url + "&speech_rate=" + String.valueOf(0);
        // pitch_rate: The pitch rate. The value ranges from -500 to 500. Optional. Default value: 0.
        // url = url + "&pitch_rate=" + String.valueOf(0);
        /**
         * Send the HTTPS GET request and process the response from the server.
         */
        Request request = new Request.Builder().url(url).get().build();
        try {
            long start = System.currentTimeMillis();
            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            System.out.println("total latency :" + (System.currentTimeMillis() - start) + " ms");
            System.out.println(response.headers().toString());
            String contentType = response.header("Content-Type");
            if ("audio/mpeg".equals(contentType)) {
                File f = new File(audioSaveFile);
                FileOutputStream fout = new FileOutputStream(f);
                fout.write(response.body().bytes());
                fout.close();
                System.out.println("The GET request succeeded!");
            }
            else {
                // The Content-Type is null or "application/json".
                String errorMessage = response.body().string();
                System.out.println("The GET request failed: " + errorMessage);
            }
            response.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * HTTPS POST request
     */
    public void processPOSTRequest(String text, String audioSaveFile, String format, int sampleRate, String voice) {
        /**
         * Configure the HTTPS POST request:
         * 1. Use the HTTPS protocol.
         * 2. Speech Synthesis service domain name: nls-gateway-ap-southeast-1.aliyuncs.com
         * 3. Speech Synthesis API request path: /stream/v1/tts
         * 4. Set the parameters used in this example: appkey, token, text, format, and sample_rate.
         * 5. Set the optional request parameters: voice, volume, speech_rate, and pitch_rate.
         */
        String url = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts";
        JSONObject taskObject = new JSONObject();
        taskObject.put("appkey", appkey);
        taskObject.put("token", accessToken);
        taskObject.put("text", text);
        taskObject.put("format", format);
        taskObject.put("voice", voice);
        taskObject.put("sample_rate", sampleRate);
        // voice: The speaker's voice. Optional. Default value: xiaoyun.
        // taskObject.put("voice", "xiaoyun");
        // volume: The volume. The value ranges from 0 to 100. Optional. Default value: 50.
        // taskObject.put("volume", 50);
        // speech_rate: The speech rate. The value ranges from -500 to 500. Optional. Default value: 0.
        // taskObject.put("speech_rate", 0);
        // pitch_rate: The pitch rate. The value ranges from -500 to 500. Optional. Default value: 0.
        // taskObject.put("pitch_rate", 0);
        String bodyContent = taskObject.toJSONString();
        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");
            if ("audio/mpeg".equals(contentType)) {
                File f = new File(audioSaveFile);
                FileOutputStream fout = new FileOutputStream(f);
                fout.write(response.body().bytes());
                fout.close();
                System.out.println("The POST request succeeded!");
            }
            else {
                // The Content-Type is null or "application/json".
                String errorMessage = response.body().string();
                System.out.println("The POST request failed: " + errorMessage);
            }
            response.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("SpeechSynthesizerRestfulDemo needs params: <token> <app-key>");
            System.exit(-1);
        }
        String token = args[0];
        String appkey = args[1];
        SpeechSynthesizerRestfulDemo demo = new SpeechSynthesizerRestfulDemo(appkey, token);
        String text = "Today is Monday. The weather is nice.";
        // URL-encode the text based on RFC 3986.
        String textUrlEncode = text;
        try {
            textUrlEncode = URLEncoder.encode(textUrlEncode, "UTF-8")
                .replace("+", "%20")
                .replace("*", "%2A")
                .replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(textUrlEncode);
        String audioSaveFile = "syAudio.wav";
        String format = "wav";
        int sampleRate = 16000;
        demo.processGETRequet(textUrlEncode, audioSaveFile, format, sampleRate, "siyue");
        //demo.processPOSTRequest(text, audioSaveFile, format, sampleRate, "siyue");
        System.out.println("### Game Over ###");
    }
}

Streaming responses

Receive audio chunks through response callbacks. Keep callbacks short. Hand off audio to another thread for playback or further processing.

import java.io.File;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.concurrent.CountDownLatch;
import io.netty.handler.codec.http.HttpHeaders;
import org.asynchttpclient.AsyncHandler;
import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.AsyncHttpClientConfig;
import org.asynchttpclient.DefaultAsyncHttpClient;
import org.asynchttpclient.DefaultAsyncHttpClientConfig;
import org.asynchttpclient.HttpResponseBodyPart;
import org.asynchttpclient.HttpResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * This example demonstrates how to:
 * 1. Call the RESTful API for Speech Synthesis.
 * 2. Handle a streaming response by enabling HTTP chunked transfer encoding.
 */
public class SpeechSynthesizerRestfulChunkedDemo {
    private static Logger logger = LoggerFactory.getLogger(SpeechSynthesizerRestfulChunkedDemo.class);
    private String accessToken;
    private String appkey;
    public SpeechSynthesizerRestfulChunkedDemo(String appkey, String token) {
        this.appkey = appkey;
        this.accessToken = token;
    }
    public void processGETRequest(String text, String audioSaveFile, String format, int sampleRate, String voice, boolean chunked) {
        /**
         * Configure the HTTPS GET request:
         * 1. Protocol: HTTPS
         * 2. Speech Synthesis Endpoint: nls-gateway-ap-southeast-1.aliyuncs.com
         * 3. Request Path: /stream/v1/tts
         * 4. Parameters used in this example: appkey, token, text, format, and sample_rate
         * 5. Optional parameters: voice, volume, speech_rate, and pitch_rate
         * 6. Use the `chunk` parameter to enable HTTP chunked transfer encoding.
         */
        String url = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts";
        url = url + "?appkey=" + appkey;
        url = url + "&token=" + accessToken;
        url = url + "&text=" + text;
        url = url + "&format=" + format;
        url = url + "&voice=" + voice;
        url = url + "&sample_rate=" + String.valueOf(sampleRate);
        url = url + "&chunk=" + String.valueOf(chunked);
        try {
            AsyncHttpClientConfig config = new DefaultAsyncHttpClientConfig.Builder()
                .setConnectTimeout(3000)
                .setKeepAlive(true)
                .setReadTimeout(10000)
                .setRequestTimeout(50000)
                .setMaxConnections(1000)
                .setMaxConnectionsPerHost(200)
                .setPooledConnectionIdleTimeout(-1)
                .build();
            AsyncHttpClient httpClient = new DefaultAsyncHttpClient(config);
            CountDownLatch latch = new CountDownLatch(1);
            AsyncHandler<org.asynchttpclient.Response> handler = new AsyncHandler<org.asynchttpclient.Response>() {
                FileOutputStream outs;
                boolean firstRecvBinary = true;
                long startTime = System.currentTimeMillis();
                int httpCode = 200;
                @Override
                public State onStatusReceived(HttpResponseStatus httpResponseStatus) throws Exception {
                    logger.info("onStatusReceived status {}", httpResponseStatus);
                    httpCode = httpResponseStatus.getStatusCode();
                    if (httpResponseStatus.getStatusCode() != 200) {
                        logger.error("request error " +  httpResponseStatus.toString());
                    }
                    return State.CONTINUE;
                }
                @Override
                public State onHeadersReceived(HttpHeaders httpHeaders) throws Exception {
                    if (httpCode != 200 || !"audio/mpeg".equals(httpHeaders.get("Content-Type"))) {
                        throw new java.io.IOException("Unexpected synthesis response: HTTP " + httpCode);
                    }
                    outs = new FileOutputStream(new File(audioSaveFile));
                    return State.CONTINUE;
                }
                @Override
                public State onBodyPartReceived(HttpResponseBodyPart httpResponseBodyPart) throws Exception {
                    // Note: For improved responsiveness, play or process the audio stream immediately upon receiving the first data chunk.
                    // Note: Do not perform time-consuming operations in this callback. Push the binary Speech Synthesis audio stream to another thread asynchronously or by using a queue.
                    logger.info("onBodyPartReceived " + httpResponseBodyPart.getBodyPartBytes().toString());
                    if(httpCode != 200) {
                        System.err.write(httpResponseBodyPart.getBodyPartBytes());
                    }
                    if (firstRecvBinary) {
                        firstRecvBinary = false;
                        // Track the First Packet Latency. You can start audio processing (e.g., playback or sending to the caller) as soon as the first packet is received.
                        // Note: This First Packet Latency also includes the time to establish the network connection.
                        logger.info("tts first latency " + (System.currentTimeMillis() - startTime) + " ms");
                    }
                    // In this example, the audio stream is saved to a file.
                    outs.write(httpResponseBodyPart.getBodyPartBytes());
                    return State.CONTINUE;
                }
                @Override
                public void onThrowable(Throwable throwable) {
                    logger.error("Synthesis request failed: {}", throwable.getClass().getSimpleName());
                    if (outs != null) {
                        try { outs.close(); } catch (java.io.IOException ignored) { }
                    }
                    latch.countDown();
                }
                @Override
                public org.asynchttpclient.Response onCompleted() throws Exception {
                    logger.info("completed");
                    logger.info("tts total latency " + (System.currentTimeMillis() - startTime) + " ms");
                    outs.close();
                    latch.countDown();
                    return null;
                }
            };
            httpClient.prepareGet(url).execute(handler);
            // Wait for the synthesis to complete.
            latch.await();
            httpClient.close();
        }catch (Exception e) {
        }
    }
    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("SpeechSynthesizerRestfulDemo requires the following parameters:  ");
            System.exit(-1);
        }
        String token = args[0];
        String appkey = args[1];
        SpeechSynthesizerRestfulChunkedDemo demo = new SpeechSynthesizerRestfulChunkedDemo(appkey, token);
        String text = "今天是周一,天气挺好的。";
        // URL-encode the text based on RFC 3986.
        String textUrlEncode = text;
        try {
            textUrlEncode = URLEncoder.encode(textUrlEncode, "UTF-8")
                .replace("+", "%20")
                .replace("*", "%2A")
                .replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(textUrlEncode);
        String audioSaveFile = "syAudio.wav";
        String format = "wav";
        int sampleRate = 16000;
        // Setting the last parameter to true enables HTTP chunked transfer encoding.
        demo.processGETRequest(textUrlEncode, audioSaveFile, format, sampleRate, "aixia", true);
        System.out.println("### Demo finished ###");
    }
}

For a complete example of splitting and synthesizing long text, download nls-restful-java-demo.zip.

C++

Note
  • Download the C++ demo.

    The C++ demo uses cURL to handle HTTPS requests and responses, and JsonCpp to generate the JSON string for the POST request body.

  • Minimum runtime requirements for Linux: Glibc 2.5 or later, and GCC 4 or GCC 5.

  • To compile on Windows, decompress the windows.zip package in the lib directory.

The sample directory contains the following:

  • CMakeLists.txt: The CMake configuration file for the demo project.

  • demo: Contains sample source code.

    File name

    Description

    restfulTtsDemo.cpp

    Demonstrates how to use the Speech Synthesis RESTful API.

  • include: Contains header files for third-party libraries.

    Directory name

    Description

    curl

    Header files for the cURL library.

    json

    Header files for the JsonCpp library.

  • lib: Contains the cURL and JsonCpp dynamic libraries.

    Load the appropriate library based on your operating system and environment:

    • Linux (requires Glibc 2.5 or later, and GCC 4 or 5)

    • Windows (requires Visual Studio 2013 or 2015)

  • readme.txt: The Readme file.

  • release.log: The release notes.

  • version: The version number.

  • build.sh: The build script for the demo.

To compile and run the demo:

Assuming the demo has been extracted to path/to, run the following commands in a Linux terminal to compile and run the program.

  • If you use CMake:

    1. Ensure that CMake 2.4 or later is installed.

    2. cd path/to/sdk/lib

    3. tar -zxvpf linux.tar.gz

    4. cd path/to/sdk

    5. ./build.sh

    6. cd path/to/sdk/demo

    7. ./restfulTtsDemo <your-token> <your-appkey>

  • If you do not use CMake:

    1. cd path/to/sdk/lib.

    2. tar -zxvpf linux.tar.gz

    3. cd path/to/sdk/demo

    4. g++ -o restfulTtsDemo restfulTtsDemo.cpp -I path/to/sdk/include -L path/to/sdk/lib/linux -ljsoncpp -lssl -lcrypto -lcurl -D_GLIBCXX_USE_CXX11_ABI=0

    5. export LD_LIBRARY_PATH=path/to/sdk/lib/linux/

    6. ./restfulTtsDemo <your-token> <your-appkey>

Sample code:

#ifdef _WIN32
#include <Windows.h>
#endif
#include <iostream>
#include <string>
#include <map>
#include <fstream>
#include <sstream>
#include "curl/curl.h"
#include "json/json.h"
using namespace std;
#ifdef _WIN32
string GBKToUTF8(const string &strGBK) {
    string strOutUTF8 = "";
    WCHAR * str1;
    int n = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0);
    str1 = new WCHAR[n];
    MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, str1, n);
    n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
    char * str2 = new char[n];
    WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
    strOutUTF8 = str2;
    delete[] str1;
    str1 = NULL;
    delete[] str2;
    str2 = NULL;
    return strOutUTF8;
}
#endif
void stringReplace(string& src, const string& s1, const string& s2) {
    string::size_type pos = 0;
    while ((pos = src.find(s1, pos)) != string::npos) {
        src.replace(pos, s1.length(), s2);
        pos += s2.length();
    }
}
string urlEncode(const string& src) {
    CURL* curl = curl_easy_init();
    char* output = curl_easy_escape(curl, src.c_str(), src.size());
    string result(output);
    curl_free(output);
    curl_easy_cleanup(curl);
    return result;
}
size_t responseHeadersCallback(void* ptr, size_t size, size_t nmemb, void* userdata)
{
    map<string, string> *headers = (map<string, string>*)userdata;
    string line((char*)ptr, size * nmemb);
    string::size_type pos = line.find(':');
    if (pos != line.npos)
    {
        string name = line.substr(0, pos);
        string value = line.substr(pos + 2);
        size_t p = 0;
        if ((p = value.rfind('\r')) != value.npos) {
            value = value.substr(0, p);
        }
        headers->insert(make_pair(name, value));
    }
    return size * nmemb;
}
size_t responseBodyCallback(void* ptr, size_t size, size_t nmemb, void* userData) {
    size_t len = size * nmemb;
    char* pBuf = (char*)ptr;
    string* bodyContent = (string*)userData;
    (*bodyContent).append(string(pBuf, pBuf + len));
    return len;
}
int processGETRequest(string appKey, string token, string text, 
                      string audioSaveFile, string format, int sampleRate) {
    CURL* curl = NULL;
    CURLcode res;
    curl = curl_easy_init();
    if (curl == NULL) {
        return -1;
    }
    string url = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts";
    /**
     * Construct the request URL with parameters.
     */
    ostringstream oss;
    oss << url;
    oss << "?appkey=" << appKey;
    oss << "&token=" << token;
    oss << "&text=" << text;
    oss << "&format=" << format;
    oss << "&sample_rate=" << sampleRate;
    // voice: The voice for synthesis. Optional. Default: xiaoyun.
    // oss << "&voice=" << "xiaoyun";
    // volume: The output volume. Optional. Valid range: 0 to 100. Default: 50.
    // oss << "&volume=" << 50;
    // speech_rate: The speech rate. Optional. Valid range: -500 to 500. Default: 0.
    // oss << "&speech_rate=" << 0;
    // pitch_rate: The pitch. Optional. Valid range: -500 to 500. Default: 0.
    // oss << "&pitch_rate=" << 0;
    string request = oss.str();
    curl_easy_setopt(curl, CURLOPT_URL, request.c_str());
    /**
     * Set the callback function for response headers.
     */
    map<string, string> responseHeaders;
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeadersCallback);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    /**
     * Set the callback function for the response body.
     */
    string bodyContent = "";
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseBodyCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bodyContent);
    /**
     * Send the HTTPS GET request.
     */
    res = curl_easy_perform(curl);
    /**
     * Release resources.
     */
    curl_easy_cleanup(curl);
    if (res != CURLE_OK) {
        cerr << "curl_easy_perform failed: " << curl_easy_strerror(res) << endl;
        return -1;
    }
    /**
     * Process the response from the server.
     */
    map<string, string>::iterator it = responseHeaders.find("Content-Type");
    if (it != responseHeaders.end() && it->second.compare("audio/mpeg") == 0) {
        ofstream fs;
        fs.open(audioSaveFile.c_str(), ios::out | ios::binary);
        if (!fs.is_open()) {
            cout << "Cannot open the audio save file.";
            return -1;
        }
        fs.write(bodyContent.c_str(), bodyContent.size());
        fs.close();
        cout << "GET request succeeded." << endl;
    }
    else {
        cout << "The GET request failed: " + bodyContent << endl;
        return -1;
    }
    return 0;
}
int processPOSTRequest(string appKey, string token, string text,
                       string audioSaveFile, string format, int sampleRate) {
    CURL* curl = NULL;
    CURLcode res;
    curl = curl_easy_init();
    if (curl == NULL) {
        return -1;
    }
    string url = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts";
    /**
     * Set the URL for the HTTPS POST request.
     */
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_POST, 1L);
    /**
     * Set the request headers.
     */
    struct curl_slist* headers = NULL;
    // Content-Type
    headers = curl_slist_append(headers, "Content-Type:application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    /**
     * Construct the request body.
     */
    Json::Value root;
    Json::FastWriter writer;
    root["appkey"] = appKey;
    root["token"] = token;
    root["text"] = text;
    root["format"] = format;
    root["sample_rate"] = sampleRate;
    // voice: The voice for synthesis. Optional. Default: xiaoyun.
    // root["voice"] = "xiaoyun";
    // volume: The output volume. Optional. Valid range: 0 to 100. Default: 50.
    // root["volume"] = 50;
    // speech_rate: The speech rate. Optional. Valid range: -500 to 500. Default: 0.
    // root["speech_rate"] = 0;
    // pitch_rate: The pitch. Optional. Valid range: -500 to 500. Default: 0.
    // root["pitch_rate"] = 0;
    string task = writer.write(root);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, task.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, task.length());
    /**
     * Set the callback function for response headers.
     */
    map<string, string> responseHeaders;
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeadersCallback);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    /**
     * Set the callback function for the response body.
     */
    string bodyContent = "";
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseBodyCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bodyContent);
    /**
     * Send the HTTPS POST request.
     */
    res = curl_easy_perform(curl);
    /**
     * Release resources.
     */
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    if (res != CURLE_OK) {
        cerr << "curl_easy_perform failed: " << curl_easy_strerror(res) << endl;
        return -1;
    }
    /**
     * Process the response from the server.
     */
    map<string, string>::iterator it = responseHeaders.find("Content-Type");
    if (it != responseHeaders.end() && it->second.compare("audio/mpeg") == 0) {
        ofstream fs;
        fs.open(audioSaveFile.c_str(), ios::out | ios::binary);
        if (!fs.is_open()) {
            cout << "Cannot open the audio save file.";
            return -1;
        }
        fs.write(bodyContent.c_str(), bodyContent.size());
        fs.close();
        cout << "The POST request succeeded." << endl;
    }
    else {
        cout << "The POST request failed: " + bodyContent << endl;
        return -1;
    }
    return 0;
}
int main(int argc, char* argv[]) {
    if (argc < 3) {
        cerr << "Invalid parameters. Usage: ./demo your_token your_appkey" << endl;
        return -1;
    }
    string token = argv[1];
    string appKey = argv[2];
    string text = "Today is Monday, and the weather is nice.";
#ifdef _WIN32
    text = GBKToUTF8(text);
#endif
    string textUrlEncode = urlEncode(text);
    stringReplace(textUrlEncode, "+", "%20");
    stringReplace(textUrlEncode, "*", "%2A");
    stringReplace(textUrlEncode, "%7E", "~");
    string audioSaveFile = "syAudio.wav";
    string format = "wav";
    int sampleRate = 16000;
    // Initialize cURL. This should be done only once per process.
    curl_global_init(CURL_GLOBAL_ALL);
    processGETRequest(appKey, token, textUrlEncode, audioSaveFile, format, sampleRate);
    //processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate);
    curl_global_cleanup();
    return 0;
}

Python

Python 3 uses http.client and urllib.parse. For Python 2, use httplib and urllib as shown in the code comments.

# -*- coding: UTF-8 -*-
# Import httplib for Python 2.x.
# import httplib
# Import http.client for Python 3.x.
import http.client
# Import urllib for Python 2.x.
# import urllib
# Import urllib.parse for Python 3.x.
import urllib.parse
import json
def processGETRequest(appKey, token, text, audioSaveFile, format, sampleRate) :
    host = 'nls-gateway-ap-southeast-1.aliyuncs.com'
    url = 'https://' + host + '/stream/v1/tts'
    # Set the request parameters in the URL.
    url = url + '?appkey=' + appKey
    url = url + '&token=' + token
    url = url + '&text=' + text
    url = url + '&format=' + format
    url = url + '&sample_rate=' + str(sampleRate)
    # voice: Optional. The voice. Default: xiaoyun.
    # url = url + '&voice=' + 'xiaoyun'
    # volume: Optional. The audio volume. Range: 0-100. Default: 50.
    # url = url + '&volume=' + str(50)
    # speech_rate: Optional. The speech rate. Range: -500 to 500. Default: 0.
    # url = url + '&speech_rate=' + str(0)
    # pitch_rate: Optional. The pitch. Range: -500 to 500. Default: 0.
    # url = url + '&pitch_rate=' + str(0)
    # Use httplib for Python 2.x.
    # conn = httplib.HTTPSConnection(host)
    # Use http.client for Python 3.x.
    conn = http.client.HTTPSConnection(host)
    conn.request(method='GET', url=url)
    # Process the server response.
    response = conn.getresponse()
    print('Response status and reason:')
    print(response.status ,response.reason)
    contentType = response.getheader('Content-Type')
    print(contentType)
    body = response.read()
    if 'audio/mpeg' == contentType :
        with open(audioSaveFile, mode='wb') as f:
            f.write(body)
        print('The GET request succeeded!')
    else :
        print('The GET request failed: ' + str(body))
    conn.close()
def processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate) :
    host = 'nls-gateway-ap-southeast-1.aliyuncs.com'
    url = 'https://' + host + '/stream/v1/tts'
    # Set the HTTPS headers.
    httpHeaders = {
        'Content-Type': 'application/json'
        }
    # Set the HTTPS body.
    body = {'appkey': appKey, 'token': token, 'text': text, 'format': format, 'sample_rate': sampleRate}
    body = json.dumps(body)
    # Use httplib for Python 2.x.
    # conn = httplib.HTTPSConnection(host)
    # Use http.client for Python 3.x.
    conn = http.client.HTTPSConnection(host)
    conn.request(method='POST', url=url, body=body, headers=httpHeaders)
    # Process the server response.
    response = conn.getresponse()
    print('Response status and reason:')
    print(response.status ,response.reason)
    contentType = response.getheader('Content-Type')
    print(contentType)
    body = response.read()
    if 'audio/mpeg' == contentType :
        with open(audioSaveFile, mode='wb') as f:
            f.write(body)
        print('The POST request succeeded!')
    else :
        print('The POST request failed: ' + str(body))
    conn.close()
appKey = 'Your AppKey'
token = 'Your Token'
text = 'Today is Monday, and the weather is nice.'
# URL-encode the text per RFC 3986.
textUrlencode = text
# Use urllib.quote for Python 2.x.
# textUrlencode = urllib.quote(textUrlencode, '')
# Use urllib.parse.quote_plus for Python 3.x.
textUrlencode = urllib.parse.quote_plus(textUrlencode)
textUrlencode = textUrlencode.replace("+", "%20")
textUrlencode = textUrlencode.replace("*", "%2A")
textUrlencode = textUrlencode.replace("%7E", "~")
print('text: ' + textUrlencode)
audioSaveFile = 'syAudio.wav'
format = 'wav'
sampleRate = 16000
# GET Request
processGETRequest(appKey, token, textUrlencode, audioSaveFile, format, sampleRate)
# POST Request
# processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate)

PHP

Requires PHP with json_encode support and the cURL extension installed. Keep certificate verification enabled for HTTPS requests.

<?php
function processGETRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate) {
    $url = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts";
    $url = $url . "?appkey=" . $appkey;
    $url = $url . "&token=" . $token;
    $url = $url . "&text=" . $text;
    $url = $url . "&format=" . $format;
    $url = $url . "&sample_rate=" . strval($sampleRate);
    // voice: The speaker. Optional. Default: xiaoyun.
    // $url = $url . "&voice=" . "xiaoyun";
    // volume: The audio volume. Optional. Valid range: 0 to 100. Default: 50.
    // $url = $url . "&volume=" . strval(50);
    // speech_rate: The speaking rate. Optional. Valid range: -500 to 500. Default: 0.
    // $url = $url . "&speech_rate=" . strval(0);
    // pitch_rate: The speech pitch. Optional. Valid range: -500 to 500. Default: 0.
    // $url = $url . "&pitch_rate=" . strval(0);
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
    /**
     * Set the HTTPS GET URL.
     */
    curl_setopt($curl, CURLOPT_URL, $url);
    /**
     * Include headers in the HTTPS response.
     */
    curl_setopt($curl, CURLOPT_HEADER, TRUE);
    /**
     * Send the HTTPS GET request.
     */
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, TRUE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
    $response = curl_exec($curl);
    if ($response == FALSE) {
        print "curl_exec failed!\n";
        curl_close($curl);
        return;
    }
    /**
     * Process the response from the server.
     */
    $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $headers = substr($response, 0, $headerSize);
    $bodyContent = substr($response, $headerSize);
    curl_close($curl);
    if (stripos($headers, "Content-Type: audio/mpeg") != FALSE || stripos($headers, "Content-Type:audio/mpeg") != FALSE) {
        file_put_contents($audioSaveFile, $bodyContent);
        print "The GET request succeeded!\n";
    }
    else {
        print "The GET request failed: " . $bodyContent . "\n";
    }
}
function processPOSTRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate) {
    $url = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts";
    /**
     * Add the request parameters to the request body as a JSON string.
     */
    $taskArr = array(
        "appkey" => $appkey,
        "token" => $token,
        "text" => $text,
        "format" => $format,
        "sample_rate" => $sampleRate
        // voice: The speaker. Optional. Default: xiaoyun.
        // "voice" => "xiaoyun",
        // volume: The audio volume. Optional. Valid range: 0 to 100. Default: 50.
        // "volume" => 50,
        // speech_rate: The speaking rate. Optional. Valid range: -500 to 500. Default: 0.
        // "speech_rate" => 0,
        // pitch_rate: The speech pitch. Optional. Valid range: -500 to 500. Default: 0.
        // "pitch_rate" => 0
    );
    $body = json_encode($taskArr);
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
    /**
     * Set the HTTPS POST URL.
     */
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POST, TRUE);
    /**
     * Set the HTTPS POST request headers.
     * */
    $httpHeaders = array(
        "Content-Type: application/json"
    );
    curl_setopt($curl, CURLOPT_HTTPHEADER, $httpHeaders);
    /**
     * Set the HTTPS POST request body.
     */
    curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
    /**
     * Include headers in the HTTPS response.
     */
    curl_setopt($curl, CURLOPT_HEADER, TRUE);
    /**
     * Send the HTTPS POST request.
     */
    $response = curl_exec($curl);
    if ($response == FALSE) {
        print "curl_exec failed!\n";
        curl_close($curl);
        return;
    }
    /**
     * Process the response from the server.
     */
    $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $headers = substr($response, 0, $headerSize);
    $bodyContent = substr($response, $headerSize);
    curl_close($curl);
    if (stripos($headers, "Content-Type: audio/mpeg") != FALSE || stripos($headers, "Content-Type:audio/mpeg") != FALSE) {
        file_put_contents($audioSaveFile, $bodyContent);
        print "The POST request succeeded!\n";
    }
    else {
        print "The POST request failed: " . $bodyContent . "\n";
    }
}
$appkey = "YOUR_APPKEY";
$token = "YOUR_TOKEN";
$text = "Today is Monday. The weather is nice.";
$textUrlEncode = urlencode($text);
$textUrlEncode = preg_replace('/\+/', '%20', $textUrlEncode);
$textUrlEncode = preg_replace('/\*/', '%2A', $textUrlEncode);
$textUrlEncode = preg_replace('/%7E/', '~', $textUrlEncode);
$audioSaveFile = "syAudio.wav";
$format = "wav";
$sampleRate = 16000;
processGETRequest($appkey, $token, $textUrlEncode, $audioSaveFile, $format, $sampleRate);
// processPOSTRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate);
?>

Node.js

Install the dependency in the directory that contains the example file:

npm install request --save
const request = require('request');
const fs = require('fs');
function processGETRequest(appkey, token, text, audioSaveFile, format, sampleRate) {
    var url = 'https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts';
    /**
     * Set the request parameters in the URL.
     */
    url = url + '?appkey=' + appkey;
    url = url + '&token=' + token;
    url = url + '&text=' + text;
    url = url + '&format=' + format;
    url = url + '&sample_rate=' + sampleRate;
    // voice: Optional. The synthesis voice. Default: xiaoyun.
    // url = url + "&voice=" + "xiaoyun";
    // volume: Optional. The audio volume. Range: 0–100. Default: 50.
    // url = url + "&volume=" + 50;
    // speech_rate: Optional. The speech rate. Range: -500–500. Default: 0.
    // url = url + "&speech_rate=" + 0;
    // pitch_rate: Optional. The speech pitch. Range: -500–500. Default: 0.
    // url = url + "&pitch_rate=" + 0;
    /**
     * Set the HTTPS GET request.
     * The `encoding` parameter must be set to null to receive the response body as a binary Buffer.
     */
    var options = {
        url: url,
        method: 'GET',
        encoding: null
    };
    request(options, function (error, response, body) {
        /**
         * Process the server response.
         */
        if (error != null) {
            console.log(error);
        }
        else {
            var contentType = response.headers['content-type'];
            if (contentType === undefined || contentType != 'audio/mpeg') {
                console.log('The GET request failed!');
            }
            else {
                fs.writeFileSync(audioSaveFile, body);
                console.log('The GET request succeeded!');
            }
        }
    });
}
function processPOSTRequest(appkeyValue, tokenValue, textValue, audioSaveFile, formatValue, sampleRateValue) {
    var url = 'https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts';
    /**
     * Set the request parameters as a JSON string in the POST request body.
    */
    var task = {
        appkey : appkeyValue,
        token : tokenValue,
        text : textValue,
        format : formatValue,
        sample_rate : sampleRateValue
        // voice: Optional. The synthesis voice. Default: xiaoyun.
        // voice : 'xiaoyun',
        // volume: Optional. The audio volume. Range: 0–100. Default: 50.
        // volume : 50,
        // speech_rate: Optional. The speech rate. Range: -500–500. Default: 0.
        // speech_rate : 0,
        // pitch_rate: Optional. The speech pitch. Range: -500–500. Default: 0.
        // pitch_rate : 0
    };
    var bodyContent = JSON.stringify(task);
    /**
     * Set the POST request headers.
     */
    var httpHeaders = {
        'Content-type' : 'application/json'
    }
    /**
     * Set the HTTPS POST request.
     * The `encoding` parameter must be set to null to receive the response body as a binary Buffer.
     */
    var options = {
        url: url,
        method: 'POST',
        headers: httpHeaders,
        body: bodyContent,
        encoding: null
    };
    request(options, function (error, response, body) {
        /**
         * Process the server response.
         */
        if (error != null) {
            console.log(error);
        }
        else {
            var contentType = response.headers['content-type'];
            if (contentType === undefined || contentType != 'audio/mpeg') {
                console.log('The POST request failed!');
            }
            else {
                fs.writeFileSync(audioSaveFile, body);
                console.log('The POST request succeeded!');
            }
        }
    });
}
var appkey = 'Your AppKey';
var token = 'Your Token';
var text = 'Today is Monday, and the weather is nice.';
var textUrlEncode = encodeURIComponent(text)
                    .replace(/[!'()*]/g, function(c) {
                        return '%' + c.charCodeAt(0).toString(16);
                    });
console.log(textUrlEncode);
var audioSaveFile = 'syAudio.wav';
var format = 'wav';
// The sample rate of the synthesized audio, in Hz.
var sampleRate = 16000;
processGETRequest(appkey, token, textUrlEncode, audioSaveFile, format, sampleRate);
// processPOSTRequest(appkey, token, text, audioSaveFile, format, sampleRate);

.NET

The example requires System.Net.Http, System.Web, and Newtonsoft.Json.Linq.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net.Http;
using System.Web;
using Newtonsoft.Json.Linq;
namespace RESTfulAPI
{
    class SpeechSynthesizerRESTfulDemo
    {
        private string appkey;
        private string token;
        public SpeechSynthesizerRESTfulDemo(string appkey, string token)
        {
            this.appkey = appkey;
            this.token = token;
        }
        public void processGETRequest(string text, string audioSaveFile, string format, int sampleRate)
        {
            /**
             * Configure the HTTPS GET request.
             * 1. Use the HTTPS protocol.
             * 2. Domain name of the Speech Synthesis service: nls-gateway-ap-southeast-1.aliyuncs.com
             * 3. Request path of the Speech Synthesis API: /stream/v1/tts
             * 4. Set the parameters used in this example: appkey, token, text, format, and sample_rate.
             * 5. Set the optional request parameters: voice, volume, speech_rate, and pitch_rate.
             */
            string url = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts";
            url = url + "?appkey=" + appkey;
            url = url + "&token=" + token;
            url = url + "&text=" + text;
            url = url + "&format=" + format;
            url = url + "&sample_rate=" + sampleRate.ToString();
            // voice: The voice. Optional. Default value: xiaoyun.
            // url = url + "&voice=" + "xiaoyun";
            // volume: The volume. Value range: 0 to 100. Optional. Default value: 50.
            // url = url + "&volume=" + 50;
            // speech_rate: The speech rate. Value range: -500 to 500. Optional. Default value: 0.
            // url = url + "&speech_rate=" + 0;
            // pitch_rate: The pitch rate. Value range: -500 to 500. Optional. Default value: 0.
            // url = url + "&pitch_rate=" + 0;
            /**
             * Send the HTTPS GET request and process the response from the server.
             */
            HttpClient client = new HttpClient();
            HttpResponseMessage response = null;
            response = client.GetAsync(url).Result;
            string contentType = null;
            if (response.IsSuccessStatusCode)
            {
                string[] typesArray = response.Content.Headers.GetValues("Content-Type").ToArray();
                if (typesArray.Length > 0)
                {
                    contentType = typesArray.First();
                }
            }
            if ("audio/mpeg".Equals(contentType))
            {
                byte[] audioBuff = response.Content.ReadAsByteArrayAsync().Result;
                FileStream fs = new FileStream(audioSaveFile, FileMode.Create);
                fs.Write(audioBuff, 0, audioBuff.Length);
                fs.Flush();
                fs.Close();
                System.Console.WriteLine("The GET request succeed!");
            }
            else
            {
                // The ContentType is null or "application/json".
                System.Console.WriteLine("Response status code and reason phrase: " +
                    response.StatusCode + " " + response.ReasonPhrase);
                string responseBodyAsText = response.Content.ReadAsStringAsync().Result;
                System.Console.WriteLine("The GET request failed: " + responseBodyAsText);
            }
        }
        public void processPOSTRequest(string text, string audioSaveFile, string format, int sampleRate)
        {
            /**
             * Configure the HTTPS POST request.
             * 1. Use the HTTPS protocol.
             * 2. Domain name of the Speech Synthesis service: nls-gateway-ap-southeast-1.aliyuncs.com
             * 3. Request path of the Speech Synthesis API: /stream/v1/tts
             * 4. Set the parameters used in this example: appkey, token, text, format, and sample_rate.
             * 5. Set the optional request parameters: voice, volume, speech_rate, and pitch_rate.
             */
            string url = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts";
            JObject obj = new JObject();
            obj["appkey"] = appkey;
            obj["token"] = token;
            obj["text"] = text;
            obj["format"] = format;
            obj["sample_rate"] = sampleRate;
            // voice: The voice. Optional. Default value: xiaoyun.
            // obj["voice"] = "xiaoyun";
            // volume: The volume. Value range: 0 to 100. Optional. Default value: 50.
            // obj["volume"] = 50;
            // speech_rate: The speech rate. Value range: -500 to 500. Optional. Default value: 0.
            // obj["speech_rate"] = 0;
            // pitch_rate: The pitch rate. Value range: -500 to 500. Optional. Default value: 0.
            // obj["pitch_rate"] = 0;
            String bodyContent = obj.ToString();
            StringContent content = new StringContent(bodyContent, Encoding.UTF8, "application/json");
            /**
             * Send the HTTPS POST request and process the response from the server.
             */
            HttpClient client = new HttpClient();
            HttpResponseMessage response = client.PostAsync(url, content).Result;
            string contentType = null;
            if (response.IsSuccessStatusCode)
            {
                string[] typesArray = response.Content.Headers.GetValues("Content-Type").ToArray();
                if (typesArray.Length > 0)
                {
                    contentType = typesArray.First();
                }
            }
            if ("audio/mpeg".Equals(contentType))
            {
                byte[] audioBuff = response.Content.ReadAsByteArrayAsync().Result;
                FileStream fs = new FileStream(audioSaveFile, FileMode.Create);
                fs.Write(audioBuff, 0, audioBuff.Length);
                fs.Flush();
                fs.Close();
                System.Console.WriteLine("The POST request succeed!");
            }
            else
            {
                System.Console.WriteLine("Response status code and reason phrase: " +
                    response.StatusCode + " " + response.ReasonPhrase);
                string responseBodyAsText = response.Content.ReadAsStringAsync().Result;
                System.Console.WriteLine("The POST request failed: " + responseBodyAsText);
            }
        }
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                System.Console.WriteLine("SpeechSynthesizerRESTfulDemo requires the following parameters: <token> <app-key>");
                return;
            }
            string token = args[0];
            string appkey = args[1];
            SpeechSynthesizerRESTfulDemo demo = new SpeechSynthesizerRESTfulDemo(appkey, token);
            string text = "Today is Monday, and the weather is nice.";
            // URL-encode the text based on RFC 3986.
            string textUrlEncode = text;
            textUrlEncode = HttpUtility.UrlEncode(textUrlEncode, Encoding.UTF8)
                .Replace("+", "%20")
                .Replace("*", "%2A")
                .Replace("%7E", "~");
            System.Console.WriteLine(textUrlEncode);
            string audioSaveFile = "syAudio.wav";
            string format = "wav";
            int sampleRate = 16000;
            demo.processGETRequest(textUrlEncode, audioSaveFile, format, sampleRate);
            //demo.processPOSTRequest(text, audioSaveFile, format, sampleRate);
        }
    }
}

Go

package main
import (
    "fmt"
    "net/url"
    "net/http"
    "io/ioutil"
    "encoding/json"
    "strconv"
    "os"
    "bytes"
    "strings"
)
func processGETRequest(appkey string, token string, text string, audioSaveFile string, format string, sampleRate int) {
    /**
     * Configure the HTTPS GET request.
     * 1. Protocol: HTTPS
     * 2. Endpoint: nls-gateway-ap-southeast-1.aliyuncs.com
     * 3. Request path: /stream/v1/tts
     * 4. Parameters used in this example: appkey, token, text, format, and sample_rate.
     * 5. Optional parameters: voice, volume, speech_rate, and pitch_rate.
     */
    var url string = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts"
    url = url + "?appkey=" + appkey
    url = url + "&token=" + token
    url = url + "&text=" + text
    url = url + "&format=" + format
    url = url + "&sample_rate=" + strconv.Itoa(sampleRate)
    // voice: The synthesis voice. Optional. Default: xiaoyun.
    // url = url + "&voice=" + "xiaoyun"
    // volume: The audio volume. Optional. Valid range: 0 to 100. Default: 50.
    // url = url + "&volume=" + strconv.Itoa(50)
    // speech_rate: The speech rate. Optional. Valid range: -500 to 500. Default: 0.
    // url = url + "&speech_rate=" + strconv.Itoa(0)
    // pitch_rate: The pitch rate. Optional. Valid range: -500 to 500. Default: 0.
    // url = url + "&pitch_rate=" + strconv.Itoa(0)
    /**
     * Send the GET request and process the server response.
     */
    response, err := http.Get(url)
    if err != nil {
        fmt.Println("The GET request failed!")
        panic(err)
    }
    defer response.Body.Close()    
    contentType := response.Header.Get("Content-Type")
    body, _ := ioutil.ReadAll(response.Body)
    if ("audio/mpeg" == contentType) {
        file, _ := os.Create(audioSaveFile)
        defer file.Close()
        file.Write([]byte(body))
        fmt.Println("The GET request succeeded!")
    } else {
        // A null or "application/json" Content-Type indicates a failed request.
        statusCode := response.StatusCode
        fmt.Println("HTTP status code: " + strconv.Itoa(statusCode))
        fmt.Println("The GET request failed: " + string(body))
    }
}
func processPOSTRequest(appkey string, token string, text string, audioSaveFile string, format string, sampleRate int) {
    /**
     * Configure the HTTPS POST request.
     * 1. Protocol: HTTPS
     * 2. Endpoint: nls-gateway-ap-southeast-1.aliyuncs.com
     * 3. Request path: /stream/v1/tts
     * 4. Parameters used in this example: appkey, token, text, format, and sample_rate.
     * 5. Optional parameters: voice, volume, speech_rate, and pitch_rate.
     */
    var url string = "https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts"
    bodyContent := make(map[string]interface{})
    bodyContent["appkey"] = appkey
    bodyContent["text"] = text
    bodyContent["token"] = token
    bodyContent["format"] = format
    bodyContent["sample_rate"] = sampleRate
    // voice: The synthesis voice. Optional. Default: xiaoyun.
    // bodyContent["voice"] = "xiaoyun"
    // volume: The audio volume. Optional. Valid range: 0 to 100. Default: 50.
    // bodyContent["volume"] = 50
    // speech_rate: The speech rate. Optional. Valid range: -500 to 500. Default: 0.
    // bodyContent["speech_rate"] = 0
    // pitch_rate: The pitch rate. Optional. Valid range: -500 to 500. Default: 0.
    // bodyContent["pitch_rate"] = 0
    bodyJson, err := json.Marshal(bodyContent)
    if err != nil {
        panic(nil)
    }
    /**
     * Send the POST request and process the server response.
     */
    response, err := http.Post(url, "application/json;charset=utf-8", bytes.NewBuffer([]byte(bodyJson)))
    if err != nil {
        panic(err)
    }
    defer response.Body.Close()
    contentType := response.Header.Get("Content-Type")
    body, _ := ioutil.ReadAll(response.Body)
    if ("audio/mpeg" == contentType) {
        file, _ := os.Create(audioSaveFile)
        defer file.Close()
        file.Write([]byte(body))
        fmt.Println("The POST request succeeded!")
    } else {
        // A null or "application/json" Content-Type indicates a failed request.
        statusCode := response.StatusCode
        fmt.Println("HTTP status code: " + strconv.Itoa(statusCode))
        fmt.Println("The POST request failed: " + string(body))
    }    
}
func main() {
    var appkey string = "YOUR_APPKEY"
    var token  string = "YOUR_TOKEN"
    var text string = "Today is Monday, and the weather is nice."
    var textUrlEncode = text
    textUrlEncode = url.QueryEscape(textUrlEncode)
    textUrlEncode = strings.Replace(textUrlEncode, "+", "%20", -1)
    textUrlEncode = strings.Replace(textUrlEncode, "*", "%2A", -1)
    textUrlEncode = strings.Replace(textUrlEncode, "%7E", "~", -1)
    fmt.Println(textUrlEncode)
    var audioSaveFile string = "syAudio.wav"
    var format string = "wav"
    var sampleRate int = 16000
    processGETRequest(appkey, token, textUrlEncode, audioSaveFile, format, sampleRate)
    // processPOSTRequest(appkey, token, text, audioSaveFile, format, sampleRate)
}

Request flow

The client sends a GET or POST request containing text. The server returns audio in the HTTP response body. A streaming client keeps reading the response body until the response ends.

image

Request parameters

For GET requests, put parameters in the URL query string. For POST requests, put them in the JSON body. The token can also be passed in the X-NLS-Token request header.

Parameter

Type

Required

Description

appkey

String

Yes

The project AppKey.

text

String

Yes

The UTF-8 text to synthesize. GET requests also require URL encoding according to RFC 3986. POST requests do not require URL encoding.

token

String

No

The access token. If omitted, the X-NLS-Token request header is required.

format

String

No

The audio format. Use lowercase pcm, wav, or mp3. Default: pcm.

sample_rate

Integer

No

The sample rate in Hz. Supports 8000 and 16000. Default: 16000. The default voice, xiaoyun, also supports 24000. For other voices, check the supported sample rates in the voice documentation.

voice

String

No

The voice. Default: xiaoyun. For available voices and their supported settings, see API reference.

volume

Integer

No

The volume. Range: 0–100. Default: 50.

speech_rate

Integer

No

The speech rate. Range: -500–500. Default: 0.

pitch_rate

Integer

No

The pitch. Range: -500–500. Default: 0.

chunk

Boolean

No

The GET streaming example sets this parameter to true to receive audio with HTTP chunked transfer encoding. The client must still read the response incrementally. Responses may also use chunked transfer encoding when this parameter is omitted.

GET requests

Encode text as UTF-8, then apply URL encoding. For example, encode + as %2B and * as %2A, and leave ~ unchanged. In the following request, <appkey> and <token> are placeholders:

https://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/tts?appkey=<appkey>&token=<token>&text=%E4%BB%8A%E5%A4%A9%E6%98%AF%E5%91%A8%E4%B8%80%EF%BC%8C%E5%A4%A9%E6%B0%94%E6%8C%BA%E5%A5%BD%E7%9A%84%E3%80%82&format=wav&sample_rate=16000

Alternatively, omit token from the query string and use a request header:

Header

Type

Required

Description

X-NLS-Token

String

Conditional

Required if token is omitted from the query string.

POST requests

Use a UTF-8 JSON request body. Do not URL-encode text.

Header

Type

Required

Description

Content-Type

String

Yes

Set to application/json.

X-NLS-Token

String

Conditional

Required if token is omitted from the request body.

Content-Length

Long

No

The request body size in bytes. Usually set automatically by the HTTP client.

Example request body:

{
  "appkey": "<appkey>",
  "text": "今天是周一,天气挺好的。",
  "token": "<token>",
  "format": "wav",
  "sample_rate": 16000
}

Response

GET and POST use the same response format. Check both the HTTP status code and Content-Type. Do not save an error response as audio.

Successful response

Content-Type is audio/mpeg, and the response body contains binary audio. This header does not mean the requested format is necessarily MP3. The format parameter determines the audio format.

A successful response may not include X-NLS-RequestId. If the header is present, record its value for troubleshooting.

Failed response

If Content-Type is application/json, the response body contains JSON error information. Also treat a missing or unexpected Content-Type as an error response.

{
    "task_id":"8f95d0b9b6e948bc98e8d0ce64b0****",
    "result":"",
    "status":40000000,
    "message":"Gateway:CLIENT_ERROR:in post data, json format illegal"
}

Field

Type

Description

task_id

String

The request's task ID, typically a 32-character string.

result

String

The service result.

status

Integer

The service status code.

message

String

The error message.

Record X-NLS-RequestId or task_id, the HTTP status code, and the error message when available. Provide this information when contacting technical support. Do not share tokens.

Service status codes

The status field in a JSON response is a service status code, not an HTTP status code.

Service status code

Meaning

Action

20000000

Success

None.

40000000

Client error

Check the error message. Contact technical support if needed.

40000001

Authentication failed

Check whether the token is valid or has expired.

40000002

Invalid message

Check the request message format.

40000003

Invalid parameter

Check the parameter values.

40000004

Idle timeout

Check whether no data was sent for an extended period.

40000005

Too many requests

Check the concurrent connection count and requests per second.

41020001

Speech synthesis client error

Check synthesis parameters based on message. For example, use lowercase pcm, wav, or mp3 for the audio format.

50000000

Server error

Record the error information. Contact technical support if the error persists.

50000001

Internal GRPC call error

Record the error information. Contact technical support if the error persists.