API Documentation
Wxtts API is OpenAI-compatible for zero-cost migration.
Base URL
https://api.wxtts.com/v1All API paths start with /v1, OpenAI-compatible.
Authentication
Send API Key in request header:
Authorization: Bearer sk-wxtts-xxxCreate a key in Dashboard → API Keys. Key prefix: sk-wxtts-
POST /audio/speech
Text to speech, OpenAI-compatible.
curl -X POST https://api.wxtts.com/v1/audio/speech \
-H "Authorization: Bearer sk-wxtts-xxx" \
-H "Content-Type: application/json" \
-d '{
"model": "tts-1",
"input": "你好,欢迎使用王小听。",
"voice": "xiaoxiao",
"response_format": "mp3",
"speed": 1.0,
"pitch": 1.0
}' --output speech.mp3| Parameter | Type | Required | Description |
|---|---|---|---|
| input | string | Required | Text to synthesize, max 5000 chars per request |
| voice | string | Required | Voice ID, see GET /v1/voices for full list |
| model | string | - | Model ID, tts-1 or tts-1-hd, default tts-1 |
| response_format | string | - | Audio format mp3 / wav / pcm, default mp3 |
| speed | number | - | Speed 0.5-2.0, default 1.0 |
| pitch | number | - | Pitch 0.5-2.0, default 1.0 |
Response Format
Returns JSON by default, audio encoded as base64:
{
"code": 0,
"data": {
"audioBase64": "UklGRiQAAABXQVZF...",
"format": "mp3",
"charCount": 12,
"voice": "xiaoxiao",
"model": "tts-1",
"timestamps": [
{ "beginTime": 0, "endTime": 1500, "text": "你好,欢迎使用王小听。" }
]
}
}Set Accept: audio/mpeg to receive raw binary audio stream. Response headers include X-Char-Count, X-Voice, X-Model.
| Field | Type | Description |
|---|---|---|
| audioBase64 | string | Base64-encoded audio data |
| format | string | Audio format |
| charCount | integer | Character count of this synthesis |
| voice | string | Voice ID |
| model | string | Model ID |
| timestamps | array | Sentence-level timestamps (for subtitle generation, may be empty) |
Other Endpoints
GET /v1/voices— List voicesGET /v1/models— List available modelsGET /v1/usage— Query current usage
SSML Support
Use SSML tags in the input field to control pauses, rate/pitch, emphasis, etc. The backend parses tags and stitches segments; plain text without tags is processed as-is.
| Tag | Description |
|---|---|
| <break time="500ms"/> | Insert silence of given duration (ms / s units). Only effective for wav/pcm formats. |
| <prosody rate="0.8">...</prosody> | Adjust rate/pitch. Supports absolute values (0.5-2.0), percentages (+10%), keywords (slow/fast/normal). |
| <emphasis>...</emphasis> | Emphasize a segment. Auto slightly raises pitch and slows down. |
| <speak>...</speak> | Outer wrapper tag (optional), auto-stripped. |
<speak>
你好,欢迎使用王小听。
<break time="500ms"/>
<prosody rate="0.8" pitch="1.1">这里是慢速高音调片段。</prosody>
<emphasis>重点强调内容</emphasis>
</speak>Multi-speaker Dialog
Wrap multiple <speaker voice="voiceId">text</speaker> segments in <dialog> to produce multi-character voiceover. Each speaker uses its own voice, with 300ms auto-pause between turns.
<dialog>
<speaker voice="longanhuan">你好,今天天气真好。</speaker>
<speaker voice="longanyang">是啊,我们去公园散步吧。</speaker>
<speaker voice="longanhuan">好主意,走吧!</speaker>
</dialog>Streaming TTS
POST /v1/audio/speech/stream splits text by sentence and pushes PCM byte stream (16-bit mono) immediately as each segment completes, achieving low first-byte latency. Content-Type: audio/pcm. Use fetch + ReadableStream on frontend, decode with AudioContext. Stream endpoint outputs PCM only, no mp3/wav.
// 浏览器 fetch + ReadableStream 流式播放
const resp = await fetch("https://api.wxtts.com/v1/audio/speech/stream", {
method: "POST",
headers: {
"Authorization": "Bearer sk-wxtts-xxx",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "tts-1",
input: "长文本将按句切分,每段合成完成立即推送 PCM 流,实现首字低延迟。",
voice: "longanhuan"
})
});
const reader = resp.body.getReader();
const audioCtx = new AudioContext({ sampleRate: 22050 });
while (true) {
const { done, value } = await reader.read();
if (done) break;
// value 为 16-bit PCM 字节,用 AudioBufferSourceNode 播放
const audioBuffer = pcmToAudioBuffer(value, 22050);
const src = audioCtx.createBufferSource();
src.buffer = audioBuffer;
src.connect(audioCtx.destination);
src.start();
}Error Codes
| Status | Description |
|---|---|
| 400 | Bad request (e.g. empty text, invalid voice, unsupported format) |
| 401 | Unauthorized or invalid API Key |
| 429 | Too many requests, please retry later |
| 500 | Internal server error |
Rate Limits
| Plan | Concurrency | RPM | Monthly Chars |
|---|---|---|---|
| Free / Creator | Not supported | Not supported | Not supported |
| Pro | 5 | 60 | 100k |
Returns 429 when exceeded.