Fish Audio
Text-to-speech, transcription, and voice design behind four fixed routes
Fronts four stateless actions on Fish Audio’s platform (https://api.fish.audio); the secret Authorization: Bearer key comes from the gateway — Fish Audio’s only credential channel. Fish Audio is a full voice-cloning platform with a persistent-model and account-balance surface too, but only the four routes below are mounted; every other Fish Audio path draws the gateway’s own 404:
Persistent voice models and account balance are not exposed. /model (create/list/get/update/delete a named, persistent voice-clone model) and /wallet/{user_id}/package, /wallet/{user_id}/api-credit (the shared account’s subscription and credit balance) are never mounted — the gateway injects one shared Fish Audio key, so a persistent model or balance reachable by one client would be reachable by every client. Per-request zero-shot cloning stays available: the references field on POST /v1/tts (and its streaming variant) sends reference audio inline with the call, which Fish Audio uses for that one request only and never turns into a shared resource.
Credential handling
Authorization: Beareris overwritten with the injected Fish Audio key — your gateway token and anything you send are both replaced. This is the only credential channel Fish Audio documents; there’s no query-param spelling to strip.- The
modelheader — how/v1/tts, its streaming variant, and/v1/voice-designpick a model — is an ordinary content header, untouched./v1/asrtakes nomodelheader; Fish Audio’s ASR is a single model.
Text to speech
POST /fishaudio/v1/tts — model header required (s1, s2-pro, or s2.1-pro). Body: text is the only required field; reference_id picks a voice from Fish Audio’s library or your own models, references (application/msgpack bodies only) supplies inline audio+transcript pairs for zero-shot cloning, and format (mp3 default, wav, pcm, opus), sample_rate, prosody, and latency control the output.
The response is chunked binary audio (Transfer-Encoding: chunked) in the requested format, relayed byte-for-byte.
POST /fishaudio/v1/tts/stream/with-timestamp takes the identical request shape and model header, but answers as Server-Sent Events: each event is one JSON payload carrying audio_base64 (concatenate every chunk, in arrival order, to reconstruct the audio), content, a cumulative alignment snapshot ({audio_duration, segments: [{text, start, end}]}) keyed by chunk_seq — replace the stored snapshot for that chunk_seq on each new event, don’t append — and chunk_audio_offset_sec.
Speech to text
POST /fishaudio/v1/asr — no model header. Body: audio (required; base64 in a JSON body, or raw bytes in application/msgpack), an optional language hint, and ignore_timestamps (default true; set false for per-segment timing on audio under 30 seconds, at higher latency).
Response: JSON {"text", "duration", "segments": [{"text", "start", "end"}, ...]}, relayed untouched.
Voice design
POST /fishaudio/v1/voice-design — model header pinned to voice-design-1, its only value. Body: instruction (required, 1–2000 characters describing the voice), plus optional reference_text, language, n (1–4 candidates, default 2), speed, num_step, guidance_scale, instruct_guidance_scale, and seed.
Response: JSON {"candidates": [{"id", "index", "audio_base64", "sample_rate", "duration_ms", "text", "instruct", "language"}, ...]}. Candidates are one-off generations, not persisted voices — turning one into a reusable model goes through /model, which isn’t mounted here.
Billing
Metered on Fish Audio’s own documented prices, read from the request or response rather than a flat guess:
text has no documented length ceiling, so TTS bills the exact byte count instead of a flat rate that could silently under-bill a long request. A references-bearing application/msgpack body, or a malformed/non-string text, is billed on the whole request body’s byte length instead — never smaller than the text bytes it contains.
WebSocket streaming
Fish Audio’s WebSocket streaming endpoint is not proxied — the gateway’s bearer gate, logging, and billing are HTTP-only, and unlike ElevenLabs, Fish Audio has no short-lived-credential broker to mint a socket-scoped secret through. For low-latency audio over HTTP, use /v1/tts/stream/with-timestamp’s chunked SSE response.
Field-level request and response detail lives in Fish Audio’s API reference; the gateway modifies neither.