RESTful API

更新时间:
复制 MD 格式

The speech synthesis RESTful API supports HTTPS GET and POST requests. You can upload text to the server for synthesis, and the server returns the synthesized audio. The connection must remain open until the response is received.

Features

This API synthesizes uploaded text into speech. You can set the following properties using request parameters:

  • Audio format: PCM, WAV, and MP3.

  • Sample rate: 8000 Hz, 16000 Hz.

  • Voice: For more information, see the voice list.

  • Speech rate.

  • Pitch.

  • Volume.

Important
  • Use streaming synthesis: Because the complexity of the algorithm increases as Text-to-Speech (TTS) quality improves, synthesis time may be longer. Streaming synthesis provides faster response times. For sample code, see this topic and the SDK examples.

  • Text length limit: The input text cannot exceed 300 characters. Any excess characters are truncated. To process longer text, you can download the Java example to view samples of long-text segmentation and concatenation in the SDK.

  • Pure JavaScript cannot call the RESTful API directly: You cannot call the RESTful API directly from pure JavaScript. This is because direct calls may trigger cross-origin resource sharing (CORS) issues and risk exposing your App Key.

Prerequisites

Endpoints

Access type

Description

URL

Host

Public internet access (default: China (Shanghai))

You can access all servers using their public access URLs.

  • China (Shanghai): nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts

  • China (Beijing): nls-gateway-cn-beijing.aliyuncs.com/stream/v1/tts

  • China (Shenzhen): nls-gateway-cn-shenzhen.aliyuncs.com/stream/v1/tts

  • China (Shanghai): nls-gateway-cn-shanghai.aliyuncs.com

  • China (Beijing): nls-gateway-cn-beijing.aliyuncs.com

  • China (Shenzhen): nls-gateway-cn-shenzhen.aliyuncs.com

ECS private network access

If you use Alibaba Cloud ECS instances in China (Shanghai), China (Beijing), or China (Shenzhen), you can use the private network endpoint. Classic network ECS instances cannot access AnyTunnel and therefore cannot access Voice Service over the private network. To use AnyTunnel, create a VPC and access the service within it.

Note

  • Private network access incurs no public network data transfer cost for your ECS instance.

  • For more information about ECS network types, see Network types.

  • China (Shanghai): nls-gateway-cn-shanghai-internal.aliyuncs.com/stream/v1/tts

  • China (Beijing): nls-gateway-cn-beijing-internal.aliyuncs.com/stream/v1/tts

  • China (Shenzhen): nls-gateway-cn-shenzhen-internal.aliyuncs.com/stream/v1/tts

  • China (Shanghai): nls-gateway-cn-shanghai-internal.aliyuncs.com

  • China (Beijing): nls-gateway-cn-beijing-internal.aliyuncs.com

  • China (Shenzhen): nls-gateway-cn-shenzhen-internal.aliyuncs.com

Important
  • Supported protocols:

    • Public network access: HTTP and HTTPS.

    • ECS private network access: HTTP only.

  • This topic uses public network access in its examples. In a production environment, you must use the URL that is appropriate for your scenario.

Interaction flow

The client sends a request that contains the text to synthesize. The server returns a response that contains the synthesized audio data.

image
Note

All server responses include a task_id parameter in the header. This parameter uniquely identifies the request.

Request parameters

The speech synthesis service supports both GET and POST methods:

  • For GET requests, you can pass parameters as a query string appended to the URL in key-value pairs (for example, "?key1=value1&key2=value2").

  • For POST requests, you can include parameters in the request body.

Both methods use the same parameters, which are described in the following table:

Name

Type

Required

Description

appkey

String

Yes

Your project appkey.

text

String

Yes

Text to synthesize, encoded in UTF-8. For GET requests, apply RFC 3986 URL encoding. For POST requests, do not URL-encode—doing so causes incorrect synthesis results.

Note

To call the multi-emotion feature of a voice, add the ssml-emotion tag to the text. For more information, see <emotion>.

If you use the <emotion> tag for a voice that does not support multiple emotions, the `Illegal ssml text` error is reported.

token

String

No

If you omit this parameter, set the X-NLS-Token field in the HTTP headers.

format

String

No

Audio coding format. Valid values: PCM, WAV, MP3. Default: pcm.

sample_rate

Integer

No

Audio sample rate. Valid values: 16000 Hz, 8000 Hz. Default: 16000 Hz.

voice

String

No

