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:
An appkey — create a project in the Intelligent Speech Interaction console to get one
An access token — see Obtain an access token
Audio requirements
| Requirement | Detail |
|---|---|
| Encoding | pulse-code modulation (PCM), 16-bit mono |
| Formats | PCM, PCM-encoded WAV, OGG-encapsulated Opus, OGG-encapsulated Speex |
| Sample rate | 8,000 Hz or 16,000 Hz |
| Max duration | 1 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.wavReplace <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, setformatandsample_rateto 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.

Service endpoint
| Type | URL | Host |
|---|---|---|
| External networks | http://nls-gateway-ap-southeast-1.aliyuncs.com/stream/v1/asr | nls-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.1Request parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
appkey | String | Yes | — | Your project appkey. |
format | String | No | pcm | Audio encoding format. Valid values: pcm, opus. |
sample_rate | Integer | No | 16000 | Audio sample rate in Hz. Valid values: 16000, 8000. |
vocabulary_id | String | No | — | ID of your hotword list. |
customization_id | String | No | — | ID of your custom language model. |
enable_punctuation_prediction | Boolean | No | false | Specifies whether to add punctuation marks during post-processing. |
enable_inverse_text_normalization | Boolean | No | false | Specifies whether to enable inverse text normalization (ITN) to convert spoken numbers to digits and apply other text normalizations during post-processing. |
enable_voice_detection | Boolean | No | false | Specifies whether to enable voice activity detection (VAD) to detect speech boundaries automatically. |
Request headers
| Header | Type | Required | Value |
|---|---|---|---|
X-NLS-Token | String | Yes | Your access token for authentication. |
Content-Type | String | Yes | application/octet-stream |
Content-Length | Long | Yes | Size of the audio data in bytes. |
Host | String | Yes | nls-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
| Parameter | Type | Description |
|---|---|---|
task_id | String | 32-character task ID. Record this for troubleshooting — include it when you submit a support ticket. |
result | String | The transcription text. Empty string if recognition fails. |
status | Integer | Status code. |
message | String | Status 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 code | Description | Resolution |
|---|---|---|
20000000 | Request succeeded. | — |
40000000 | Client error (default). | Check the error message for details, or submit a support ticket. |
40000001 | Authentication failed. | Check that your token is valid and has not expired. |
40000002 | Invalid request. | Check that your request meets the API requirements. |
40000003 | Invalid parameters. | Check that all parameter values are within the valid ranges. |
40000004 | Client timed out. | Check whether the client stopped sending data to the server. |
40000005 | Request rate exceeded. | Check whether your concurrent connections or queries per second (QPS) exceed the limit. |
41010101 | Unsupported 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). |
50000000 | Server error (default). | Submit a support ticket with the task_id if this recurs. |
50000001 | Internal 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 folder | Description |
|---|---|
CMakeLists.txt | CMake 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.txt | Description |
release.log | Release notes |
version | Version number |
build.sh | Compilation 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
Usehttplibfor Python 2.x andhttp.clientfor 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 --saveconst 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
RequiresSystem.Net.HttpandNewtonsoft.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
Manage projects — configure hotword lists, custom language models, and language selection
Obtain an access token — refresh or regenerate tokens