On this page

On this page

Providers

Fish Audio

OpenClaw supports Fish Audio in two distinct ways:

  • Hosted S2.1 and Drama 3 run through the fish-audio speech provider on the Gateway and work across channels, voice notes, Talk, and telephony.
  • Local S2 Pro runs inside the native macOS app through the existing mlx Talk provider. It stays on the Mac and does not require a Fish API key.

Hosted S2.1

Install the fish-audio-speech plugin:

bash
openclaw plugins install @openclaw/fish-audio-speech

The plugin id is fish-audio-speech. The provider and TTS configuration id remain fish-audio.

Set an API key from the Fish Audio API Keys page:

bash
export FISH_API_KEY="..."

Then configure the provider:

json5
{  tts: {    auto: "tagged",    provider: "fish-audio",    providers: {      "fish-audio": {        apiKey: "${FISH_API_KEY}",        model: "s2.1-pro",        // Optional saved or public Fish Audio voice model id:        speakerVoiceId: "802e3bc2b27e49c2995d23ef70e6ac89",        latency: "balanced",      },    },  },}

speakerVoiceId is optional. Without it, Fish Audio uses its default voice. FISH_AUDIO_API_KEY is also accepted for compatibility with existing community plugins, but FISH_API_KEY is the standard Fish SDK environment variable.

Hosted models

Model Use
drama-3 Released Drama 3. Natural-language voice direction and word-level delivery tags.
drama-3-preview Preview. Natural-language voice direction and word-level delivery tags; behavior and availability may change.
s2.1-pro Default. Production S2.1 service with the hosted service guarantees attached to your plan.
s2.1-pro-free Promotional S2.1 access that ended on August 31, 2026; no TTFA or DPA guarantees.
s2-pro Previous S2 generation.
s1 Previous generation with parenthesized emotion controls.

The provider requests MP3 for ordinary audio, Opus at 48 kHz for native voice notes, and raw PCM at 8 kHz for telephony. For Discord voice, OpenClaw consumes Fish Audio's chunked HTTP response as it arrives instead of waiting for the entire clip.

Expressive speech

S2 and S2.1 accept inline natural-language tags. Put them in the spoken text:

text
[whisper] Keep this between us. [pause] [excited] We shipped it!

Common tags include [whisper], [laughing], [excited], [sad], [pause], and free-form instructions such as [professional broadcast tone].

Drama 3

Set tts.providers.fish-audio.model to "drama-3" to opt in. The provider continues to default to s2.1-pro; existing configurations do not automatically switch. "drama-3-preview" remains accepted. For a Talk-specific override, use talk.providers.fish-audio.modelId: "drama-3".

Drama 3 uses the same hosted API, API key, and voice ids. It accepts plain-language directions in square brackets, sounds and pauses, and paired tags that affect only the enclosed words:

text
[calm, reassuring] We have time. [short pause] <whisper>One step at a time.</whisper>

Supported delivery tags include <whisper>, <emphasis>, <soft>, <fast>, <slow>, <stress>, and <forceful>. Directions belong in the spoken text, not a separate model or voice setting.

See Fish Audio Drama 3 for direction examples and limitations. OpenClaw currently selects one Fish voice per synthesis request; Fish's multi-speaker reference_id arrays are not exposed by this provider.

Voice selection and cloning

Use /tts status to inspect the active provider and /tts audio <text> for a one-off clip. Fish voice ids can come from your own trained voices or the public Fish voice library. OpenClaw lists your voices first, then a bounded page of popular public voices.

The speech provider consumes existing voice ids; it does not upload recordings or create voice models. Voice creation is a separate consent-sensitive action in the Fish Audio app or API.

Local S2 Pro on macOS

The native macOS app bundles an isolated MLX TTS helper. On Apple silicon, point the existing mlx Talk provider at the 8-bit Fish conversion:

json5
{  talk: {    provider: "mlx",    providers: {      mlx: {        modelId: "mlx-community/fish-audio-s2-pro-8bit",      },    },  },}

The first utterance downloads about 6.8 GB of model and codec data. OpenClaw keeps one selected MLX model resident for repeated utterances, then unloads it after five idle minutes, app shutdown, or memory pressure.

Local reference voice

When the Gateway and macOS app share the same filesystem, configure a clean 10–30 second reference recording and its exact transcript:

json5
{  talk: {    provider: "mlx",    providers: {      mlx: {        modelId: "mlx-community/fish-audio-s2-pro-8bit",        referenceAudioPath: "/Users/example/Voices/reference.wav",        referenceText: "The exact words spoken in the reference recording.",      },    },  },}

referenceAudioPath is resolved on the Mac running the native app, not on a remote Gateway. The file stays local: the app passes it only to its isolated MLX helper. Local Fish output is streamed as PCM into Talk playback so speech can start before a long generation finishes.

Troubleshooting

  • Fish Audio API key missing: set FISH_API_KEY or tts.providers.fish-audio.apiKey.
  • HTTP 401: verify the API key at Fish Audio.
  • HTTP 402: the selected hosted model requires available credits or plan access.
  • Local model falls back to the system voice: confirm Apple silicon, free disk space, and the exact Hugging Face model id.
  • Local clone does not match: use clean single-speaker audio and make referenceText match it exactly.

See the Fish Audio TTS API and Fish Audio Research License.

Was this useful?