Skip to main content
AI Reserve serves the Fish Audio API at 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 in references 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 (429 with Retry-After), and — on every POST — 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/tts body the gateway cannot read as JSON or MessagePack with a string text is refused with 400 before any upstream call; a deployment that cannot reach the ledger refuses billable calls with 503 rather than serving them unmetered.
  • Headers. Your Authorization and x-api-key are replaced by AI Reserve’s Fish key; Accept-Encoding is pinned to identity so Fish’s bytes are the bytes relayed. The model header, content types and your client’s user agent go through. Fish’s X-Generation-Id comes 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 429 from Fish is relayed as Fish sends it (without Retry-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/speech instead.