Voice. Default: xiaoyun. For more voices, see API reference.

volume

Integer

No

Volume. Range: 0–100. Default: 50.

speech_rate

Integer

No

Speech rate. Range: -500–500. Default: 0.

pitch_rate

Integer

No

Pitch. Range: -500–500. Default: 0.

Upload text using GET

  • Full URL: https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts

  • Request headers:

    • X-NLS-Token (String, optional): Authentication token.

  • Example URL with parameters (see Request parameters for details)

    # Text: "Today is Monday, and the weather is nice."
    https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts?appkey=${your_appkey}&token=${your_token}&text=Today%20is%20Monday%2C%20and%20the%20weather%20is%20nice.&format=wav&sample_rate=16000
Important
  • You can set the authentication token in one of the following two ways:

    • (Recommended) Use the token request parameter.

    • Set the X-NLS-Token header field.

  • The text parameter must be encoded in UTF-8 and then URL-encoded based on RFC 3986. For example, you must encode a plus sign (+) as %2B, an asterisk (*) as %2A, and a tilde (~) as %7E.

Upload text using POST

  • Full URL: https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts

  • Request headers:

    • Content-Type (String, required): The value must be "application/json". This indicates that the request body is a JSON string.

    • X-NLS-Token (String, optional): Authentication token.

    • Content-Length (String, optional): Length of the request body.

  • Example request body (see Request parameters for details)

      {
        "appkey":"31f932fb",
        "text":"Today is Monday, and the weather is nice.",
        "token":"450343c793aaaaaa****",
        "format":"wav"
      }
Important
  • You can set the authentication token in one of the following two ways:

    • (Recommended) Use the token parameter in the request body.

    • Set the X-NLS-Token header field.

  • For POST requests, the text parameter in the request body must be encoded in UTF-8 but not URL-encoded. If the text is URL-encoded, incorrect synthesis results are returned. This differs from GET requests.

Response

GET and POST requests return the same responses.

The Content-Type header indicates whether the request is successful.

  • Success response

    • The Content-Type header is audio/mpeg, which indicates that the synthesis is successful. The audio data is in the response body.

    • The response body contains binary audio data.

  • Error response

    • The Content-Type header is missing or is set to application/json, which indicates that the synthesis failed. The error message is in the response body.

    • The X-NLS-RequestId header contains the task_id for this request.

    • The response body contains a JSON-formatted error message, as shown in the following example:

      {
          "task_id":"8f95d0b9b6e948bc98e8d0ce64b0****",
          "result":"",
          "status":40000000,
          "message":"Gateway:CLIENT_ERROR:in post data, json format illegal"
      }
    • The fields in the error message are described in the following table.

      Name

      Type

      Description

      task_id

      String

      32-character task ID. Record this value for troubleshooting.

      result

      String

      Service result.

      status

      Integer

      Service status code.

      message

      String

      Service status description.

Service status codes

Service status code

Service status description

Resolution

20000000

Request succeeded

None.

40000000

Default client error

Check the error message.

40000001

Authentication failed

Verify your token is correct and not expired.

40000002

Invalid message

Verify that the sent message meets the requirements.

40000003

Invalid parameter

Verify your parameter values are valid.

40000004

Idle timeout

Verify that no data has been sent to the server for a long time.

40000005

Too many requests

Check if you exceeded concurrent connections or requests per second.

40000010

Trial period ended without commercial activation or account overdue payment.

Log on to the console to check your service status and account balance.

50000000

Default server error

Internal service error. Retry from the client.

50000001

Internal gRPC call error

Internal service error. Retry from the client.

Java example

Note

You can download more Java examples here.

Dependencies:

<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>

