方言 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 分钟