方言 TTS API 文档
Base URL: https://api.xiangyinge.com/api/v1
认证与加密
所有接口需要在请求头中携带 API Key,且请求体和响应体均使用 AES 加密:
X-API-Key: your_api_key
Content-Type: application/json
加密说明
- 加密算法:AES-256-CBC
- 密钥派生:使用 API Key 的 SHA256 哈希作为 AES 密钥
- 请求有效期:5 分钟(基于 timestamp 校验)
请求格式
所有 POST 请求的请求体需要加密后发送:
{
"encryptedData": "Base64编码的加密数据",
"iv": "Base64编码的初始化向量",
"timestamp": 1704067200000
}
encryptedData 解密后为实际的请求参数 JSON。
响应格式
所有响应均为加密格式:
{
"encryptedData": "Base64编码的加密数据",
"iv": "Base64编码的初始化向量",
"timestamp": 1704067200000
}
解密后得到实际的响应数据。
加密示例(JavaScript)
const crypto = require('crypto');
function encrypt(data, apiKey) {
const key = crypto.createHash('sha256').update(apiKey).digest();
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(JSON.stringify(data), 'utf8', 'base64');
encrypted += cipher.final('base64');
return {
encryptedData: encrypted,
iv: iv.toString('base64'),
timestamp: Date.now()
};
}
function decrypt(response, apiKey) {
const key = crypto.createHash('sha256').update(apiKey).digest();
const iv = Buffer.from(response.iv, 'base64');
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(response.encryptedData, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
接口列表
POST /tts
语音合成接口,将文本转换为方言语音。
请求参数(加密前)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| text | string | 是 | 待合成文本,最大 5000 字符 |
| voice_id | string | 是 | 音色 ID |
请求示例
const apiKey = 'your_api_key';
const payload = encrypt({ text: '你好', voice_id: 'dongbei_laotie' }, apiKey);
fetch('https://api.xiangyinge.com/api/v1/tts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': apiKey
},
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(encrypted => {
const data = decrypt(encrypted, apiKey);
console.log(data);
});
成功响应(解密后)
{
"success": true,
"data": {
"audio_url": "https://r2.xiangyinge.com/abc123.mp3",
"billing": {
"raw_chars": 2,
"billable_chars": 50,
"cost_yuan": 0.01,
"balance_after_yuan": 0.99
}
}
}
错误响应(解密后)
{
"success": false,
"error_code": "INSUFFICIENT_BALANCE",
"message": "余额不足,需要 0.01 元,当前余额 0.00 元",
"details": {
"required_cents": 1,
"available_cents": 0
}
}
GET /voices
获取所有可用音色列表。
请求示例
fetch('https://api.xiangyinge.com/api/v1/voices', {
headers: { 'X-API-Key': 'your_api_key' }
})
.then(res => res.json())
.then(encrypted => {
const data = decrypt(encrypted, 'your_api_key');
console.log(data);
});
成功响应(解密后)
{
"success": true,
"data": {
"voices": {
"东北话": [
{ "id": "dongbei_laotie", "name": "东北老铁" },
{ "id": "dongbei_yatou", "name": "东北丫头" }
],
"四川话": [
{ "id": "chongqing_xiaohuo", "name": "重庆小伙" },
{ "id": "sichuan_tianmeier", "name": "四川甜妹儿" }
]
}
}
}
GET /account
查询当前账户信息。
请求示例
fetch('https://api.xiangyinge.com/api/v1/account', {
headers: { 'X-API-Key': 'your_api_key' }
})
.then(res => res.json())
.then(encrypted => {
const data = decrypt(encrypted, 'your_api_key');
console.log(data);
});
成功响应(解密后)
{
"success": true,
"data": {
"name": "test@example.com",
"balance_yuan": 1.0,
"total_recharge_yuan": 1.0,
"total_consumed_yuan": 0.0,
"price_per_wan_yuan": 2.0
}
}
计费规则
- 标准价格:2 元 / 万字符
- 计费步长:按 50 字符向上取整(1-50 按 50 计,51-100 按 100 计)
- 阶梯价格:
- 累计充值 ≥500 元:1.9 元 / 万字符
- 累计充值 ≥2000 元:1.75 元 / 万字符
错误码
| 错误码 | HTTP 状态码 | 说明 |
|---|---|---|
| AUTH_ERROR | 401 | 未提供 X-API-Key 或解密失败 |
| MISSING_API_KEY | 401 | 未提供 X-API-Key 请求头 |
| INVALID_API_KEY | 401 | API Key 无效或已禁用 |
| DECRYPTION_FAILED | 400 | 请求解密失败 |
| MISSING_PARAMETER | 400 | 缺少必填参数 text 或 voice_id |
| TEXT_TOO_LONG | 400 | 文本超过 5000 字符限制 |
| INSUFFICIENT_BALANCE | 402 | 账户余额不足 |
| RATE_LIMIT_EXCEEDED | 429 | 请求频率超过限制(默认 60 次/分钟) |
| TTS_FAILED | 200 | 语音合成失败,详见 message 字段 |
限制
- 单次请求文本最大长度:5000 字符
- 默认请求频率限制:60 次/分钟
- 请求时间戳有效期:5 分钟