Mode d’emploi
- Copiez la commande et examinez le paquet avant de l’installer dans votre environnement agent.
- Consultez le document original pour les outils, identifiants et environnements requis.
- Décrivez les entrées et le livrable souhaité ; comparez la sortie aux sources.
npx skills add https://github.com/fishaudio/docs --skill fish-audio-sdkAvant de commencer
- L’installation n’inclut ni abonnement au modèle, ni quota API, ni accès aux fichiers.
- Étoiles et installations reflètent l’activité, pas un test indépendant de qualité ou de sécurité.
Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.
Fish Audio SDK Skill
Use this skill to generate correct, runnable code with the official Fish Audio SDKs:
- Python: package
fish-audio-sdkon PyPI, imported asfishaudio. (The same wheel still ships a separate legacyfish_audio_sdkpackage. Do not mix them; everything here is the modernfishaudiopackage.) - JavaScript / TypeScript: package
fish-audioon npm, imported asFishAudioClient.
If the user wants raw curl / HTTP / WebSocket without installing an SDK, use the `fish-audio-api` skill instead.
This file is the index. Deeper, task-specific rules and full examples live in `references/`. Read the reference for the task you're doing before writing code.
Global facts
- Auth: both SDKs read the API key from the
FISH_API_KEYenvironment variable automatically. Get keys athttps://fish.audio/app/api-keys. Never hardcode a key. - Base URL:
https://api.fish.audio(override withbase_url=in Python /baseUrl:in JS). - TTS models: the API supports
s1(deprecated),s2-pro,s2.1-pro(recommended for production), ands2.1-pro-free(free tier). Do not chooses1for new code: S1 is deprecated and will be retired on December 31, 2026. After that date, requests that specifys1are served bys2.1-pro(migration:https://docs.fish.audio/developer-guide/models-pricing/migrate-from-s1). However, the Python SDK typesmodelas onlys1ands2-pro(plus the deprecatedspeech-1.x), defaults2-pro. The JS package on npm (fish-audio0.1.0) typesbackendwithouts2-proors2.1-proand defaults it to"s1"at runtime (its README says"s2-pro"), so in JS always passbackendexplicitly. Both SDKs forward the model value without runtime validation, so"s2.1-pro"works over the wire. Static type checkers will flag it, so add# type: ignore(Python) / anascast (TS), or use thefish-audio-apiskill for raw calls.speech-1.5/speech-1.6are deprecated. In Python passmodel="s2-pro"(keyword); in JS pass the positionalbackendargument. - ASR models: use
transcribe-1-pro(recommended: speaker turns, long recordings, emotion cues). Neither SDK has an ASRmodelargument: send themodel: transcribe-1-proHTTP header on every request (PythonRequestOptions(additional_headers=...), JSrequestOptions.headers). A request without it is served and billed astranscribe-1, the model for short recordings. See references/speech-to-text.md. - Audio formats:
mp3(default),wav,pcm,opus. - Playback in examples:
play()shells out to a system audio tool: Python uses ffmpeg/ffplay (ormpv), JS uses ffplay. It is for local/desktop use; in a server,save()to a file or stream the bytes instead. See references/installation.md.
Quick start: Python
from fishaudio import FishAudio
from fishaudio.utils import play, save
client = FishAudio() # reads FISH_API_KEY
# Generate speech (returns the full audio as bytes)
audio = client.tts.convert(text="Hello from Fish Audio!")
save(audio, "output.mp3") # write to a file
# play(audio) # or play locally (needs ffmpeg)Async: identical resource tree on AsyncFishAudio, used as a context manager:
import asyncio
from fishaudio import AsyncFishAudio
from fishaudio.utils import save
async def main():
async with AsyncFishAudio() as client:
audio = await client.tts.convert(text="Hello from Fish Audio!")
save(audio, "output.mp3")
asyncio.run(main())Quick start: JavaScript / TypeScript
import { FishAudioClient, play } from "fish-audio";
const client = new FishAudioClient({ apiKey: process.env.FISH_API_KEY });
// convert() returns audio you can play or pipe to a file
const audio = await client.textToSpeech.convert({
text: "Hello from Fish Audio!",
}); // npm 0.1.0 defaults to the deprecated "s1"; pass a model as shown below
await play(audio); // local playback (needs ffplay)To pick a model in JS, pass backend as the positional argument (not a named option):
import type { Backends } from "fish-audio";
// The cast is needed because the npm 0.1.0 `Backends` type omits "s2.1-pro".
const audio = await client.textToSpeech.convert(
{ text: "Hi" },
"s2.1-pro" as Backends
);Capabilities → references
| Task | Reference |
|---|---|
| Install, auth, playback deps, verify a key | references/installation.md |
| Text-to-Speech (convert, stream, formats, prosody, model select) | references/text-to-speech.md |
| Voice cloning (instant references + persistent voice models) | references/voice-cloning.md |
| Speech-to-Text (models, timestamps, fields the SDK drops) | references/speech-to-text.md |
| Realtime WebSocket TTS (stream text → audio) | references/websocket.md |
| Errors, retries, and timeouts (the real exception types) | references/errors.md |
Python ↔ JavaScript name map
The two SDKs do not use the same names. Use this map when porting code between them.
| Concept | Python (fishaudio) | JavaScript (fish-audio) |
|---|---|---|
| Client | FishAudio() / AsyncFishAudio() | new FishAudioClient({ apiKey }) |
| Text-to-Speech | client.tts.convert(text=...) → bytes | client.textToSpeech.convert({ text }) |
| TTS HTTP stream | client.tts.stream(...) → AudioStream | (use convert; realtime streaming is convertRealtime) |
| Realtime WebSocket | client.tts.stream_websocket(text_stream) | client.textToSpeech.convertRealtime(request, textStream) |
| Speech-to-Text | client.asr.transcribe(audio=...) | client.speechToText.convert({ audio }) |
| List voice models | client.voices.list() | client.voices.search() |
| Get voice model | client.voices.get(id) | client.voices.get(id) |
| Create voice (clone) | client.voices.create(title=..., voices=[bytes]) | client.voices.ivc.create({ title, voices: [File] }) |
| Update / delete voice | client.voices.update(id, ...) / delete(id) | client.voices.update(id, ...) / delete(id) |
| Credit balance | client.account.get_credits() | client.user.get_api_credit() |
| Subscription package | client.account.get_package() | client.user.get_package() |
| Choose model | model="s2-pro" keyword arg | positional backend arg, e.g. convert(req, "s2-pro") |
| ASR model (header) | RequestOptions(additional_headers=...) | convert(req, { headers: { model: "transcribe-1-pro" } }) |
Decision shortcuts
- Audio from text →
tts.convert(Python) /textToSpeech.convert(JS). - Reuse a saved voice → pass
reference_id(the voice modelid). - Clone a voice instantly from a clip → pass
references=[ReferenceAudio(audio=..., text=...)](Python) /references: [{ audio, text }](JS). See voice-cloning. - Persistent custom voice to reuse → create a voice model, then use its
idasreference_id. - Stream tokens from an LLM and play speech as it arrives →
tts.stream_websocket(Python) /textToSpeech.convertRealtime(JS). See websocket. - Transcribe audio →
asr.transcribe(Python) /speechToText.convert(JS) with themodel: transcribe-1-proheader (recommended; without it, the request runs ontranscribe-1). Pro request fields,speaker_turns,request_id, and the language fields need raw HTTP in Python (fish-audio-sdk1.3.0). See speech-to-text.
Gotchas (verified against the SDK source)
- Python
latencyaccepts only `"normal"` or `"balanced"` (default"balanced"); there is no"low". - The Python client has no `max_retries` and does not auto-retry; the JS client does auto-retry (configurable via per-call
requestOptions.maxRetries). See errors. - Python defines a
ValidationErrorclass but never raises it, so don't catch it expecting validation failures; a 422 surfaces asAPIError. The JS SDK throwsUnprocessableEntityErroron 422. - ASR segment
start/endanddurationare all in seconds. The Python SDK'sASRResponsedocstring says milliseconds; that is wrong. See speech-to-text.



