RESTful API

更新时间:
复制 MD 格式

Use a single HTTP POST request to transcribe audio up to 1 minute long. The service returns the transcription result as JSON in the HTTP response. Keep the connection open until the response arrives.

Prerequisites

Before you begin, make sure you have:

Audio requirements

RequirementDetail
Encodingpulse-code modulation (PCM), 16-bit mono
FormatsPCM, PCM-encoded WAV, OGG-encapsulated Opus, OGG-encapsulated Speex
Sample rate8,000 Hz or 16,000 Hz
Max duration1 minute

To use a language other than the default, select the corresponding model when you edit your project in the Intelligent Speech Interaction console. See Manage projects.

Quick start

Download the sample audio file (nls-sample-16k.wav, 16 kHz WAV, generic model), then run:

curl -X POST \
  -H "X-NLS-Token: <your-token>" \
  "http://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asr?appkey=<your-appkey>" \
  --data-binary @nls-sample-16k.wav

Replace <your-token> and <your-appkey> with your credentials. A successful response looks like:

{
    "task_id": "cf7b0c5339244ee29cd4e43fb97f****",
    "result": "Weather in Beijing",
    "status": 20000000,
    "message": "SUCCESS"
}
The sample file uses a generic model. To test with a different audio file, set format and sample_rate to match your file, and select the appropriate model in the console.

How it works

The client sends one HTTP POST request with the audio data in the body. The server processes the audio and returns the transcription result in a single JSON response.

Interaction flowchart

Service endpoint

TypeURLHost
External networkshttp://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asrnls-gateway-ap-southeast-1.aliyuncs.com

API reference

Every request consists of a request line, request headers, and a request body.

Request line

POST /stream/v1/asr?appkey=<your-appkey>&format=pcm&sample_rate=16000&enable_punctuation_prediction=true HTTP/1.1

Request parameters

ParameterTypeRequiredDefaultDescription
appkeyStringYesYour project appkey.
formatStringNopcmAudio encoding format. Valid values: pcm, opus.
sample_rateIntegerNo16000Audio sample rate in Hz. Valid values: 16000, 8000.
vocabulary_idStringNoID of your hotword list.
customization_idStringNoID of your custom language model.
enable_punctuation_predictionBooleanNofalseSpecifies whether to add punctuation marks during post-processing.
enable_inverse_text_normalizationBooleanNofalseSpecifies whether to enable inverse text normalization (ITN) to convert spoken numbers to digits and apply other text normalizations during post-processing.
enable_voice_detectionBooleanNofalseSpecifies whether to enable voice activity detection (VAD) to detect speech boundaries automatically.

Request headers

HeaderTypeRequiredValue
X-NLS-TokenStringYesYour access token for authentication.
Content-TypeStringYesapplication/octet-stream
Content-LengthLongYesSize of the audio data in bytes.
HostStringYesnls-gateway-ap-southeast-1.aliyuncs.com

Request body

The request body is the raw binary audio data. Set Content-Type to application/octet-stream.

Example request

POST /stream/v1/asr?appkey=23f5****&format=pcm&sample_rate=16000&enable_punctuation_prediction=true&enable_inverse_text_normalization=true HTTP/1.1
X-NLS-Token: 450372e4279bcc2b3c793****
Content-Type: application/octet-stream
Content-Length: 94616
Host: nls-gateway-ap-southeast-1.aliyuncs.com

[audio data]

Responses

Response parameters

ParameterTypeDescription
task_idString32-character task ID. Record this for troubleshooting — include it when you submit a support ticket.
resultStringThe transcription text. Empty string if recognition fails.
statusIntegerStatus code.
messageStringStatus description.

Success response

{
    "task_id": "cf7b0c5339244ee29cd4e43fb97f****",
    "result": "Weather in Beijing",
    "status": 20000000,
    "message": "SUCCESS"
}

Error response

{
    "task_id": "8bae3613dfc54ebfa811a17d8a7a****",
    "result": "",
    "status": 40000001,
    "message": "Gateway:ACCESS_DENIED:The token 'c0c1e860f3*******de8091c68a' is invalid!"
}
The server includes task_id in error responses. Record the task ID and include it when you submit a support ticket.

Status codes

For server errors (5xxxxxxx), if the error occurs only occasionally, no action is needed. If it recurs, submit a support ticket and include the task_id from the response.

