语音合成 API(TTS)
New API 的语音合成走异步任务:提交合成请求拿到任务 ID,再轮询任务状态取回音频。 同一套接口还提供音色设计(用文字描述生成新音色)与官方音色列表。
本页字段、校验规则与状态码直接对应仓库实现,改动代码时请同步更新:
relay/channel/task/ttscenter/models.go(请求/响应结构)、relay/channel/task/ttscenter/validation.go(校验规则与长度上限)、controller/tts.go(状态映射与响应组装)、router/tts-router.go(路由)。
端点一览
| 方法 | 路径 | 说明 |
|---|---|---|
POST | https://api.yu-yu.ai/v1/audio/speech/tasks | 提交语音合成任务 |
POST | https://api.yu-yu.ai/v1/voices/design/tasks | 提交音色设计任务 |
GET | https://api.yu-yu.ai/v1/tts/tasks/{task_id} | 查询任务状态与结果 |
GET | https://api.yu-yu.ai/v1/voices/official/all | 拉取官方音色列表 |
鉴权与请求标识
http
Authorization: Bearer sk-xxxxxxxxxxxxxxxx
Content-Type: application/json
Idempotency-Key: your-unique-key-001Idempotency-Key可选。同一个 key + 同一个请求体重复提交,只会创建一个任务,返回首次的任务 ID; 同一个 key 换成不同请求体会得到409 IDEMPOTENCY_CONFLICT。不传时网关按本次请求自动生成。 key 最长 191 个字符。X-Request-Id可选。不传时网关自动生成并在响应头回传,排查问题时带上它即可定位。
语音合成
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | 模型名,语音合成为 volcengine |
input | string | 是 | 待合成文本,最长 3000 字(按字符计) |
voice | string | 否 | 音色标识。可用官方音色列表接口查询;不传用模型默认音色 |
response_format | string | 否 | 音频格式,mp3(默认)/wav/pcm 三选一 |
speed | number | 否 | 语速,取值 0.5 ~ 2.0;超出范围报 INVALID_SPEED |
references | array | 否 | 参考素材数组,用于复刻/指定音色,见下 |
references[] 元素字段:
| 字段 | 类型 | 说明 |
|---|---|---|
audio_data | string | 参考音频(Base64),与 audio_url 互斥 |
audio_url | string | 参考音频 URL,与 audio_data 互斥 |
image_data | string | 参考图片(Base64),与 image_url 互斥 |
image_url | string | 参考图片 URL,与 image_data 互斥 |
每个元素至少要有一个音频或图片来源,否则报 EMPTY_REFERENCE。 注意:stream_format 在异步任务接口上不支持,传了会报 STREAM_NOT_SUPPORTED。
请求示例
bash
curl -X POST 'https://api.yu-yu.ai/v1/audio/speech/tasks' \
-H 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: speech-20260101-001' \
-d '{
"model": "volcengine",
"input": "欢迎使用 New API 语音合成接口。",
"voice": "zh_female_shuangkuaisisi_moon_bigtts",
"response_format": "mp3",
"speed": 1.0
}'音色设计
用一段描述生成一个可复用的新音色。字段比语音合成多,且必填项更多:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 音色名称 |
voice_slot_id | string | 是 | 音色位标识 |
prompt | string | 是 | 音色描述提示词,最长 200 字 |
preview_text | string | 是 | 试听文本,最长 300 字 |
language | string | 是 | zh、zh-CN、en、en-US 四选一 |
scene | string | 否 | 使用场景,最长 64 字 |
description | string | 否 | 补充描述,最长 500 字 |
age | string | 否 | 年龄特征,最长 32 字 |
gender | string | 否 | 性别特征,最长 32 字 |
avatar | string | 否 | 头像 URL,最长 1024 字 |
trialURL | string | 否 | 试听音频 URL,最长 1024 字 |
emotions | array | 否 | 情绪列表,元素形如 { "Icon": "...", "Label": "...", "Value": "..." } |
bash
curl -X POST 'https://api.yu-yu.ai/v1/voices/design/tasks' \
-H 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{
"name": "沉稳男声",
"voice_slot_id": "slot-001",
"prompt": "四十岁男性,声音低沉平稳,适合纪录片旁白",
"preview_text": "这里是试听文本。",
"language": "zh-CN"
}'提交响应
两个提交端点的返回结构一致:
json
{
"task_id": "task_xxxxxxxxxxxxxxxx",
"task_type": "speech_generation",
"status": 1,
"status_text": "排队中",
"progress": 0,
"status_url": "/v1/tts/tasks/task_xxxxxxxxxxxxxxxx",
"created_at": "2026-01-01T12:00:00"
}| 字段 | 类型 | 说明 |
|---|---|---|
task_id | string | 任务 ID,后续查询用它 |
task_type | string | speech_generation(语音合成)或 voice_design(音色设计) |
business_id | string | 仅音色设计返回,业务侧标识 |
status | integer | 任务状态码,见下表 |
status_text | string | 状态中文说明,与 status 一一对应 |
progress | integer | 进度百分比,0~100 |
status_url | string | 该任务的查询路径 |
created_at | string | 创建时间,格式 YYYY-MM-DDTHH:mm:ss |
查询任务
bash
curl 'https://api.yu-yu.ai/v1/tts/tasks/task_xxxxxxxxxxxxxxxx' \
-H 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx'响应在提交响应的字段基础上,补充了结果与时间信息:
| 字段 | 类型 | 说明 |
|---|---|---|
task_id / task_type / status / status_text / progress / status_url / created_at | — | 同提交响应,status/progress 会随任务推进变化 |
started_at | string | 开始时间;未开始时不返回该字段 |
finished_at | string | 完成时间;未完成时不返回该字段 |
error | object | 失败/取消/不存在时的 { code, message };其他状态不返回该字段 |
| 结果字段 | — | 成功时上游返回的结果字段(音频地址等)会被原样展开在顶层,字段名以实际上游返回为准 |
状态码
status | status_text | 含义 | 是否结束 |
|---|---|---|---|
1 | 排队中 | 已受理,等待生成 | 否 |
2 | 生成中 | 正在合成 | 否 |
3 | 生成成功 | 完成,可取回音频 | 是 |
4 | 生成失败 | 失败,看 error.message | 是 |
5 | 已取消 | 已取消 | 是 |
-1 | 未知或任务不存在 | 任务 ID 不属于当前 Key,或状态异常 | 是 |
注意查询一个不存在的任务返回 HTTP 200,靠 status = -1 与 error.code = TASK_NOT_FOUND 判定, 不要只看状态码。
官方音色列表
bash
curl 'https://api.yu-yu.ai/v1/voices/official/all' \
-H 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx'返回官方可用音色集合(字段由语音服务提供,网关原样透传)。该端点不可用时返回 503,错误码 UPSTREAM_UNAVAILABLE。
轮询建议
- 合成通常几秒到十几秒完成,建议首次延迟 2~3 秒、之后每 2 秒查询一次,上限 15 次左右。
- 命中
3/4/5/-1立即停止轮询。 - 用
Idempotency-Key+ 失败重试可以安全重发,不会产生重复任务。
错误响应
错误体形如:
json
{
"error": {
"message": "input is required",
"type": "invalid_request_error",
"param": "input",
"code": "REQUIRED_FIELD_MISSING"
}
}| 错误码 | 触发条件 | 处理方式 |
|---|---|---|
READ_REQUEST_BODY_FAILED | 请求体读取失败或超长 | 检查请求体大小与编码 |
INVALID_JSON | 请求体不是合法 JSON | 校验 JSON 语法 |
REQUIRED_FIELD_MISSING | 缺少必填字段(param 指出是哪一个) | 按字段表补齐 |
FIELD_TOO_LONG | 文本超出长度上限(param 指出字段) | 按上表裁剪 |
INVALID_RESPONSE_FORMAT | response_format 不是 mp3/wav/pcm | 改用支持的值 |
INVALID_SPEED | speed 不在 0.5~2.0 | 调整语速 |
STREAM_NOT_SUPPORTED | 传了 stream_format | 去掉该字段(异步任务不支持流式) |
MUTUALLY_EXCLUSIVE_REFERENCE_FIELDS | 同一参考素材同时给了 data 与 url | 二选一 |
EMPTY_REFERENCE | references[] 元素没有任何素材 | 至少给音频或图片来源 |
UNSUPPORTED_LANGUAGE | language 不在白名单 | 用 zh/zh-CN/en/en-US |
UNSUPPORTED_TTS_PATH | 提交到了不支持的路径 | 用本文档列出的两个提交端点 |
IDEMPOTENCY_CONFLICT | 同一个 Idempotency-Key 配了不同请求体 | 换 key 或改用同样的请求体 |
IDEMPOTENCY_KEY_TOO_LONG | Idempotency-Key 超过 191 字符 | 缩短 key |
TASK_QUERY_FAILED | 查询任务时服务端异常 | 稍后重试 |
TASK_NOT_FOUND | 查询的任务不存在或不属于当前 Key | 核对任务 ID |
UPSTREAM_UNAVAILABLE | 语音服务暂时不可用 | 稍后重试 |
常见问题
- 合成成功但没找到音频地址:成功时结果字段由语音服务返回,名称以实际响应为准;也可以直接用 响应里的
status_url配合本文档的查询端点复查。 - 音色设计报缺少
voice_slot_id:该字段必填,取值由你的业务侧约定(例如slot-001)。 - 重复提交产生了两个任务:检查是否每次都传了不同的
Idempotency-Key;同一个 key 才会去重。 - 查询一直返回
1:任务在排队。语音服务并发有限,排队时间随并发量波动。