Sample code:

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. Domain name for the speech synthesis service: nls-gateway-cn-shanghai.aliyuncs.com
         * 3. Request path for the speech synthesis API: /stream/v1/tts
         * 4. Set the required request parameters: 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-cn-shanghai.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. Optional. Default value: xiaoyun.
        // url = url + "&voice=" + "xiaoyun";
        // volume: The volume. Optional. Valid values: 0 to 100. Default value: 50.
        // url = url + "&volume=" + String.valueOf(50);
        // speech_rate: The speech rate. Optional. Valid values: -500 to 500. Default value: 0.
        // url = url + "&speech_rate=" + String.valueOf(0);
        // pitch_rate: The pitch rate. Optional. Valid values: -500 to 500. Default value: 0.
        // url = url + "&pitch_rate=" + String.valueOf(0);
        System.out.println("URL: " + url);
        /**
         * Send an 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. Domain name for the speech synthesis service: nls-gateway-cn-shanghai.aliyuncs.com
         * 3. Request path for the speech synthesis API: /stream/v1/tts
         * 4. Set the required request parameters: 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-cn-shanghai.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. Optional. Default value: xiaoyun.
        // taskObject.put("voice", "xiaoyun");
        // volume: The volume. Optional. Valid values: 0 to 100. Default value: 50.
        // taskObject.put("volume", 50);
        // speech_rate: The speech rate. Optional. Valid values: -500 to 500. Default value: 0.
        // taskObject.put("speech_rate", 0);
        // pitch_rate: The pitch rate. Optional. Valid values: -500 to 500. Default value: 0.
        // taskObject.put("pitch_rate", 0);
        String bodyContent = taskObject.toJSONString();
        System.out.println("POST Body Content: " + bodyContent);
        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 need 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, and the weather is nice.";
        // URL-encode the text based on the RFC 3986 standard.
        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 ###");
    }
}

Java (streaming synthesis) sample code:

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:
 * 1. How to call the Text-to-Speech (TTS) RESTful API.
 * 2. How to process streaming responses using the HTTP chunked mechanism.
 */
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 processGETRequet(String text, String audioSaveFile, String format, int sampleRate, String voice, boolean chunked) {
        /**
         * Set the HTTPS GET request.
         * 1. Use the HTTPS protocol.
         * 2. Set the domain name for the speech synthesis service to nls-gateway-cn-shanghai.aliyuncs.com.
         * 3. Set the request path for the speech synthesis API to /stream/v1/tts.
         * 4. Set the following required request parameters: appkey, token, text, format, and sample_rate.
         * 5. Set the following optional request parameters: voice, volume, speech_rate, and pitch_rate.
         */
        String url = "https://nls-gateway-cn-shanghai.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);
        System.out.println("URL: " + url);
        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 null;
                }
                @Override
                public State onHeadersReceived(HttpHeaders httpHeaders) throws Exception {
                    outs = new FileOutputStream(new File("tts.wav"));
                    return null;
                }
                @Override
                public State onBodyPartReceived(HttpResponseBodyPart httpResponseBodyPart) throws Exception {
                    // Note: Once the data stream is received, you can play it to the user or use it for other processing to improve the response speed.
                    // Note: Do not perform time-consuming operations in this callback. You can push the binary TTS audio stream to another thread asynchronously or using a queue.
                    logger.info("onBodyPartReceived " + httpResponseBodyPart.getBodyPartBytes().toString());
                    if(httpCode != 200) {
                        System.err.write(httpResponseBodyPart.getBodyPartBytes());
                    }
                    if (firstRecvBinary) {
                        firstRecvBinary = false;
                        // Calculate the first packet latency. The synthesized audio can be played or sent to the caller immediately after the first packet is received. Note: The first packet latency includes the time that is required to establish a 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 null;
                }
                @Override
                public void onThrowable(Throwable throwable) {
                    logger.error("throwable {}", throwable);
                    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 need params: <token> <app-key>");
            System.exit(-1);
        }
        String token = args[0];
        String appkey = args[1];
        SpeechSynthesizerRestfulChunkedDemo demo = new SpeechSynthesizerRestfulChunkedDemo(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.";
        // URL-encode the text based on the RFC 3986 standard.
        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;
        // If the value of the last parameter is true, HTTP chunked transfer encoding is enabled.
        demo.processGETRequet(textUrlEncode, audioSaveFile, format, sampleRate, "aixia", true);
        System.out.println("### Game Over ###");
    }
}

C++ example

Note
  • Download the C++ example.

    The C++ example uses the curl library for HTTPS requests and responses and the jsoncpp library for JSON strings in POST bodies.

  • The minimum runtime requirements for Linux are Glibc 2.5 or later and GCC 4 or GCC 5.

  • On Windows, you must decompress the windows.zip file from the lib directory for compilation.

Example directory structure:

  • CMakeLists.txt: CMake configuration file for the example project.

  • demo: Example files.

    Filename

    Description

    restfulTtsDemo.cpp

    Speech synthesis RESTful API example.

  • include

    Directory

    Description

    curl

    curl library header files.

    json

    jsoncpp library header files.

  • lib: Contains curl and jsoncpp dynamic libraries.

    Use one of the following versions based on your platform:

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

    • Windows (Visual Studio 2013, Visual Studio 2015)

  • readme.txt: Description file.

  • release.log: Release notes.

  • version: Version number.

  • build.sh: Compilation script.

