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.
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; and explicitly send a modelId returned by capabilities. See the migration guide for the complete mapping.