一句话识别 RESTful API 支持通过 HTTP POST 请求上传不超过 1 分钟的音频。服务端处理完成后,在 HTTP 响应中一次性返回 JSON 格式的识别结果。
前提条件
调用接口前,需准备以下信息:
音频要求
要求 | 说明 |
编码 | 单声道、16 bit 采样位数。 |
格式 | PCM、PCM 编码的 WAV、OGG 封装的 Opus、OGG 封装的 Speex、AMR、MP3、AAC。 |
采样率 | 8000 Hz 或 16000 Hz。 |
时长 | 不超过 1 分钟。 |
语种和场景模型不能通过请求参数指定。需在控制台为项目选择与音频匹配的模型,具体操作请参见管理项目。
不要在浏览器前端代码中直接调用该接口。浏览器可能因跨域资源共享(CORS)限制而拒绝请求,而且前端代码会暴露 AppKey 和 Token。
快速测试
下载示例音频 nls-sample-16k.wav。该文件为 16 kHz WAV 文件,适用于通用模型。
设置 AppKey 和 Token 后,运行以下命令:
curl -X POST \
-H "X-NLS-Token: <token>" \
"https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/asr?appkey=<appkey>&format=wav&sample_rate=16000" \
--data-binary @nls-sample-16k.wav成功响应示例:
{
"task_id": "cf7b0c5339244ee29cd4e43fb97f****",
"result": "北京的天气。",
"status": 20000000,
"message": "SUCCESS"
}交互流程
客户端在一个 HTTP POST 请求中发送鉴权信息、请求参数和完整音频。服务端处理完音频后,在同一 HTTP 连接中返回一次 JSON 响应。收到响应前不要中断连接。
客户端向服务端发起 POST 请求。
服务端校验鉴权信息和请求参数,并处理音频。
服务端返回任务 ID、状态码和识别结果。
服务地址
根据项目所在地域和网络环境选择服务地址。公网地址支持 HTTPS 和 HTTP,建议使用 HTTPS。
地域 | 网络 | 服务地址 |
华东 2(上海) | 公网 |
|
华北 2(北京) | 公网 |
|
华南 1(深圳) | 公网 |
|
华东 2(上海) | 内网 |
|
华北 2(北京) | 内网 |
|
华南 1(深圳) | 内网 |
|
API 说明
请求由请求行、请求头和请求体组成。
请求行
POST /stream/v1/asr?appkey=<appkey>&format=pcm&sample_rate=16000&enable_punctuation_prediction=true HTTP/1.1参数 | 类型 | 是否必选 | 默认值 | 说明 |
| String | 是 | 无 | 项目 AppKey。 |
| String | 否 |
| 音频格式。取值:pcm、wav、opus、speex、amr、mp3、aac。 |
| Integer | 否 |
| 音频采样率。取值:8000、16000,单位为 Hz。 |
| String | 否 | 无 | 热词表 ID。 |
| String | 否 | 无 | 自学习模型 ID。 |
| Boolean | 否 |
| 是否在后处理中添加标点。 |
| Boolean | 否 |
| 是否启用逆文本标准化,将口语数字转换为阿拉伯数字等规范格式。 |
| Boolean | 否 |
| 是否启用语音活动检测(VAD),自动检测有效语音的开始和结束。 |
| Boolean | 否 |
| 是否过滤语气词。 |
| String | 否 | 无 | 可通过公网访问的音频文件 URL。设置该参数时不需要在请求体中传入音频。 |
请求头
请求头 | 类型 | 是否必选 | 说明 |
| String | 是 | 用于身份验证的访问 Token。 |
| String | 是 |
|
| Long | 是 | 请求体中的音频数据大小,单位为字节。 |
| String | 是 | 所选服务地址的域名,例如 nls-gateway-cn-shanghai.aliyuncs.com。 |
请求体
将完整音频的二进制数据写入请求体,并将 Content-Type 设置为 application/octet-stream。
也可以通过 audio_address 传入可通过公网访问的音频文件 URL。使用该参数时,请求体为空。建议使用签名 URL,生成方法请参见使用预签名 URL 下载或预览文件。
请求示例
POST /stream/v1/asr?appkey=23f5****&format=pcm&sample_rate=16000 HTTP/1.1
X-NLS-Token: 450372e4279bcc2b3c793****
Content-Type: application/octet-stream
Content-Length: 94616
Host: nls-gateway-cn-shanghai.aliyuncs.com
[audio data]POST /stream/v1/asr?appkey=23f5****&format=wav&sample_rate=16000&audio_address=https%3A%2F%2Fexample.com%2Faudio.wav HTTP/1.1
X-NLS-Token: 450372e4279bcc2b3c793****
Host: nls-gateway-cn-shanghai.aliyuncs.com
Content-Length: 0响应说明
响应参数
参数 | 类型 | 说明 |
| String | 32 位任务 ID。排查问题时需提供该 ID。 |
| String | 识别结果。识别失败时为空字符串。 |
| Integer | 状态码。 |
| String | 状态说明。 |
成功响应
{
"task_id": "cf7b0c5339244ee29cd4e43fb97f****",
"result": "北京的天气。",
"status": 20000000,
"message": "SUCCESS"
}失败响应
{
"task_id": "8bae3613dfc54ebfa811a17d8a7a****",
"result": "",
"status": 40000001,
"message": "Gateway:ACCESS_DENIED:The token is invalid"
}排查失败请求时,记录响应中的任务 ID。
状态码
出现偶发的服务端错误(5xxxxxxx)时可以重试。如果错误持续出现,请提交工单并提供响应中的任务 ID。
状态码 | 说明 | 处理建议 |
| 请求成功。 | 无需处理。 |
| 客户端错误。 | 根据错误消息检查请求。 |
| 身份验证失败。 | 检查 Token 是否正确且未过期。 |
| 请求无效。 | 检查请求是否符合接口要求。 |
| 参数无效。 | 检查参数值是否在有效范围内。 |
| 客户端超时。 | 检查客户端是否停止发送数据。 |
| 请求速率超限。 | 检查并发数或 QPS 是否超过限制。 |
| 音频格式不支持。 | 检查 format 参数和实际音频格式。 |
| 采样率不支持。 | 检查 sample_rate 是否与音频和项目模型匹配。 |
| 服务端错误。 | 持续出现时提交工单并提供任务 ID。 |
| 服务内部调用错误。 | 持续出现时提交工单并提供任务 ID。 |
示例代码
以下示例从环境变量读取服务地址、AppKey、Token 和本地音频路径,并以二进制方式发送 PCM 音频。
获取 Token 的方法,请参见获取 Token。
环境变量 | 说明 |
|
|
| 项目 AppKey。 |
| 有效的访问 Token。 |
| 16 kHz、16 bit、单声道 PCM 音频文件的本地路径。 |
Java
示例使用 JDK 21。
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
public class SpeechRecognition {
private static String required(String name) {
String value = System.getenv(name);
if (value == null || value.isBlank()) {
throw new IllegalArgumentException("Missing environment variable: " + name);
}
return value;
}
public static void main(String[] args) throws Exception {
String endpoint = required("NLS_ENDPOINT");
String appKey = URLEncoder.encode(required("NLS_APP_KEY"), StandardCharsets.UTF_8);
String token = required("NLS_TOKEN");
Path audioFile = Path.of(required("NLS_AUDIO_FILE"));
String url = endpoint + "?appkey=" + appKey
+ "&format=pcm&sample_rate=16000"
+ "&enable_punctuation_prediction=true"
+ "&enable_inverse_text_normalization=true";
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.header("X-NLS-Token", token)
.header("Content-Type", "application/octet-stream")
.POST(HttpRequest.BodyPublishers.ofFile(audioFile))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
System.out.println(response.body());
}
}C++
示例使用 C++17 and libcurl 8.7.1。
#include <curl/curl.h>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <string>
std::string required(const char* name) {
const char* value = std::getenv(name);
if (value == nullptr || *value == '\0') {
throw std::runtime_error(std::string("Missing environment variable: ") + name);
}
return value;
}
size_t writeResponse(char* data, size_t size, size_t count, void* target) {
static_cast<std::string*>(target)->append(data, size * count);
return size * count;
}
int main() {
std::ifstream file(required("NLS_AUDIO_FILE"), std::ios::binary);
if (!file) throw std::runtime_error("Cannot open audio file");
std::string audio((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL* curl = curl_easy_init();
if (curl == nullptr) throw std::runtime_error("Cannot initialize cURL");
char* escaped = curl_easy_escape(curl, required("NLS_APP_KEY").c_str(), 0);
std::string url = required("NLS_ENDPOINT") + "?appkey=" + escaped
+ "&format=pcm&sample_rate=16000"
+ "&enable_punctuation_prediction=true"
+ "&enable_inverse_text_normalization=true";
curl_free(escaped);
std::string response;
std::string tokenHeader = "X-NLS-Token: " + required("NLS_TOKEN");
curl_slist* headers = nullptr;
headers = curl_slist_append(headers, tokenHeader.c_str());
headers = curl_slist_append(headers, "Content-Type: application/octet-stream");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, audio.data());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(audio.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeResponse);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
CURLcode code = curl_easy_perform(curl);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
if (code != CURLE_OK) throw std::runtime_error(curl_easy_strerror(code));
std::cout << response << std::endl;
}Python
示例使用 Python 3.14。
import os
import urllib.parse
import urllib.request
def required(name):
value = os.getenv(name)
if not value:
raise RuntimeError(f"Missing environment variable: {name}")
return value
endpoint = required("NLS_ENDPOINT")
query = urllib.parse.urlencode({
"appkey": required("NLS_APP_KEY"),
"format": "pcm",
"sample_rate": 16000,
"enable_punctuation_prediction": "true",
"enable_inverse_text_normalization": "true",
})
with open(required("NLS_AUDIO_FILE"), "rb") as audio_file:
request = urllib.request.Request(
f"{endpoint}?{query}",
data=audio_file.read(),
headers={
"X-NLS-Token": required("NLS_TOKEN"),
"Content-Type": "application/octet-stream",
},
method="POST",
)
with urllib.request.urlopen(request) as response:
print(response.read().decode("utf-8"))PHP
示例使用 PHP 8.5 with the cURL extension。
<?php
function required_env(string $name): string {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Missing environment variable: " . $name);
}
return $value;
}
$query = http_build_query([
'appkey' => required_env('NLS_APP_KEY'),
'format' => 'pcm',
'sample_rate' => 16000,
'enable_punctuation_prediction' => 'true',
'enable_inverse_text_normalization' => 'true',
]);
$audio = file_get_contents(required_env('NLS_AUDIO_FILE'));
if ($audio === false) {
throw new RuntimeException('Cannot read the audio file');
}
$curl = curl_init(required_env('NLS_ENDPOINT') . '?' . $query);
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $audio,
CURLOPT_HTTPHEADER => [
'X-NLS-Token: ' . required_env('NLS_TOKEN'),
'Content-Type: application/octet-stream',
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($curl);
if ($response === false) {
throw new RuntimeException(curl_error($curl));
}
echo $response . PHP_EOL;Node.js
示例使用 Node.js 22。
import fs from "node:fs";
import http from "node:http";
import https from "node:https";
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`Missing environment variable: ${name}`);
return value;
}
const endpoint = new URL(required("NLS_ENDPOINT"));
endpoint.search = new URLSearchParams({
appkey: required("NLS_APP_KEY"),
format: "pcm",
sample_rate: "16000",
enable_punctuation_prediction: "true",
enable_inverse_text_normalization: "true",
});
const audio = fs.readFileSync(required("NLS_AUDIO_FILE"));
const transport = endpoint.protocol === "https:" ? https : http;
const request = transport.request(endpoint, {
method: "POST",
headers: {
"X-NLS-Token": required("NLS_TOKEN"),
"Content-Type": "application/octet-stream",
"Content-Length": audio.length,
},
}, (response) => {
let body = "";
response.setEncoding("utf8");
response.on("data", (chunk) => { body += chunk; });
response.on("end", () => console.log(body));
});
request.on("error", (error) => { throw error; });
request.end(audio);C#
示例使用 .NET 8。
using System.Net.Http.Headers;
static string Required(string name)
{
string? value = Environment.GetEnvironmentVariable(name);
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException($"Missing environment variable: {name}");
return value;
}
string query = string.Join("&", new Dictionary<string, string>
{
["appkey"] = Required("NLS_APP_KEY"),
["format"] = "pcm",
["sample_rate"] = "16000",
["enable_punctuation_prediction"] = "true",
["enable_inverse_text_normalization"] = "true",
}.Select(item => $"{Uri.EscapeDataString(item.Key)}={Uri.EscapeDataString(item.Value)}"));
using HttpClient client = new();
using ByteArrayContent audio = new(await File.ReadAllBytesAsync(Required("NLS_AUDIO_FILE")));
audio.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
using HttpRequestMessage request = new(HttpMethod.Post, $"{Required("NLS_ENDPOINT")}?{query}");
request.Headers.Add("X-NLS-Token", Required("NLS_TOKEN"));
request.Content = audio;
using HttpResponseMessage response = await client.SendAsync(request);
Console.WriteLine(await response.Content.ReadAsStringAsync());Go
示例使用 Go 1.24。
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"net/url"
"os"
)
func required(name string) string {
value := os.Getenv(name)
if value == "" {
panic("Missing environment variable: " + name)
}
return value
}
func main() {
audio, err := os.ReadFile(required("NLS_AUDIO_FILE"))
if err != nil {
panic(err)
}
query := url.Values{
"appkey": {required("NLS_APP_KEY")},
"format": {"pcm"},
"sample_rate": {"16000"},
"enable_punctuation_prediction": {"true"},
"enable_inverse_text_normalization": {"true"},
}
request, err := http.NewRequest(
http.MethodPost, required("NLS_ENDPOINT")+"?"+query.Encode(), bytes.NewReader(audio))
if err != nil {
panic(err)
}
request.Header.Set("X-NLS-Token", required("NLS_TOKEN"))
request.Header.Set("Content-Type", "application/octet-stream")
response, err := http.DefaultClient.Do(request)
if err != nil {
panic(err)
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
}