Compilation and execution steps:

If you extracted the example to the path/to directory, run the following commands in a Linux terminal:

  • Support for CMake:

    1. Verify 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>

  • CMake is not supported:

    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);
    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-cn-shanghai.aliyuncs.com/stream/v1/tts";
    /**
     * Set the HTTPS URL request parameters.
     */
    ostringstream oss;
    oss << url;
    oss << "?appkey=" << appKey;
    oss << "&token=" << token;
    oss << "&text=" << text;
    oss << "&format=" << format;
    oss << "&sample_rate=" << sampleRate;
    // voice: The speaker. This parameter is optional. Default value: xiaoyun.
    // oss << "&voice=" << "xiaoyun";
    // volume: The volume. This parameter is optional. Valid values: 0 to 100. Default value: 50.
    // oss << "&volume=" << 50;
    // speech_rate: The speech rate. This parameter is optional. Valid values: -500 to 500. Default value: 0.
    // oss << "&speech_rate=" << 0;
    // pitch_rate: The pitch rate. This parameter is optional. Valid values: -500 to 500. Default value: 0.
    // oss << "&pitch_rate=" << 0;
    string request = oss.str();
    cout << request << endl;
    curl_easy_setopt(curl, CURLOPT_URL, request.c_str());
    /**
     * Set the callback function to receive the HTTPS response headers.
     */
    map<string, string> responseHeaders;
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeadersCallback);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    /**
     * Set the callback function to receive the HTTPS 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 the 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 << "The audio save file can not open!";
            return -1;
        }
        fs.write(bodyContent.c_str(), bodyContent.size());
        fs.close();
        cout << "The GET request succeed!" << 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-cn-shanghai.aliyuncs.com/stream/v1/tts";
    /**
     * Set the HTTPS POST URL.
     */
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_POST, 1L);
    /**
     * Set the HTTPS POST request header.
     */
    struct curl_slist* headers = NULL;
    // Content-Type
    headers = curl_slist_append(headers, "Content-Type:application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    /**
     * Set the HTTPS POST 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 speaker. This parameter is optional. Default value: xiaoyun.
    // root["voice"] = "xiaoyun";
    // volume: The volume. This parameter is optional. Valid values: 0 to 100. Default value: 50.
    // root["volume"] = 50;
    // speech_rate: The speech rate. This parameter is optional. Valid values: -500 to 500. Default value: 0.
    // root["speech_rate"] = 0;
    // pitch_rate: The pitch rate. This parameter is optional. Valid values: -500 to 500. Default value: 0.
    // root["pitch_rate"] = 0;
    string task = writer.write(root);
    cout << "POST request Body: " << task << endl;
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, task.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, task.length());
    /**
     * Set the callback function to receive the HTTPS response headers.
     */
    map<string, string> responseHeaders;
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeadersCallback);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
    /**
     * Set the callback function to receive the HTTPS 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 the 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 << "The audio save file can not open!";
            return -1;
        }
        fs.write(bodyContent.c_str(), bodyContent.size());
        fs.close();
        cout << "The POST request succeed!" << endl;
    }
    else {
        cout << "The POST request failed: " + bodyContent << endl;
        return -1;
    }
    return 0;
}
int main(int argc, char* argv[]) {
    if (argc < 3) {
        cerr << "params is not valid. 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 globally only once.
    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 example

Note
  • For Python 2.x, you must use the httplib module. For Python 3.x, you must use the http.client module.

  • When creating HTTP/HTTPS connections, Python 2.x uses the httplib module, and Python 3.x uses the http.client module:

    Python 2.x

    Create HTTP connection

    import httplib
    
    host = 'nls-gateway-cn-shanghai.aliyuncs.com'
    conn = httplib.HTTPConnection(host)

    Create HTTPS connection

    import httplib
    
    host = 'nls-gateway-cn-shanghai.aliyuncs.com'
    conn = httplib.HTTPSConnection(host)

    Python 3.x

    Create HTTP connection

    import http.client
    
    host = 'nls-gateway-cn-shanghai.aliyuncs.com'
    conn = http.client.HTTPConnection(host)

    Create HTTPS connection

    import http.client
    
    host = 'nls-gateway-cn-shanghai.aliyuncs.com'
    conn = http.client.HTTPSConnection(host)
  • To apply RFC 3986 URL encoding, use urllib.quote for Python 2.x or urllib.parse.quote_plus for Python 3.x.

# -*- coding: UTF-8 -*-
# Import the httplib module for Python 2.x.
# import httplib
# Import the http.client module for Python 3.x.
import http.client
# Import the urllib module for Python 2.x.
# import urllib
# Import the urllib.parse module for Python 3.x.
import urllib.parse
import json
def processGETRequest(appKey, token, text, audioSaveFile, format, sampleRate) :
    host = 'nls-gateway-cn-shanghai.aliyuncs.com'
    url = 'https://' + host + '/stream/v1/tts'
    # Set the URL request parameters.
    url = url + '?appkey=' + appKey
    url = url + '&token=' + token
    url = url + '&text=' + text
    url = url + '&format=' + format
    url = url + '&sample_rate=' + str(sampleRate)
    # voice: The speaker. Optional. Default value: xiaoyun.
    # url = url + '&voice=' + 'xiaoyun'
    # volume: The volume. Optional. Valid values: 0 to 100. Default value: 50.
    # url = url + '&volume=' + str(50)
    # speech_rate: The speech rate. Optional. Valid values: -500 to 500. Default value: 0.
    # url = url + '&speech_rate=' + str(0)
    # pitch_rate: The pitch rate. Optional. Valid values: -500 to 500. Default value: 0.
    # url = url + '&pitch_rate=' + str(0)
    print(url)
    # For Python 2.x, use httplib.
    # conn = httplib.HTTPSConnection(host)
    # For Python 3.x, use http.client.
    conn = http.client.HTTPSConnection(host)
    conn.request(method='GET', url=url)
    # Process the response from the server.
    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 '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-cn-shanghai.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)
    print('The POST request body content: ' + body)
    # For Python 2.x, use httplib.
    # conn = httplib.HTTPSConnection(host)
    # For Python 3.x, use http.client.
    conn = http.client.HTTPSConnection(host)
    conn.request(method='POST', url=url, body=body, headers=httpHeaders)
    # Process the response from the server.
    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 '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 in compliance with RFC 3986.
textUrlencode = text
# For Python 2.x, use urllib.quote.
# textUrlencode = urllib.quote(textUrlencode, '')
# For Python 3.x, use urllib.parse.quote_plus.
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 example

Important

The PHP example uses cURL functions. This example requires PHP 4.0.2 or later with the cURL extension installed.

<?php
function processGETRequest($appkey, $token, $text, $audioSaveFile, $format, $sampleRate) {
    $url = "https://nls-gateway-cn-shanghai.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 value: xiaoyun.
    // $url = $url . "&voice=" . "xiaoyun";
    // volume: The volume. Valid values: 0 to 100. Optional. Default value: 50.
    // $url = $url . "&volume=" . strval(50);
    // speech_rate: The speech rate. Valid values: -500 to 500. Optional. Default value: 0.
    // $url = $url . "&speech_rate=" . strval(0);
    // pitch_rate: The pitch rate. Valid values: -500 to 500. Optional. Default value: 0.
    // $url = $url . "&pitch_rate=" . strval(0);
    print $url . "\n";
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
    /**
     * Set the HTTPS GET URL.
     */
    curl_setopt($curl, CURLOPT_URL, $url);
    /**
     * Specify that the response includes the HTTPS header.
     */
    curl_setopt($curl, CURLOPT_HEADER, TRUE);
    /**
     * Send the HTTPS GET request.
     */
    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 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-cn-shanghai.aliyuncs.com/stream/v1/tts";
    /**
     * Specify the request parameters in a JSON-formatted string in the body of the HTTPS POST request.
     */
    $taskArr = array(
        "appkey" => $appkey,
        "token" => $token,
        "text" => $text,
        "format" => $format,
        "sample_rate" => $sampleRate
        // voice: The speaker. Optional. Default value: xiaoyun.
        // "voice" => "xiaoyun",
        // volume: The volume. Valid values: 0 to 100. Optional. Default value: 50.
        // "volume" => 50,
        // speech_rate: The speech rate. Valid values: -500 to 500. Optional. Default value: 0.
        // "speech_rate" => 0,
        // pitch_rate: The pitch rate. Valid values: -500 to 500. Optional. Default value: 0.
        // "pitch_rate" => 0
    );
    $body = json_encode($taskArr);
    print "The POST request body content: " . $body . "\n";
    $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 header.
     * */
    $httpHeaders = array(
        "Content-Type: application/json"
    );
    curl_setopt($curl, CURLOPT_HTTPHEADER, $httpHeaders);
    /**
     * Set the HTTPS POST request body.
     */
    curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
    /**
     * Specify that the response includes the HTTPS header.
     */
    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, and the weather is fine.";
