Synchronous Text to Speech v2
Synchronous HTTP TTS v2 compatibility contract for existing clients.
HTTP TTS v2 is maintained for existing clients. New integrations should use HTTP TTS v3, which provides a strict field contract, model capabilities, and recoverable asynchronous jobs.
Migration notice: The v2 synchronous endpoint remains available. No retirement date has been set. Existing clients should migrate and verify their requests using the migration guide; new clients should use v3. Changing the URL alone is insufficient because v3 rejects some legacy v2 fields.
Endpoint
POST /api/open/v2/speech/ttsFull URL:
https://fishaudio.org/api/open/v2/speech/ttsAuthentication and request headers
Authorization: Bearer FISHAUDIO_API_KEY
Content-Type: application/json
X-Request-Id: YOUR_STABLE_REQUEST_IDKeep the API key on a trusted server. Success is binary audio; errors are JSON.
Request
{
"text": "Hello from Fish Audio.",
"voiceId": "00a1b221-6137-4b73-ad62-b0cbce134167",
"modelId": "fishaudio-s21pro-flash",
"format": "mp3",
"speed": 1,
"volume": 0,
"stability": 1,
"similarity": 1
}| Field | Type | Required | Notes |
|---|---|---|---|
text | string | Yes | 1–10,000 characters |
voiceId | string | Yes | Public or personal voice ID |
modelId | string | No | Public engine model ID; omission uses voice/account defaults |
format | string | No | mp3, wav, or ogg; default mp3 |
speed | number | No | 0.5–2; default 1 |
volume | number | No | -20–20; default 0 |
pitch | number | No | -12–12 |
stability | number | No | 0.5–1.5 |
similarity | number | No | 0.5–1.5 |
language | string | No | Language hint |
emotion | string | No | Global emotion ID |
instruction | string | No | Qwen style instruction, up to 1,600 characters |
textNormalization | boolean | No | Structured-text pronunciation normalization |
V2 also accepts historical fields such as engineModelId, version, qwenModel, and minimaxEmotion. They exist only for old clients. Do not use them in new code or mix them into v3 requests. V2 has no provider-neutral capability catalog.
curl example
curl "https://fishaudio.org/api/open/v2/speech/tts" \
-H "Authorization: Bearer $FISHAUDIO_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Request-Id: legacy-tts-001" \
-d '{"text":"Hello","voiceId":"00a1b221-6137-4b73-ad62-b0cbce134167","modelId":"fishaudio-s21pro-flash","format":"mp3"}' \
--output speech.mp3Successful response
HTTP/1.1 200 OK
Content-Type: audio/mpeg
X-Request-Id: legacy-tts-001
X-OpenAPI-Quota-Remaining: 99994
X-OpenAPI-Credits-Used: 6
<binary audio data>Errors and retries
Errors use a flat JSON shape:
{
"code": "ERR_REQUEST_ID_CONFLICT",
"message": "Request id was reused with a different request",
"requestId": "legacy-tts-001"
}| Status | Meaning |
|---|---|
400 | Invalid request or voice/model combination |
401 | Invalid API key |
402 | Insufficient API quota |
409 | Request ID active, completed, or reused with different input |
413 | HTTP request body exceeds the limit |
429 | Rate limited; honor Retry-After |
500 | Generation or settlement failure |
Reuse X-Request-Id only for an identical retry. Lost synchronous audio cannot be replayed; workflows that require recovery should migrate to v3 Jobs.
Migrate to v3
Keep text, voiceId, and generic controls; remove historical provider fields. modelId is optional in v3; omitting it uses the default engine for the selected voice. See the migration guide for the complete mapping.