Skip to content

TTS: Fish Audio go-live (operators)

Fish Audio is a direct provider: Pyre talks to api.fish.audio over its own REST adapter, keyed by a single bearer token, not through OpenRouter. Like Amazon Polly, Fish ships dormant. The adapter is registered on every boot but stays configured off until TTS_FISH_KEY is set, so a box with no key behaves exactly as it did before Fish existed.

Fish authenticates with a single bearer token, not the three part AWS SigV4 credential Polly uses. Set one line on the service environment:

Terminal window
TTS_FISH_KEY=fk_live_... # the Fish Audio API key (bearer token)

The mechanism is the Polly wiring pattern, generalized to one key. The Polly runbook uses scripts/wire-polly-prod.sh, which reads the TTS_POLLY_* lines from your local secrets.txt and appends them to the prod box /opt/pyre/.env, then recreates core and admin so they pick up the new env. Fish uses the same shape: a Fish twin of that script (or the generalized wiring script) reads the one TTS_FISH_KEY line and does the identical append and recreate. As with Polly, the operator runs the wiring script: the secret value is read and transmitted by your own shell, never by the agent, and never echoed.

Fish direct is not a monthly plan. It is a prepaid API credit balance that you top up, and usage draws it down. Two facts drive the sizing:

  • Metered by character. The s2.1-pro model bills at roughly 15 USD per one million characters. Fish counts UTF-8 bytes, so an emoji or a CJK character spends more than a Latin letter. Pyre already meters Fish by byte, so the per provider usage in the admin Usage and caps card matches what Fish bills.
  • Concurrency scales with the prepaid balance. How many requests can be in flight at once is a function of how much credit you have prepaid, not a plan tier you subscribe to. As a rough guide, a 100 USD balance allows on the order of 15 concurrent requests, and a 1000 USD balance on the order of 50. Prepay to the concurrency you expect at peak, then keep the balance topped up.

3. Whitelist Fish voices (once they exist)

Section titled “3. Whitelist Fish voices (once they exist)”

There is nothing to whitelist until the owner has designed at least one voice. When designed voices exist, everything below happens in the TTS admin panel. No auto seed keys Fish for you: the operator curates each voice by hand, which is the whole point of the curated catalog.

  1. Open the voice catalog card and run discovery for Fish. The discovery pool lists only the Pyre Fish account own designed voices, each tagged with whether it is already whitelisted.

  2. Whitelist a voice with a public name. It appears in the streamer catalog immediately, provider hidden: nothing viewer facing renders the word “fish”.

  3. Optionally set a backing chain. A plain designed voice needs none: its single Fish backing is derived automatically. Add a fallback backing only if you want a second provider to cover a Fish outage for that voice.

  • It does not add any voice to the catalog on its own. Keying Fish makes the provider ready; voices arrive only when the owner designs them and an operator whitelists them.
  • It does not change any streamer default. A channel keeps whatever voice it chose, and the platform default is untouched until an operator points it somewhere else.
  • It does not enable the community library. Only account designed voices are ever discoverable, provider hidden, and curated by hand.