$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 example

Note

First, you must install the request dependency. Run the following command in your example directory:

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-cn-shanghai.aliyuncs.com/stream/v1/tts';
    /**
     * Set the URL request parameters.
     */
    url = url + '?appkey=' + appkey;
    url = url + '&token=' + token;
    url = url + '&text=' + text;
    url = url + '&format=' + format;
    url = url + '&sample_rate=' + sampleRate;
    // voice: The speaker. Optional. Default value: xiaoyun.
    // url = url + "&voice=" + "xiaoyun";
    // volume: The volume. Optional. Valid values: 0 to 100. Default value: 50.
    // url = url + "&volume=" + 50;
    // speech_rate: The speech rate. Optional. Valid values: -500 to 500. Default value: 0.
    // url = url + "&speech_rate=" + 0;
    // pitch_rate: The pitch rate. Optional. Valid values: -500 to 500. Default value: 0.
    // url = url + "&pitch_rate=" + 0;
    console.log(url);
    /**
     * Set the HTTPS GET request.
     * The encoding parameter must be set to null. The body of the HTTPS response is a binary Buffer.
     */
    var options = {
        url: url,
        method: 'GET',
        encoding: null
    };
    request(options, function (error, response, body) {
        /**
         * Process the server-side response.
         */
        if (error != null) {
            console.log(error);
        }
        else {
            var contentType = response.headers['content-type'];
            if (contentType === undefined || contentType != 'audio/mpeg') {
                console.log(body.toString());
                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-cn-shanghai.aliyuncs.com/stream/v1/tts';
    /**
     * Specify the request parameters as a JSON-formatted string in the body of the HTTPS POST request.
    */
    var task = {
        appkey : appkeyValue,
        token : tokenValue,
        text : textValue,
        format : formatValue,
        sample_rate : sampleRateValue
        // voice: The speaker. Optional. Default value: xiaoyun.
        // voice : 'xiaoyun',
        // volume: The volume. Optional. Valid values: 0 to 100. Default value: 50.
        // volume : 50,
        // speech_rate: The speech rate. Optional. Valid values: -500 to 500. Default value: 0.
        // speech_rate : 0,
        // pitch_rate: The pitch rate. Optional. Valid values: -500 to 500. Default value: 0.
        // pitch_rate : 0
    };
    var bodyContent = JSON.stringify(task);
    console.log('The POST request body content: ' + bodyContent);
    /**
     * Set the HTTPS POST request header.
     */
    var httpHeaders = {
        'Content-type' : 'application/json'
    }
    /**
     * Set the HTTPS POST request.
     * The encoding parameter must be set to null. The body of the HTTPS response is a binary Buffer.
     */
    var options = {
        url: url,
        method: 'POST',
        headers: httpHeaders,
        body: bodyContent,
        encoding: null
    };
    request(options, function (error, response, body) {
        /**
         * Process the server-side response.
         */
        if (error != null) {
            console.log(error);
        }
        else {
            var contentType = response.headers['content-type'];
            if (contentType === undefined || contentType != 'audio/mpeg') {
                console.log(body.toString());
                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';
var sampleRate = 16000;
processGETRequest(appkey, token, textUrlEncode, audioSaveFile, format, sampleRate);
// processPOSTRequest(appkey, token, text, audioSaveFile, format, sampleRate);

.NET example

Note

This example has dependencies on 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. The domain name of the speech synthesis service: nls-gateway-cn-shanghai.aliyuncs.com
             * 3. The URI of the request for the speech synthesis API: /stream/v1/tts
             * 4. The required request parameters: appkey, token, text, format, and sample_rate.
             * 5. The optional request parameters: voice, volume, speech_rate, and pitch_rate.
             */
            string url = "http://nls-gateway.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: Optional. The speaker. Default value: xiaoyun.
            // url = url + "&voice=" + "xiaoyun";
            // volume: Optional. The volume. Valid values: 0 to 100. Default value: 50.
            // url = url + "&volume=" + 50;
            // speech_rate: Optional. The speech rate. Valid values: -500 to 500. Default value: 0.
            // url = url + "&speech_rate=" + 0;
            // pitch_rate: Optional. The pitch rate. Valid values: -500 to 500. Default value: 0.
            // url = url + "&pitch_rate=" + 0;
            System.Console.WriteLine(url);
            /**
             * Send an 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. The domain name of the speech synthesis service: nls-gateway-cn-shanghai.aliyuncs.com
             * 3. The URI of the request for the speech synthesis API: /stream/v1/tts
             * 4. The required request parameters: appkey, token, text, format, and sample_rate.
             * 5. The optional request parameters: voice, volume, speech_rate, and pitch_rate.
             */
            string url = "https://nls-gateway-cn-shanghai.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: Optional. The speaker. Default value: xiaoyun.
            // obj["voice"] = "xiaoyun";
            // volume: Optional. The volume. Valid values: 0 to 100. Default value: 50.
            // obj["volume"] = 50;
            // speech_rate: Optional. The speech rate. Valid values: -500 to 500. Default value: 0.
            // obj["speech_rate"] = 0;
            // pitch_rate: Optional. The pitch rate. Valid values: -500 to 500. Default value: 0.
            // obj["pitch_rate"] = 0;
            String bodyContent = obj.ToString();
            StringContent content = new StringContent(bodyContent, Encoding.UTF8, "application/json");
            /**
             * Send an 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 need params: <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 fine.";
            // Encode the URL based on the RFC 3986 standard.
            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 example

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. Use the HTTPS protocol.
     * 2. Specify the domain name of the speech synthesis service: nls-gateway-cn-shanghai.aliyuncs.com.
     * 3. Specify the URI of the request for the speech synthesis API: /stream/v1/tts.
     * 4. Set the required request parameters: appkey, token, text, format, and sample_rate.
     * 5. Set the optional request parameters: voice, volume, speech_rate, and pitch_rate.
     */
    var url string = "https://nls-gateway-cn-shanghai.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 voice for audio synthesis. This parameter is optional. Default value: xiaoyun.
    // url = url + "&voice=" + "xiaoyun"
    // volume: the volume. This parameter is optional. Valid values: 0 to 100. Default value: 50.
    // url = url + "&volume=" + strconv.Itoa(50)
    // speech_rate: the speech rate. This parameter is optional. Valid values: -500 to 500. Default value: 0.
    // url = url + "&speech_rate=" + strconv.Itoa(0)
    // pitch_rate: the pitch rate. This parameter is optional. Valid values: -500 to 500. Default value: 0.
    // url = url + "&pitch_rate=" + strconv.Itoa(0)
    fmt.Println(url)
    /**
     * Send an HTTPS GET request and process the response from the server.
     */
    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 succeed!")
    } else {
        // The Content-Type is null or application/json.
        statusCode := response.StatusCode
        fmt.Println("The HTTP statusCode: " + 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. Use the HTTPS protocol.
     * 2. Specify the domain name of the speech synthesis service: nls-gateway-cn-shanghai.aliyuncs.com.
     * 3. Specify the URI of the request for the speech synthesis API: /stream/v1/tts.
     * 4. Set the required request parameters: appkey, token, text, format, and sample_rate.
     * 5. Set the optional request parameters: voice, volume, speech_rate, and pitch_rate.
     */
    var url string = "https://nls-gateway-cn-shanghai.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 voice for audio synthesis. This parameter is optional. Default value: xiaoyun.
    // bodyContent["voice"] = "xiaoyun"
    // volume: the volume. This parameter is optional. Valid values: 0 to 100. Default value: 50.
    // bodyContent["volume"] = 50
    // speech_rate: the speech rate. This parameter is optional. Valid values: -500 to 500. Default value: 0.
    // bodyContent["speech_rate"] = 0
    // pitch_rate: the pitch rate. This parameter is optional. Valid values: -500 to 500. Default value: 0.
    // bodyContent["pitch_rate"] = 0
    bodyJson, err := json.Marshal(bodyContent)
    if err != nil {
        panic(nil)
    }
    fmt.Println(string(bodyJson))
    /**
     * Send an HTTPS POST request and process the response from the server.
     */
    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 succeed!")
    } else {
        // The Content-Type is null or application/json.
        statusCode := response.StatusCode
        fmt.Println("The HTTP statusCode: " + 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)
}