Status codeDescriptionResolution
20000000Request succeeded.
40000000Client error (default).Check the error message for details, or submit a support ticket.
40000001Authentication failed.Check that your token is valid and has not expired.
40000002Invalid request.Check that your request meets the API requirements.
40000003Invalid parameters.Check that all parameter values are within the valid ranges.
40000004Client timed out.Check whether the client stopped sending data to the server.
40000005Request rate exceeded.Check whether your concurrent connections or queries per second (QPS) exceed the limit.
41010101Unsupported sample rate.The sample rate in your code (8000 or 16000) must match the model bound to your appkey in the console (8k or 16k).
50000000Server error (default).Submit a support ticket with the task_id if this recurs.
50000001Internal gRPC call error.Submit a support ticket with the task_id if this recurs.

Code examples

All examples send binary audio data via HTTP POST using the same endpoint and headers. Set appkey, token, and optional parameters to match your project configuration.

Java

Add the following dependencies to your pom.xml:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.9.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version>
</dependency>
import com.alibaba.fastjson.JSONPath;
import com.alibaba.nls.client.example.utils.HttpUtil;
import java.util.HashMap;

public class SpeechRecognizerRESTfulDemo {
    private String accessToken;
    private String appkey;

    public SpeechRecognizerRESTfulDemo(String appkey, String token) {
        this.appkey = appkey;
        this.accessToken = token;
    }

    public void process(String fileName, String format, int sampleRate,
                        boolean enablePunctuationPrediction,
                        boolean enableInverseTextNormalization,
                        boolean enableVoiceDetection) {

        // Build the request URL with required and optional parameters
        String url = "http://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asr";
        String request = url + "?appkey=" + appkey
                + "&format=" + format
                + "&sample_rate=" + sampleRate;
        if (enablePunctuationPrediction) {
            request += "&enable_punctuation_prediction=true";
        }
        if (enableInverseTextNormalization) {
            request += "&enable_inverse_text_normalization=true";
        }
        if (enableVoiceDetection) {
            request += "&enable_voice_detection=true";
        }

        System.out.println("Request: " + request);

        // Set authentication token and binary content type
        HashMap<String, String> headers = new HashMap<>();
        headers.put("X-NLS-Token", this.accessToken);
        headers.put("Content-Type", "application/octet-stream");

        // Send the request and print the transcription result
        String response = HttpUtil.sendPostFile(request, headers, fileName);
        if (response != null) {
            System.out.println("Response: " + response);
            String result = JSONPath.read(response, "result").toString();
            System.out.println("Recognition result: " + result);
        } else {
            System.err.println("Recognition failed.");
        }
    }

    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("Usage: SpeechRecognizerRESTfulDemo <token> <appkey>");
            System.exit(-1);
        }

        String token = args[0];
        String appkey = args[1];

        SpeechRecognizerRESTfulDemo demo = new SpeechRecognizerRESTfulDemo(appkey, token);

        String fileName = SpeechRecognizerRESTfulDemo.class
                .getClassLoader().getResource("./nls-sample-16k.wav").getPath();

        demo.process(fileName, "pcm", 16000, true, true, false);
    }
}

HttpUtil class (uses OkHttp):

import okhttp3.*;
import java.io.File;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class HttpUtil {

    private static String getResponseWithTimeout(Request q) {
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .build();

        try {
            Response s = client.newCall(q).execute();
            String ret = s.body().string();
            s.close();
            return ret;
        } catch (SocketTimeoutException e) {
            System.err.println("Request timed out.");
            return null;
        } catch (IOException e) {
            System.err.println("Request error: " + e.getMessage());
            return null;
        }
    }

    public static String sendPostFile(String url, HashMap<String, String> headers, String fileName) {
        File file = new File(fileName);
        if (!file.isFile()) {
            System.err.println("File not found: " + fileName);
            return null;
        }

        RequestBody body = RequestBody.create(
                MediaType.parse("application/octet-stream"), file);

        Headers.Builder hb = new Headers.Builder();
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                hb.add(entry.getKey(), entry.getValue());
            }
        }

        Request request = new Request.Builder()
                .url(url).headers(hb.build()).post(body).build();

        return getResponseWithTimeout(request);
    }
}

C++

The C++ example uses the cURL library. Download the cURL library and demo.

The ZIP file contains:

File or folderDescription
CMakeLists.txtCMake build file
demo/restfulAsrDemo.cpp — the demo source file
include/cURL header files
lib/cURL dynamic library (curl-7.60) for Linux (Glibc 2.5, GCC 4, or GCC 5) and Windows (VS 2013 or VS 2015)
readme.txtDescription
release.logRelease notes
versionVersion number
build.shCompilation script

