文字转语音(同步)v3
使用供应商无关的 HTTP v3 协议同步生成语音,或创建可恢复的异步任务。
HTTP TTS v3 是新接入推荐使用的统一协议。平台负责供应商路由,客户端只使用公共 voiceId、modelId 和通用控制参数。
切换模型时,接口地址、鉴权方式和响应结构保持不变,但必须重新确认音色返回的 modelIds 包含目标 modelId。不同模型支持的控制参数、文本长度和输出格式也可能不同。
Base URL
https://fishaudio.org/api/open/v3除能力目录和 OpenAPI 文档外,所有接口都需要服务端保存的 Bearer API Key。不要把 API Key 写入浏览器、移动端安装包或公开仓库。
选择同步还是异步
| 场景 | 推荐接口 | 原因 |
|---|---|---|
| 短文本、调用方可以持续等待 HTTP 响应 | POST /speech/tts | 成功后直接返回音频二进制 |
| 长文本、批量任务、需要可靠查询结果 | POST /speech/tts/jobs | 返回任务 ID,可以轮询并重新下载结果 |
| 响应丢失后必须找回音频 | 异步 Jobs | 同步接口不会重放已经返回过的音频 |
第一步:查询模型能力
能力接口无需鉴权。请在生成请求前读取它,不要在客户端硬编码模型能力。
curl "https://fishaudio.org/api/open/v3/speech/tts/capabilities"{
"contractVersion": "v3",
"route": "/api/open/v3/speech/tts",
"models": [
{
"id": "fishaudio-s21pro-flash",
"available": true,
"maxTextLength": 10000,
"outputFormats": ["mp3", "wav", "ogg"],
"controls": {
"speed": true,
"volume": true,
"stability": true,
"similarity": true
},
"supportedOperations": {
"synchronous": true,
"asynchronous": true
}
}
]
}只选择 available=true 的模型,并以该模型返回的 maxTextLength、outputFormats 和 controls 为准。
第二步:查询兼容音色
curl "https://fishaudio.org/api/open/v3/voices?page=1&pageSize=20&includePersonal=false" \
-H "Authorization: Bearer $FISHAUDIO_API_KEY"{
"total": 1,
"page": 1,
"pageSize": 20,
"totalPages": 1,
"items": [
{
"voiceId": "00a1b221-6137-4b73-ad62-b0cbce134167",
"name": "System test voice",
"isPersonal": false,
"primaryLanguage": "zh",
"languages": ["zh"],
"modelIds": ["fishaudio-s21pro-flash"]
}
],
"requestId": "req_xxx"
}modelIds 是该音色当前可以使用的公共模型列表。生成前必须选择一个同时满足“模型可用”和“音色兼容”的组合。查询单个音色可调用 GET /voices/{voiceId}。
第三步:同步生成
POST /api/open/v3/speech/ttscurl "https://fishaudio.org/api/open/v3/speech/tts" \
-H "Authorization: Bearer $FISHAUDIO_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Request-Id: trace-123-segment-1" \
-H "Idempotency-Key: tts-order-123-segment-1" \
-d '{
"text": "你好,这是一段 HTTP TTS v3 测试。",
"voiceId": "00a1b221-6137-4b73-ad62-b0cbce134167",
"modelId": "fishaudio-s21pro-flash",
"format": "mp3",
"speed": 1,
"volume": 0,
"stability": 1,
"similarity": 1,
"language": "zh",
"textNormalization": true
}' \
--output speech.mp3请求字段
| 字段 | 类型 | 必填 | 约束与默认值 |
|---|---|---|---|
text | string | 是 | 1–10,000 字符,同时不能超过所选模型的 maxTextLength |
voiceId | string | 是 | 从 /voices 获取,且必须支持所选 modelId |
modelId | string | 是 | 能力目录返回的公共模型 ID |
format | string | 否 | mp3、wav 或 ogg,默认 mp3;还必须在模型的 outputFormats 中 |
speed | number | 否 | 0.5–2,默认 1 |
volume | number | 否 | -20–20,默认 0 |
pitch | number | 否 | -12–12,仅在能力目录声明支持时发送 |
stability | number | 否 | 0.5–1.5,仅在能力目录声明支持时发送 |
similarity | number | 否 | 0.5–1.5,仅在能力目录声明支持时发送 |
language | string | 否 | 1–64 字符的语言提示 |
emotion | string | 否 | 1–64 字符的全局情绪 ID |
instruction | string | 否 | 最多 1,600 字符的风格、方言、角色或情绪指令 |
textNormalization | boolean | 否 | 是否启用结构化文本读音归一化 |
请求合同是严格的:provider、供应商 API Key、供应商原生模型字段和其它未知字段都会返回 400。合法但当前模型不支持的通用控制参数会被忽略,并在 X-OpenAPI-Ignored-Parameters 中列出。
成功响应
HTTP/1.1 200 OK
Content-Type: audio/mpeg
X-Request-Id: trace-123-segment-1
X-OpenAPI-Quota-Remaining: 99994
X-OpenAPI-Credits-Used: 6
X-OpenAPI-Ignored-Parameters: pitch
<binary audio data>客户端必须先检查 HTTP 状态码,再根据 Content-Type 处理响应。成功响应是音频二进制;错误响应是 JSON。X-OpenAPI-Ignored-Parameters 只在确实忽略了参数时出现。
异步任务
长文本、批量任务或要求结果可恢复的业务应使用 Jobs。创建请求体与同步 v3 相同。
curl "https://fishaudio.org/api/open/v3/speech/tts/jobs" \
-H "Authorization: Bearer $FISHAUDIO_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Request-Id: trace-job-001" \
-H "Idempotency-Key: tts-job-001" \
-d '{
"text": "需要可靠生成和下载的文本。",
"voiceId": "00a1b221-6137-4b73-ad62-b0cbce134167",
"modelId": "fishaudio-s21pro-flash",
"format": "mp3"
}'创建成功返回 202 Accepted。Location 指向任务状态资源,Retry-After 给出建议轮询间隔。立即保存 task.taskId:
{
"task": {
"taskId": "task_123",
"status": "pending",
"voiceId": "00a1b221-6137-4b73-ad62-b0cbce134167",
"modelId": "fishaudio-s21pro-flash"
},
"requestId": "trace-job-001",
"quotaRemaining": 99994,
"creditsUsed": 6,
"ignoredParameters": []
}GET /speech/tts/jobs/{jobId}
GET /speech/tts/jobs?page=1&limit=20&status=success
GET /speech/tts/jobs/{jobId}/audio?download=1
GET /speech/tts/jobs/{jobId}/segments/{segmentIndex}
Authorization: Bearer FISHAUDIO_API_KEYpending 和 processing 不是终态;只有 success、partial_fail、fail 是终态。下载音频时保留 Bearer 认证并允许客户端跟随重定向。
错误格式与处理
{
"code": "ERR_REQUEST_ID_CONFLICT",
"message": "Request id was reused with a different request",
"requestId": "tts-order-123-segment-1"
}| 状态码 | 常见原因 | 客户端处理 |
|---|---|---|
400 | JSON、字段、模型、音色或格式无效 | 修正请求,不要原样重试 |
401 | API Key 缺失或无效 | 更新服务端凭证 |
402 | API 额度不足 | 停止任务并提示充值或调整额度 |
404 | 音色或异步任务不存在 | 检查 ID 和所属账户 |
409 | 请求正在处理、已完成、已退款或请求 ID 冲突 | 根据 code 处理,不要盲目换 ID 重试 |
413 | HTTP 请求体超过上限 | 缩小请求;长文本改用 Jobs |
429 | 超过接口限流 | 遵循 Retry-After 并指数退避 |
500 | 平台或供应商生成失败 | 先保存 requestId,确认结算状态后再重试 |
503 | 所选模型当前不可用 | 重新查询能力目录并选择可用模型 |
幂等、计费与重试
X-Request-Id 是追踪 ID,服务端会在响应中回显;没有传入时服务端自动生成。Idempotency-Key 是业务幂等键,最长 128 字符。每次逻辑生成创建一个稳定的幂等键,仅在重试完全相同的请求时复用,不要并发发送相同键。
已有客户端可以暂时继续把 X-Request-Id 用作兼容幂等键;新客户端必须分开传入两个请求头。没有传入 Idempotency-Key 时,本次调用仍会生成,但客户端不能依赖该调用的幂等重试。
- 同步接口采用 at-most-once(至多一次) 语义:完成后复用同一个幂等键返回
409 ERR_REQUEST_ALREADY_COMPLETED,不会重放音频,也不会再次扣费。 - 异步创建接口会为相同请求重放已经接受的任务,可以继续查询和下载,不会重复计费。
- 同一个幂等键携带不同参数会返回
409 ERR_REQUEST_ID_CONFLICT。 - 客户端超时不代表服务端已停止。需要在响应丢失后找回结果时,必须使用异步 Jobs。
- 参数、鉴权或额度校验失败不会扣费;生成或结算失败时平台会执行退款流程。
机器可读合同与迁移
完整 OpenAPI 3.1:
GET /api/open/v3/openapi.jsonOpenAPI 描述固定字段和响应结构,能力接口描述当前模型可用性;两者需要一起读取。现有 v1、v2 客户端继续兼容,新客户端使用 v3。版本字段和路径变化见迁移指南。