Fish Audio TTS
FishAudioTTS targets the Fish Audio TTS endpoint (POST https://api.fish.audio/v1/tts), which streams synthesised audio back with chunked transfer encoding.
The default model is s2.1-pro — Fish’s recommended production model: 83 languages, multi-speaker synthesis, and natural-language expression control via [bracket] tags. The default audio output is PCM_S16LE @ 16 kHz so chunks drop straight into the Patter pipeline without transcoding.
Fish selects the model with a request header, not a body field. One API key
therefore serves every model without reconnecting — switching between
s2.1-pro and s2-pro is a constructor argument, nothing more.Install
getpatter[fish_audio] extra adds aiohttp>=3.10 for HTTP streaming plus ormsgpack>=1.5, which is used only by the WebSocket transport (see WebSocket streaming). On TypeScript the HTTP and ASR adapters need nothing beyond the base install; the WebSocket transport uses @msgpack/msgpack, shipped as an optional dependency.
Authentication
Usage
Choosing a voice
voice maps to Fish’s reference_id — the id of a voice model from the Fish voice library or one you cloned yourself. Omit it entirely to use the model’s built-in voice.
Multi-speaker (S2 models)
Pass a sequence of reference ids and mark the speakers inline in the text:Expression control
S2 models steer delivery from natural-language tags written inline in[brackets]. The tags are consumed by the model, not spoken:
Latency
latency trades quality against time-to-first-audio. Patter defaults to balanced, the interactive sweet spot.
Telephony
Fish emits linear PCM only — it has no native G.711 output — so the pipeline always runs the μ-law encode. The carrier factories still save work:WebSocket streaming (s2-pro)
FishAudioWebSocketTTS targets wss://api.fish.audio/v1/tts/live instead of the HTTP endpoint. It skips the per-utterance HTTP request setup (~50 ms) and pairs with s2-pro’s ~100 ms time-to-first-audio.
start → text → flush → stop, with audio frames coming back). That is why the codec dependency exists — the server returns raw audio bytes inline, which JSON cannot carry without base64. The HTTP adapter has no such requirement.
Models
Options
Every option left unset is omitted from the request so Fish applies its own documented default rather than a value the SDK guessed.
Low-level usage
Pricing
Fish bills **0.015 / 1k` and meters UTF-8 byte length, not character count — exact for latin scripts and correctly ~3× higher for CJK, where one character is three bytes. Override per project viaPatter(pricing={...}). See Fish Audio pricing and rate limits for the authoritative numbers and the concurrency tiers.
Beta. This provider is validated against the Fish Audio API specification
but has not yet been exercised on a live phone call end to end.