Build and run (Linux)

Assume the archive is extracted to path/to/sdk.

With CMake (version 2.4 or later):

cd path/to/sdk/lib && tar -zxvpf linux.tar.gz
cd path/to/sdk && ./build.sh
cd path/to/sdk/demo && ./restfulAsrDemo <your-token> <your-appkey>

Without CMake:

cd path/to/sdk/lib && tar -zxvpf linux.tar.gz
cd path/to/sdk/demo
g++ -o restfulAsrDemo restfulAsrDemo.cpp \
    -I path/to/sdk/include \
    -L path/to/sdk/lib/linux \
    -lssl -lcrypto -lcurl \
    -D_GLIBCXX_USE_CXX11_ABI=0
export LD_LIBRARY_PATH=path/to/sdk/lib/linux/
./restfulAsrDemo <your-token> <your-appkey>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "curl/curl.h"

using namespace std;

#ifdef _WIN32
string UTF8ToGBK(const string& strUTF8) {
    int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
    unsigned short * wszGBK = new unsigned short[len + 1];
    memset(wszGBK, 0, len * 2 + 2);
    MultiByteToWideChar(CP_UTF8, 0, (char*)strUTF8.c_str(), -1, (wchar_t*)wszGBK, len);
    len = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)wszGBK, -1, NULL, 0, NULL, NULL);
    char *szGBK = new char[len + 1];
    memset(szGBK, 0, len + 1);
    WideCharToMultiByte(CP_ACP, 0, (wchar_t*)wszGBK, -1, szGBK, len, NULL, NULL);
    string strTemp(szGBK);
    delete[] szGBK;
    delete[] wszGBK;
    return strTemp;
}
#endif

// Response callback — accumulates the JSON result string
size_t responseCallback(void* ptr, size_t size, size_t nmemb, void* userData) {
    string* srResult = (string*)userData;
    size_t len = size * nmemb;
    char *pBuf = (char*)ptr;
    string response = string(pBuf, pBuf + len);
#ifdef _WIN32
    response = UTF8ToGBK(response);
#endif
    cout << "current result: " << response << endl;
    *srResult += response;
    cout << "total result: " << *srResult << endl;
    return len;
}

int sendAsrRequest(const char* request, const char* token, const char* fileName, string* srResult) {
    // Read audio file into memory
    ifstream fs;
    fs.open(fileName, ios::out | ios::binary);
    if (!fs.is_open()) {
        cerr << "Audio file not found: " << fileName << endl;
        return -1;
    }
    stringstream buffer;
    buffer << fs.rdbuf();
    string audioData(buffer.str());

    CURL* curl = curl_easy_init();
    if (curl == NULL) return -1;

    // Set request line
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
    curl_easy_setopt(curl, CURLOPT_URL, request);

    // Set headers: token, content type, content length
    struct curl_slist* headers = NULL;
    string X_NLS_Token = "X-NLS-Token:" + string(token);
    headers = curl_slist_append(headers, X_NLS_Token.c_str());
    headers = curl_slist_append(headers, "Content-Type:application/octet-stream");
    ostringstream oss;
    oss << "Content-Length:" << audioData.length();
    headers = curl_slist_append(headers, oss.str().c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    // Set request body (binary audio data)
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, audioData.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, audioData.length());

    // Set response callback
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, srResult);

    CURLcode res = curl_easy_perform(curl);

    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;
    }
    return 0;
}

int process(const char* request, const char* token, const char* fileName) {
    curl_global_init(CURL_GLOBAL_ALL);
    string srResult = "";
    int ret = sendAsrRequest(request, token, fileName, &srResult);
    curl_global_cleanup();
    return ret;
}

int main(int argc, char* argv[]) {
    if (argc < 3) {
        cerr << "Usage: ./demo <your-token> <your-appkey>" << endl;
        return -1;
    }

    string token = argv[1];
    string appKey = argv[2];

    bool enablePunctuationPrediction = true;
    bool enableInverseTextNormalization = true;
    bool enableVoiceDetection = false;

    // Build the request URL
    string url = "http://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asr";
    ostringstream oss;
    oss << url
        << "?appkey=" << appKey
        << "&format=pcm"
        << "&sample_rate=16000";
    if (enablePunctuationPrediction) {
        oss << "&enable_punctuation_prediction=true";
    }
    if (enableInverseTextNormalization) {
        oss << "&enable_inverse_text_normalization=true";
    }
    if (enableVoiceDetection) {
        oss << "&enable_voice_detection=true";
    }

    string request = oss.str();
    cout << "request: " << request << endl;

    process(request.c_str(), token.c_str(), "sample.pcm");
    return 0;
}

