Como usar
- Copie o comando e verifique o pacote antes de instalar no seu ambiente de agente.
- Consulte no original as ferramentas, credenciais e ambientes necessários.
- Descreva os dados de entrada e a entrega esperada; confira a saída com as fontes.
npx skills add https://github.com/fishaudio/docs --skill fish-audio-sdkAntes de começar
- A instalação não inclui assinatura de modelo, franquia API ou acesso aos seus arquivos.
- Estrelas e instalações indicam atividade, não um teste independente de qualidade ou segurança.
Renderizado do repositório de origem, preservando títulos, exemplos, código, tabelas, links e imagens.
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.



