接入文档
REST API 直调 · MCP · Skill 一键安装
鉴权
所有 API 请求需要在 HTTP 头里带上 Bearer 形式的 API key:
Authorization: Bearer JK********
登录控制台后在「API key」面板复制;激活码用完后请重新购买。
POST /api/v1/tts
将文本合成为语音,返回音频公网地址。默认 mp3;传 format: "wav" 可直接拿到 PCM 16-bit / 单声道 / 44.1kHz 的 wav(计费不变)。
请求
POST /api/v1/tts HTTP/1.1 Host: vox.timor419.com Authorization: Bearer JK******** Content-Type: application/json { "text": "你好世界" }
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| text | string | 是 | 要合成的文本,1-2000 字符 |
| voice_id | string | 否 | 音色 ID(首页可试听挑选),也可以是你自己克隆的音色(cv- 开头,见「声音克隆」)。省略则用 /api/v1/voices 列表里的第一个(平台当前推荐) |
| format | "mp3" | "wav" | 否 | 输出格式,默认 mp3。wav 为 PCM 16-bit / 单声道 / 44.1kHz(车机铃声等需直接落地 .wav 的场景)。计费与 mp3 完全一致,url 后缀随之变化 |
响应
成功返回 200 OK, body 是 JSON。url 字段是合成好的 mp3 在公网的可播地址(任意浏览器直接打开就能听)。
{ "url": "https://oss.timor419.com/tts/output/abc123def456789abcdef0123456789a.mp3", "request_id": "abc123def456789abcdef0123456789a", "voice_id": "云楚灵", "units": 4, "remaining": 999996, "duration_ms": 3245 }
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | string | 是 | 音频公网地址(永久有效,匿名可访问);后缀随 format 为 .mp3 或 .wav |
| request_id | string | 是 | 本次请求唯一 ID(32 位 hex,幂等键) |
| voice_id | string | 是 | 实际使用的音色 ID |
| units | number | 是 | 本次扣费的字符数 |
| remaining | number | null | 否 | 剩余余额;扣费失败时为 null(见 billing_warning) |
| duration_ms | number | 是 | 合成耗时(毫秒) |
| billing_warning | string | 否 | 仅当扣费失败时出现;音频已生成可用,但本次未成功记账 |
GET /api/v1/voices
列出当前可用的音色。无需鉴权(匿名结果带 60s 边缘缓存)。 返回顺序:精选音色按管理员设置的顺序排在最前,其余按目录顺序。带鉴权调用时返回的是当前账户实际可用的列表(部分账户配置了专属音色套餐,列表可能与公开列表不同),并附加该账户克隆的音色("owned": true)。 程序集成建议始终带上 Authorization 头获取本账户的真实可用集。 管理员可加 ?group=<分组ID或名称> 查看指定分组(?group=all 为全量), 非管理员指定 group 返回 403。
请求
GET /api/v1/voices HTTP/1.1 Host: vox.timor419.com
响应
{ "voices": [ { "id": "云楚灵", "display_name": "云楚灵", "demo_url": "https://oss.timor419.com/tts/voice-demos/...", "featured": true }, { "id": "...", "featured": false } ], "total": 147 }
featured: true 标识该音色是当前精选; 已停用的音色不会出现在列表中。 带上 Authorization 头调用时, 列表末尾会附加你自己克隆的音色(标记 "owned": true)。 合成时 voice_id 请取 id 字段——display_name 仅供展示,可能重名。
声音克隆
上传一段你自己的参考音频,克隆出一个专属音色,之后像普通音色一样用 voice_id 合成。 克隆出的音色仅当前账户可见可用。
POST /api/v1/voices/clone — 克隆
参考音频要求:≤ 15MB、时长 ≤ 15 秒,格式支持 wav / mp3 / flac / m4a / aac / ogg(服务端自动转码)。 单人、无背景音乐的清晰录音克隆效果最好。 首次克隆会渲染一段试听 demo(约 20-40 秒),请把客户端超时设到 120 秒。 支持两种传法:上传文件(multipart/form-data)或传公网音频 URL(application/json,由服务端下载并缓存—— 同一 URL 再次克隆秒回,不重复下载)。
curl -s -X POST https://vox.timor419.com/api/v1/voices/clone \ -H "Authorization: Bearer JK********" \ -F "file=@my-voice.wav" \ -F "name=我的声音" \ --max-time 120
或者用 JSON 传一个公网可访问的 .wav URL:
curl -s -X POST https://vox.timor419.com/api/v1/voices/clone \ -H "Authorization: Bearer JK********" \ -H "Content-Type: application/json" \ -d '{"url":"https://example.com/my-voice.wav","name":"我的声音"}' \ --max-time 120
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | file | 否 | (multipart 方式)参考音频:wav/mp3/flac/m4a/aac/ogg,≤15MB,时长 ≤15 秒 |
| url | string | 否 | (JSON 方式)公网可访问的音频地址(格式同上),≤15MB,时长 ≤15 秒;服务端下载并按 URL 缓存。file / url 二选一 |
| name | string | 是 | 音色名称,1-64 字符(不能含 \ / : * ? " < > |) |
{ "ok": true, "duplicate": false, "voice": { "id": "cv-3f9a1b2c4d5e", "display_name": "我的声音", "demo_url": "https://oss.timor419.com/tts/clone-demos/....mp3", "duration_sec": 8.4, "created_at": "2026-06-06T08:00:00.000Z" }, "units": 300, "remaining": 999700 }
拿到 voice.id(cv- 开头)后,直接作为 voice_id 调用 POST /api/v1/tts 即可,按字符计费与普通音色完全一致。
- 计费:克隆一次性收 300 字符(与 TTS 同单位),试听 demo 包含在内。
- 去重:同一个文件(字节级相同)重复克隆不再收费,直接返回已有音色(
"duplicate": true),重试安全。 - URL 缓存:同一个 URL 再次克隆不会重新下载(按 URL 建索引)。 如果 URL 背后的内容换了,请改用文件上传。
- 授权提醒:请确保你对上传的声音拥有使用授权。
DELETE /api/v1/voices/clone — 删除
curl -s -X DELETE "https://vox.timor419.com/api/v1/voices/clone?voice_id=cv-3f9a1b2c4d5e" \ -H "Authorization: Bearer JK********"
返回 { "ok": true, "deleted": "cv-…" }。 删除只移除你账户里的这个音色,不影响余额。
GET /api/v1/voices/clone/precheck — 秒传预检(可选优化)
上传前先把文件算一个 SHA-256,问服务端这个文件是否已存在: 已存在则可改用 JSON 体 {"hash":"<sha256>","name":"…"} 调用克隆端点,跳过文件传输;自己已克隆过则无需任何操作。普通使用可以忽略这个端点。
HASH=$(sha256sum my-voice.wav | cut -d' ' -f1) curl -s "https://vox.timor419.com/api/v1/voices/clone/precheck?hash=$HASH" \ -H "Authorization: Bearer JK********"
返回 { exists, own_voice, fee_units, voice_count }。
GET /api/v1/balance
查询当前 API key 的余额。零扣费。
请求
GET /api/v1/balance HTTP/1.1 Host: vox.timor419.com Authorization: Bearer JK********
响应
{ "balance": 999580, "unit": "字符", "account_number": "ACC********", "app": { "slug": "vox", "name": "Vox" } }
代码示例
curl
curl -s -X POST https://vox.timor419.com/api/v1/tts \ -H "Authorization: Bearer JK********" \ -H "Content-Type: application/json" \ -d '{"text":"你好世界"}' \ | jq -r '.url'
省略 voice_id 时使用 voices 列表第一个音色;想指定音色则加上 "voice_id":"云楚灵"。输出一行 mp3 URL,浏览器打开即可播放。如果想保存本地:把 jq -r '.url' 换成 jq -r '.url' | xargs curl -fsSL -o hello.mp3。
Python
import requests resp = requests.post( "https://vox.timor419.com/api/v1/tts", headers={"Authorization": "Bearer JK********"}, json={"text": "你好世界"}, timeout=60, ) resp.raise_for_status() data = resp.json() print("url:", data["url"]) print("remaining:", data["remaining"])
Node.js
const res = await fetch("https://vox.timor419.com/api/v1/tts", { method: "POST", headers: { Authorization: "Bearer JK********", "Content-Type": "application/json", }, body: JSON.stringify({ text: "你好世界" }), }); if (!res.ok) throw new Error(`tts failed: ${res.status}`); const data = await res.json(); console.log("url:", data.url); console.log("remaining:", data.remaining);
错误码
| HTTP | code | 说明 |
|---|---|---|
| 400 | invalid_params | text 缺失 / 超长(> 2000 字)/ JSON 格式错误 |
| 400 | invalid_format | format 不是 mp3 或 wav |
| 401 | missing_api_key | Authorization 头缺失或格式错误 |
| 401 | invalid_api_key | API key 不存在或已被删除 |
| 402 | insufficient_balance | 余额不足,请重新购买激活码 |
| 403 | account_disabled | 账户被停用,请联系客服 |
| 403 | api_key_revoked | API key 已被吊销 |
| 403 | voice_disabled | 指定的音色已被管理员停用 |
| 403 | voice_not_allowed | 指定的音色不在当前账户的音色套餐内;带鉴权调用 GET /api/v1/voices 查看可用列表 |
| 403 | group_forbidden | voices 的 group 参数仅管理员可用 |
| 404 | group_not_found | voices 的 group 参数指定的分组不存在 |
| 404 | voice_not_found | voice_id(cv- 开头)不存在或不属于当前账户 |
| 400 | unsupported_audio / duration_exceeded / audio_parse_failed | 克隆参考音频不合规:须可解码音频(wav/mp3/flac/m4a/aac/ogg)、≤15MB、时长 ≤15 秒 |
| 400 | invalid_url / url_blocked | 克隆 url 无法解析 / 指向内网地址 |
| 413 | file_too_large / url_too_large | 克隆参考音频超过 15MB |
| 502 | url_fetch_failed | 克隆 url 下载失败(不可达 / 超时 30 秒) |
| 429 | rate_limited | 调用过快(TTS 60 次/分钟,克隆 10 次/分钟) |
| 502 | render_failed | 克隆试听渲染失败,未扣费,可重试 |
| 502 | synthesis_failed | 底层引擎合成失败,可重试 |
| 502 | storage_failed | 音频已合成但上传 CDN 失败,未扣费,可重试 |
| 502 | transcode_failed | format=wav 时 mp3→wav 转码失败,未扣费,可重试 |
| 504 | synthesis_failed (timeout) | 底层引擎超时,可重试 |
限流 + 计费
- 单个 API key:TTS 60 次/分钟、 克隆 10 次/分钟。超过返回 429 + Retry-After 头。
- 按字符计费:1 中文字符 = 1 字符;英文字母、空格、标点、数字也各算 1 字符。
- 声音克隆:一次性 300 字符/个(含试听 demo);同一文件重复克隆免费;用克隆音色合成与普通音色同价。
- 扣费幂等:调用失败时不扣费;调用成功扣费一次。(每次请求生成唯一 request_id,可在用量历史中查看。)
- 单次最长 2000 字符;更长请客户端拆段调用。