Python

Use httplib for Python 2.x and http.client for Python 3.x.
# -*- coding: UTF-8 -*-
# For Python 2.x, replace http.client with httplib
import http.client
import json

def process(request, token, audioFile):
    # Read audio file
    with open(audioFile, mode='rb') as f:
        audioContent = f.read()

    host = 'nls-gateway-ap-southeast-1.aliyuncs.com'

    # Set authentication token and binary content type
    httpHeaders = {
        'X-NLS-Token': token,
        'Content-type': 'application/octet-stream',
        'Content-Length': len(audioContent)
    }

    conn = http.client.HTTPConnection(host)
    conn.request(method='POST', url=request, body=audioContent, headers=httpHeaders)

    response = conn.getresponse()
    print('Status:', response.status, response.reason)

    body = response.read()
    try:
        body = json.loads(body)
        print('Response:', body)
        if body['status'] == 20000000:
            print('Recognition result:', body['result'])
        else:
            print('Recognition failed.')
    except ValueError:
        print('Response is not valid JSON.')

    conn.close()


appKey = '<your-appkey>'
token = '<your-token>'
audioFile = '/path/to/nls-sample-16k.wav'

# Build the request URL
url = 'http://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asr'
request = (url
    + '?appkey=' + appKey
    + '&format=pcm'
    + '&sample_rate=16000'
    + '&enable_punctuation_prediction=true'
    + '&enable_inverse_text_normalization=true')

print('Request:', request)
process(request, token, audioFile)

PHP

Requires PHP 4.0.2 or later with cURL extensions enabled.
<?php

function process($token, $request, $audioFile) {
    $audioContent = file_get_contents($audioFile);
    if ($audioContent === false) {
        print "Audio file not found.\n";
        return;
    }

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_TIMEOUT, 120);

    // Set request URL and method
    curl_setopt($curl, CURLOPT_URL, $request);
    curl_setopt($curl, CURLOPT_POST, TRUE);

    // Set authentication token and binary content type
    $headers = array(
        "X-NLS-Token:" . $token,
        "Content-type:application/octet-stream",
        "Content-Length:" . strval(strlen($audioContent))
    );
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

    // Set request body (binary audio data)
    curl_setopt($curl, CURLOPT_POSTFIELDS, $audioContent);
    curl_setopt($curl, CURLOPT_NOBODY, FALSE);

    $returnData = curl_exec($curl);
    curl_close($curl);

    if ($returnData === false) {
        print "Request failed.\n";
        return;
    }

    print $returnData . "\n";

    $resultArr = json_decode($returnData, true);
    if ($resultArr["status"] == 20000000) {
        print "Recognition result: " . $resultArr["result"] . "\n";
    } else {
        print "Recognition failed.\n";
    }
}


$appkey = "<your-appkey>";
$token = "<your-token>";
$audioFile = "/path/to/nls-sample-16k.wav";

// Build the request URL
$request = "http://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asr"
    . "?appkey=" . $appkey
    . "&format=pcm"
    . "&sample_rate=16000"
    . "&enable_punctuation_prediction=true"
    . "&enable_inverse_text_normalization=true";

print "Request: " . $request . "\n";
process($token, $request, $audioFile);
?>

Node.js

Install the request package first:

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

function callback(error, response, body) {
    if (error) {
        console.log('Request error:', error);
        return;
    }
    console.log('Response:', body);
    if (response.statusCode === 200) {
        body = JSON.parse(body);
        if (body.status === 20000000) {
            console.log('Recognition result:', body.result);
        } else {
            console.log('Recognition failed.');
        }
    } else {
        console.log('HTTP error:', response.statusCode);
    }
}

function process(requestUrl, token, audioFile) {
    let audioContent;
    try {
        audioContent = fs.readFileSync(audioFile);
    } catch (error) {
        console.log('Audio file not found.');
        return;
    }

    // Set authentication token and binary content type
    const httpHeaders = {
        'X-NLS-Token': token,
        'Content-type': 'application/octet-stream',
        'Content-Length': audioContent.length
    };

    request({
        url: requestUrl,
        method: 'POST',
        headers: httpHeaders,
        body: audioContent
    }, callback);
}


const appkey = '<your-appkey>';
const token = '<your-token>';
const audioFile = '/path/to/nls-sample-16k.wav';

