https://api.aireserve.com/fish-audio.
A Fish Audio client whose base URL is repointed here — the fish-audio-sdk
Python package, the fish-audio JavaScript package, curl — keeps working after
two settings change: the base URL and the key. The gateway authenticates
your AI Reserve key, swaps it for AI Reserve’s Fish Audio key, forwards the
request exactly as you sent it (JSON or MessagePack, multipart uploads, the
model header), relays Fish’s answer exactly as Fish gave it, and books each
successful request to your wallet at Fish’s list price.
Any AI Reserve API key works here; there is no separate credential and no
organization setting to turn on.
This is a passthrough, not a translation. Request bodies, the
model header, voice ids (reference_id),
inline references for zero-shot cloning, output formats, response shapes and Fish’s own errors are all Fish’s.
The OpenAI-shaped alternative — POST /v1/audio/speech with grok-tts or the eleven-* models — is documented
under Text to speech.What is served
The model is selected the way Fish selects it: the
model HTTP header.
Without it, or with an id Fish does not recognise, synthesis is served and
billed as s2.1-pro; transcription is served and billed as transcribe-1
unless the header reads exactly transcribe-1-pro. The header is forwarded
as you sent it.
Each successful call appears as its own line in Observe › Event Log and
Financials (model fish-audio:s2.1-pro, fish-audio:transcribe-1-pro,
fish-audio:voice-design-1, …, with Fish’s X-Generation-Id, the metered
bytes or seconds and the rate in its details). Fish does not bill requests
that fail, and neither does AI Reserve: a 4xx or 5xx from Fish is relayed
and books nothing.
What to change
Voice cloning
Fish offers two ways to clone a voice. Instant cloning — reference audio and its transcript sent inline inreferences on /v1/tts — works unchanged
through AI Reserve and needs nothing stored. Stored voice models
(POST /model, which returns a reusable _id) are not available yet: every
AI Reserve organization reaches Fish through one shared account, and a model
stored there would be visible to every other organization’s GET /model?self=true.
Until stored clones are tenant-scoped, POST, PATCH and DELETE /model
answer 403 with
Stored voice models cannot be created, changed or deleted through AI Reserve yet. Clone per request by sending reference audio in \references` on /v1/tts, or pick a library voice from GET /model.`
What AI Reserve enforces
Every refusal is a JSON{ "status": <code>, "message": "…" } body, the
smallest shape Fish’s clients read, and names its cause in message.
- Your organization’s policies. The key is checked exactly as on every AI
Reserve endpoint: paused keys (
401), invalid keys (401,Invalid API key.), per-key IP allowlists and organization network policies (403), rate limits (429withRetry-After), and — on everyPOST— your organization’s spend caps and wallet (402). A Fish request is a wallet request: an exhausted budget refuses it before Fish is called. - Metering is a precondition, not an afterthought. A
/v1/ttsbody the gateway cannot read as JSON or MessagePack with a stringtextis refused with400before any upstream call; a deployment that cannot reach the ledger refuses billable calls with503rather than serving them unmetered. - Headers. Your
Authorizationandx-api-keyare replaced by AI Reserve’s Fish key;Accept-Encodingis pinned toidentityso Fish’s bytes are the bytes relayed. Themodelheader, content types and your client’s user agent go through. Fish’sX-Generation-Idcomes back on every synthesis and transcription. - A request log. Each call is recorded with method, path, Fish’s generation id, upstream status, byte counts, time-to-headers, duration, outcome, your key id, and the metered amount. Refusals are recorded with their outcome before any upstream request. Neither includes bodies, audio, or credentials.
- Transport. Fish unreachable →
503; no response headers within the time-to-headers bound (sized for multi-minute transcriptions) →504; a stream that has started is never cut by that bound.
Limits
- Rate limits are Fish’s concurrency tiers, shared. Fish limits
concurrent requests per account, not per key; AI Reserve’s account tier is
shared across every organization using this endpoint, and a
429from Fish is relayed as Fish sends it (withoutRetry-After). Back off exponentially, as Fish’s own docs advise. - One Fish account, Fish’s data handling. Text, audio uploads and reference audio reach Fish Audio under AI Reserve’s account and Fish’s terms. See the provider data-handling page.
- No stored voices, no WebSockets, no agents, no wallet (above).
- The native API only. Fish’s OpenAI- and ElevenLabs-compatible
endpoints (
/compat/*,/elevenlabs/*) are not mounted; use the OpenAI shape on AI Reserve’s own/v1/audio/speechinstead.