1. 接入前准备
获取 API Key
登录后进入 API 接入 页面创建 Key。默认以 bet_ 开头、总长 44 位;后台可修改开头与总长度,以站点设置为准。只在创建时显示一次,服务端仅保存 SHA-256。
bet_你的KEY 是占位符,必须替换成真实 Key;直接复制占位符请求会返回 401 API Key 无效。Base URL
https://tts.blackegg.cn
鉴权方式
| 场景 | 请求头 / 参数 |
|---|---|
| 本站原生、OpenAI、Fish Audio | Authorization: Bearer <你的KEY> |
| Gemini(推荐) | x-goog-api-key: <你的KEY> |
| Gemini(备用) | URL 参数 ?key=<你的KEY> |
兼容层使用本站 bet_ Key,不是 OpenAI / Fish / Google 官方 Key;请勿填各厂商的官方密钥。
通用限制
- 每个 Key 每分钟最多 30 次(后台可调)。
- 单条文本最多 500 字(后台可调)。
- 只输出
audio/mpeg(MP3);请求其他格式会返回 400。 - 未传音色时按「个人默认音色 > 站点默认音色 > fish 默认」回落。
- 开启计费后按模型与字数扣余额,余额不足返回 402。
2. 接口总览
| 兼容格式 | 方法与路径 | 成功响应 |
|---|---|---|
| 本站原生 | POST /api/v1/tts | JSON(可切换为音频二进制) |
| OpenAI | POST /v1/audio/speech | 音频二进制 |
| Fish Audio | POST /v1/tts | 音频二进制 |
| Gemini | POST /v1beta/models/{model}:generateContent | JSON(base64 音频) |
| 音色列表 | GET /api/v1/voices | JSON |
| 用量查询 | GET /api/v1/me | JSON |
所有接口都支持 OPTIONS 预检,返回 204,并带 CORS 头。
3. 本站原生接口
POST/api/v1/tts
请求参数(JSON)
| 字段 | 必填 | 说明 |
|---|---|---|
text | 是 | 要合成的文本,≤ 500 字。 |
voice_id | 否 | 直接作为 fish 的 reference_id 使用。 |
voice | 否 | 可传音色库 id、名称或 ref_id;优先级低于 voice_id。 |
model | 否 | fish 模型或后台模型 code;未知值回落站点默认模型。 |
响应
默认返回 JSON:
{"ok":true,"id":12,"url":"/audio?id=12","bytes":23456,"model":"s2.1-pro-free"}
请求头带 Accept: audio/mpeg 时直接返回 MP3 二进制。
示例
curl -X POST https://tts.blackegg.cn/api/v1/tts \
-H "Authorization: Bearer bet_你的KEY" \
-H "Content-Type: application/json" \
-d '{"text":"你好,世界","voice":"示例音色","model":"s2.1-pro-free"}'
4. OpenAI TTS 兼容
POST/v1/audio/speech
可直接把 OpenAI SDK 的 base_url 指向本站 https://tts.blackegg.cn/v1。
请求参数(JSON)
| 字段 | 必填 | 说明 |
|---|---|---|
input | 是 | 要合成的文本,≤ 500 字。 |
model | 否 | 任意值;本站认识的模型会保留,tts-1 等未知值回落站点默认模型。 |
voice | 否 | 可传音色库 id / 名称 / ref_id;alloy 等 OpenAI 内置音色名不在音色库时回落默认音色。 |
response_format | 否 | 只支持 mp3(默认),其他值返回 400。 |
speed | 否 | 接受但忽略,本站不做变速。 |
响应
成功返回 200,Content-Type: audio/mpeg,响应体为 MP3 字节;附带 X-Gen-Id 便于排查。
示例(curl)
curl -X POST https://tts.blackegg.cn/v1/audio/speech \
-H "Authorization: Bearer bet_你的KEY" \
-H "Content-Type: application/json" \
-d '{"model":"s2.1-pro-free","voice":"示例音色","input":"你好,世界","response_format":"mp3"}' \
--output hello.mp3
示例(OpenAI Python SDK)
from openai import OpenAI
client = OpenAI(api_key="bet_你的KEY", base_url="https://tts.blackegg.cn/v1")
resp = client.audio.speech.create(
model="s2.1-pro-free",
voice="示例音色",
input="你好,世界",
)
resp.stream_to_file("hello.mp3")
response_format;如果显式改成 wav/opus,本站会返回 400。请保持 mp3。5. Fish Audio 兼容
POST/v1/tts
字段与 fish.audio 的 /v1/tts 对齐,可把 Fish 客户端的 Base URL 指向本站;鉴权仍用本站 bet_ Key。
请求参数(JSON)
| 字段 | 必填 | 说明 |
|---|---|---|
text | 是 | 要合成的文本,≤ 500 字。 |
reference_id | 否 | 音色库 ref_id,或直接透传任意 fish 参考音色 ID;不传用默认音色。 |
format | 否 | 只支持 mp3(默认),其他值返回 400。 |
model | 否 | 也可放在请求头 model;未知值回落站点默认模型。 |
mp3_bitrate / chunk_length / normalize / latency / prosody | 否 | 接受但忽略,由 fish.audio 默认行为决定。 |
响应
成功返回 200,响应体为 MP3 字节,Content-Type: audio/mpeg。
示例
curl -X POST https://tts.blackegg.cn/v1/tts \
-H "Authorization: Bearer bet_你的KEY" \
-H "Content-Type: application/json" \
-d '{"text":"你好,世界","reference_id":"YOUR_REFERENCE_ID","format":"mp3"}' \
--output hello.mp3
错误格式:{"detail":"错误原因"},HTTP 状态码与原生接口一致。
6. Gemini TTS 兼容
POST/v1beta/models/{model}:generateContent
接受 Gemini generateContent 的请求结构,返回 candidates[0].content.parts[0].inlineData。路径里的模型名只用于兼容,实际使用站点默认模型。
请求参数(JSON)
| 字段 | 必填 | 说明 |
|---|---|---|
contents[].parts[].text | 是 | 要合成的文本,多个 part 会用换行拼接;总长 ≤ 500 字。 |
generationConfig.responseModalities | 否 | 建议传 ["AUDIO"],不传也按音频处理。 |
generationConfig.speechConfig.voiceConfig.prebuiltVoiceConfig.voiceName | 否 | 与音色库名称匹配时使用该音色;Kore 等 Gemini 内置名不在库时回落默认音色。 |
响应
{
"candidates": [{
"content": {
"parts": [{
"inlineData": {"mimeType": "audio/mpeg", "data": "<base64 MP3>"}
}],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}],
"modelVersion": "s2.1-pro-free",
"usageMetadata": {"promptTokenCount": 6, "candidatesTokenCount": 0, "totalTokenCount": 6}
}
audio/L16);本站返回 audio/mpeg 的 base64。按 mimeType 解码即可,若客户端写死 PCM 需自行转码或改用其他兼容格式。示例(curl)
curl -X POST "https://tts.blackegg.cn/v1beta/models/gemini-2.5-flash-preview-tts:generateContent" \
-H "x-goog-api-key: bet_你的KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{"parts": [{"text": "你好,世界"}]}],
"generationConfig": {
"responseModalities": ["AUDIO"],
"speechConfig": {"voiceConfig": {"prebuiltVoiceConfig": {"voiceName": "示例音色"}}}
}
}'
也支持 ?key=bet_你的KEY 和 Authorization: Bearer 两种鉴权。
7. 音色与模型
查询音色
curl https://tts.blackegg.cn/api/v1/voices -H "Authorization: Bearer bet_你的KEY"
返回:
{"ok":true,"count":2,"voices":[
{"id":3,"name":"示例音色","ref_id":"YOUR_REF_A","model":"","tags":"","remark":""},
{"id":4,"name":"示例音色 B","ref_id":"YOUR_REF_B","model":"","tags":"","remark":""}
]}
音色取值
- 推荐使用
ref_id,稳定且不受改名影响。 - 也可用音色库
id或name(名称需唯一且启用)。 - 默认音色在「个人设置 → 默认音色」和「后台 → 站点设置 → 站点默认音色」配置。
本站可用模型
| 模型名称 | 调用 code | 计费 |
|---|---|---|
| 标准模型(免费) | s2.1-pro-free |
免费 |
| 高质量模型 | s2-pro |
¥0.0010/次 + ¥0.0001/5字 |
| 旗舰模型 | s2.1-pro |
¥0.0030/次 + ¥0.0003/5字 |
调用时 model 填「调用 code」一列;页面显示的名称不能直接用于接口。
模型取值
- 优先使用上表的「调用 code」;也可用 fish 内置模型:
s2.1-pro-free、s2-pro、s2.1-pro。 - 不传
model时使用站点默认模型;OpenAI / Gemini 格式里的模型名不认识时也会回落默认模型。
8. 错误码
| HTTP | 含义 | OpenAI 格式 | Fish 格式 | Gemini 格式 |
|---|---|---|---|---|
| 400 | 参数错误 / 未配置 fish Key / 不支持的格式 | error.message | detail | error.message |
| 401 | Key 缺失或无效 | authentication_error | detail | UNAUTHENTICATED |
| 402 | 余额不足 | invalid_request_error | detail | FAILED_PRECONDITION |
| 403 | Key / 账号停用 | invalid_request_error | detail | PERMISSION_DENIED |
| 405 | 方法不允许 | invalid_request_error | detail | INVALID_ARGUMENT |
| 422 | 文本为空或超长 | invalid_request_error | detail | INVALID_ARGUMENT |
| 429 | 超过每分钟限流 | invalid_request_error | detail | RESOURCE_EXHAUSTED |
| 500 | 存储或服务异常 | server_error | detail | INTERNAL |
| 502 | 上游 fish.audio 失败 | server_error | detail | UNAVAILABLE |
| 503 | 站点关闭开放 API | server_error | detail | UNAVAILABLE |
9. 常见问题
为什么只支持 MP3?
站点底层由 fish.audio 返回 MP3,未安装转码服务,因此不提供 wav/opus/aac。需要其他格式请先在客户端转码。
OpenAI SDK 报 404?
检查 base_url 是否带 /v1,例如 https://tts.blackegg.cn/v1,SDK 会自动拼 /audio/speech。
Gemini 返回的 base64 播不了?
按 inlineData.mimeType(audio/mpeg)解码保存为 .mp3,不要按 PCM 处理。
如何查看调用量与字数?
GET /api/v1/me 返回当前 Key 的调用次数、累计字数、限流与单条上限。