// Build the request URL
let requestUrl = 'http://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asr'
    + '?appkey=' + appkey
    + '&format=pcm'
    + '&sample_rate=16000'
    + '&enable_punctuation_prediction=true'
    + '&enable_inverse_text_normalization=true';

process(requestUrl, token, audioFile);

.NET

Requires System.Net.Http and Newtonsoft.Json.Linq.
using System;
using System.Net.Http;
using System.IO;
using Newtonsoft.Json.Linq;

namespace RESTfulAPI
{
    class SpeechRecognizerRESTfulDemo
    {
        private string token;
        private string appkey;

        public SpeechRecognizerRESTfulDemo(string appkey, string token)
        {
            this.appkey = appkey;
            this.token = token;
        }

        public void Process(string fileName, string format, int sampleRate,
            bool enablePunctuationPrediction,
            bool enableInverseTextNormalization,
            bool enableVoiceDetection)
        {
            // Build the request URL
            string url = "http://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asr"
                + "?appkey=" + appkey
                + "&format=" + format
                + "&sample_rate=" + sampleRate;
            if (enablePunctuationPrediction)
                url += "&enable_punctuation_prediction=true";
            if (enableInverseTextNormalization)
                url += "&enable_inverse_text_normalization=true";
            if (enableVoiceDetection)
                url += "&enable_voice_detection=true";

            Console.WriteLine("URL: " + url);

            if (!File.Exists(fileName))
            {
                Console.WriteLine("Audio file not found.");
                return;
            }

            HttpClient client = new HttpClient();
            // Set authentication token in the request header
            client.DefaultRequestHeaders.Add("X-NLS-Token", token);

            // Set request body (binary audio data)
            byte[] audioData = File.ReadAllBytes(fileName);
            ByteArrayContent content = new ByteArrayContent(audioData);
            content.Headers.Add("Content-Type", "application/octet-stream");

            HttpResponseMessage response = client.PostAsync(url, content).Result;
            string responseBodyAsText = response.Content.ReadAsStringAsync().Result;
            Console.WriteLine("Response: " + responseBodyAsText);

            if (response.IsSuccessStatusCode)
            {
                JObject obj = JObject.Parse(responseBodyAsText);
                Console.WriteLine("Recognition result: " + obj["result"]);
            }
            else
            {
                Console.WriteLine("Recognition failed: " + response.StatusCode + " " + response.ReasonPhrase);
            }
        }

        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("Usage: SpeechRecognizerRESTfulDemo <token> <appkey>");
                return;
            }

            var demo = new SpeechRecognizerRESTfulDemo(args[1], args[0]);
            demo.Process("nls-sample-16k.wav", "pcm", 16000, true, true, false);
        }
    }
}

Go

package main

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

func process(appkey, token, fileName, format string, sampleRate int,
    enablePunctuationPrediction, enableInverseTextNormalization, enableVoiceDetection bool) {

    // Build the request URL
    url := "http://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asr"
    url += "?appkey=" + appkey
    url += "&format=" + format
    url += "&sample_rate=" + strconv.Itoa(sampleRate)
    if enablePunctuationPrediction {
        url += "&enable_punctuation_prediction=true"
    }
    if enableInverseTextNormalization {
        url += "&enable_inverse_text_normalization=true"
    }
    if enableVoiceDetection {
        url += "&enable_voice_detection=true"
    }
    fmt.Println(url)

    // Read audio file
    audioData, err := ioutil.ReadFile(fileName)
    if err != nil {
        panic(err)
    }

    req, err := http.NewRequest("POST", url, bytes.NewBuffer(audioData))
    if err != nil {
        panic(err)
    }

    // Set authentication token and binary content type
    req.Header.Add("X-NLS-Token", token)
    req.Header.Add("Content-Type", "application/octet-stream")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))

    if resp.StatusCode == 200 {
        var resultMap map[string]interface{}
        if err = json.Unmarshal(body, &resultMap); err != nil {
            panic(err)
        }
        fmt.Println("Recognition result:", resultMap["result"].(string))
    } else {
        fmt.Println("Recognition failed. HTTP status:", strconv.Itoa(resp.StatusCode))
    }
}

func main() {
    process(
        "<your-appkey>",
        "<your-token>",
        "nls-sample-16k.wav",
        "pcm",
        16000,
        true,  // enable_punctuation_prediction
        true,  // enable_inverse_text_normalization
        false, // enable_voice_detection
    )
}

What's next