/audiogen — Game Audio Generation via ElevenLabs
Generate background music, character voice lines, and sound effects for games
via the ElevenLabs REST API. One CLI (
), three modalities,
zero npm deps. Usable both as a Claude Code skill and as a standalone shell
CLI (e.g. from CI).
Prerequisites
- Node.js >= 20.14 — required for the built-in .
The CLI asserts this at entry and fails with a clear message on older
Node.
- — get one at
https://elevenlabs.io/app/settings/api-keys. Either export it in your
shell, or add to a file at the project
root. The CLI loads every in cwd and its parents, then in the
script directory and its parents; the nearest file wins for each
variable. Shell-exported values take
precedence over values (Node's default; not an audiogen
choice).
- ElevenLabs plan — any plan works, free or paid. Don't assume
which one the user has: (below) checks. Only free-plan audio
must credit ElevenLabs, and free accounts are limited to
--output-format mp3_44100_64
. See Licensing.
Quick Start
bash
# Background music — 30 seconds of orchestral tension
/audiogen music tense orchestral battle cue --length-ms 30000
# Voice line — must specify a voice
/audiogen voice "Halt, traveller! What brings you here?" --voice-id Rachel
# Sound effect — 2 seconds
/audiogen sfx heavy wooden door slam with reverb --duration 2
# Voice catalog browse
/audiogen voices --gender female --language en
Each of these runs the bundled CLI as
node ${CLAUDE_SKILL_DIR}/generate.cjs <subcommand> ...
. All outputs default
to
assets/audio/{music,voice,sfx}/<slug>.mp3
in the current working
directory.
Handling No Arguments
If the user invokes
with nothing after it, ask what they want
to generate before calling the CLI. Don't guess — the three modalities
are priced and shaped very differently. A good clarification: "Music
(background track), a voice line, or a sound effect? And how long should
it be?"
Arguments — Subcommand Dispatch
The first positional word is always a subcommand:
/audiogen music|voice|sfx|voices|plan <rest...>
When the user's phrasing makes intent obvious, pick the subcommand
yourself:
- "boss battle music", "title screen theme", "tavern loop" →
- "goblin says ...", "narrator line", "NPC dialogue" →
- "door slam", "coin pickup", "spell cast" →
- "find a female British voice", "list premade voices" →
When the phrasing is ambiguous (e.g. "a scream" — voice or sfx?), ask.
is the catalog-browse command, not a generator.
Subcommand Reference
— background tracks
/audiogen music <prompt...> [--length-ms MS] [--seed N]
[--force-instrumental]
[--output-format FMT] [--output PATH]
Generates one music clip via
.
- — 3000–600000. Default (30 s). Max 5 minutes.
- — integer seed for reproducibility.
- — suppress vocals.
- — , , , ,
. Default . WAV formats () are
rejected — the music endpoint does not accept them.
Loop caveat. There is no native "seamless loop" flag for music. For
looping game BGM, loop in the engine / HTML, or build a
(not exposed in this CLI). See
Loop Caveat below.
— TTS (text-to-speech)
/audiogen voice <text...> --voice-id <NAME_OR_ID>
[--language-code CODE]
[--stability N] [--similarity-boost N]
[--style N] [--speed N]
[--model-id ID] [--seed N]
[--output-format FMT] [--output PATH]
Generates one TTS clip via
POST /v1/text-to-speech/{voice_id}
.
- — required. Accepts either an exact voice name from
the local cache (case-insensitive), or a 20-char alphanumeric voice
ID. If the name isn't cached, fall back to
to discover one.
- Input cap: 40,000 characters (enforced client-side).
- — default . Others:
(fast/cheap), ,
(expressive — best for emotional lines).
- , , , — all
optional fields. Ranges 0–1 except (0.5–2).
- — includes in addition to the usual set
(WAV is supported for TTS but not for music or sfx).
— sound effects
/audiogen sfx <prompt...> [--duration N] [--loop]
[--prompt-influence N]
[--output-format FMT] [--output PATH]
Generates one sound effect via
POST /v1/sound-generation
.
- — 0.5 to 30 seconds. Optional — omit to let the API
auto-pick a duration. The 30-second ceiling is a hard API limit; for
longer ambience, generate a loopable clip and repeat in-engine.
- — native API flag (requires the
model, which is the default). Produces a seamlessly loopable
waveform.
- — 0–1. Default . Higher = closer adherence
to the prompt; lower = more creative latitude.
- — , , , , .
WAV rejected, same as music.
— browse the voice catalog
/audiogen voices [query...] [--accent STR] [--gender male|female]
[--language CODE] [--category STR]
[--limit N] [--page-size N]
[--json] [--refresh]
Lists voices from
with client-side filters. Results
are cached at
in the project root with a
24-hour TTL; stale caches are refreshed automatically. Use
to force a re-fetch.
- (optional positional) — substring match on voice name,
description, and labels.
- — substring match on accent labels (e.g. ,
).
- — or .
- — ISO code (, , , …).
- — e.g. , , .
- — cap the number of rows in the table view (default 50).
ignores this.
- — emit raw JSON for scripting; table view otherwise.
The cache file is gitignored. It is not a source of truth — the
ElevenLabs catalog is — but is the canonical resolver for
.
— which ElevenLabs plan this key is on
Reads
GET /v1/user/subscription
and prints one JSON line, for
example
{"plan":"free","creditRequired":true,"creditsLeft":9900,"creditLimit":10000}
.
is
, a paid plan's name (
,
,
, …),
or
when the key isn't allowed to read the account (keys can
be limited to generation) or ElevenLabs can't be reached. It costs no
credits. Run it once before the first generation in a session; see
Licensing for what to do with the answer.
How to Compose Prompts
Music and SFX prompts are free-form natural language. Write like you
are briefing a human foley artist or composer:
- Be specific about instrumentation, tempo, mood. "Sorrowful
string quartet, 60 BPM, dry room tone" beats "sad music."
- Name the genre or era. "NES chiptune", "Sega Genesis FM
synthesis", "1950s noir jazz combo" all land recognizably.
- Describe the scene. "Heavy iron portcullis slamming shut in a
stone corridor, long reverb tail" beats "door sound."
- Stack adjectives for SFX. The model responds well to three or
four descriptors chained ("crunchy, wet, low-frequency, metallic").
For quick starting points, see
${CLAUDE_SKILL_DIR}/reference.md
— it contains ~20
music presets, ~15 voice archetypes, and ~25 SFX presets. Presets are
templates, not literal prompts: expand them with any additional cues
from the user's phrasing.
Choosing a Voice
- If the user names a voice ("use Rachel", "use JBFqn..."), pass
that to directly. 20-char alphanumeric strings are
treated as IDs; anything else is matched against the cache by
name (case-insensitive).
- If the user describes what they want ("gruff old wizard",
"young American female"), run first
— possibly with , , or . Pick a
candidate by name, then call with that name.
- The voice cache auto-refreshes after 24 hours. Use if
the user says "new voices were added" or you hit a "voice not
found" error.
- See
${CLAUDE_SKILL_DIR}/reference.md
for archetype-to-search-query guidance (e.g.
"Arcane Scholar → voices wise old male english
").
Output Organization
Default layout in the current working directory:
assets/audio/
music/ — background tracks
voice/ — TTS lines
sfx/ — sound effects
- Filename is derived from the prompt (lowercased, non-alphanumerics
collapsed to , first 40 chars). Non-Latin prompts fall back to
.
- Auto-versioning on collision. If
assets/audio/music/foo.mp3
exists, the next call becomes , then , up to
. Pass to overwrite in place.
- overrides everything:
- If is an existing directory (or ends with ), the slug is
written inside it.
- Otherwise is the literal output filename (auto-versioning
still applies unless ).
Filenames are a collision-avoidance mechanism, not a version
manifest. If the user wants to track iterations ("go back to v1",
"that was better than v2"), use
against
— see
Regeneration & Iteration.
Confirmation Policy
- Single generation: run without asking. The user asked for one
thing; deliver it.
- Batch of 3+ generations in one turn: before starting, quote the
estimated cost (see Cost) and confirm. Example: "That's 5 music
clips at ~$0.15 each = ~$0.75. OK to proceed?"
- Voice cloning (IVC/PVC) is out of scope — ElevenLabs requires
explicit consent-recording workflows that belong in their UI, not a
CLI. Direct the user to https://elevenlabs.io/voice-lab.
Handling Errors
The CLI prints every failure as
on stderr and
exits 1. Common patterns:
- 401 / 402 — API key invalid, out of credits, or tier
restriction. Check the key and billing page.
- 422 with in the detail — the free plan's
format limit, so the account is on the free plan. The CLI appends the hint "Free-tier accounts are
restricted to . Try
--output-format mp3_44100_64
."
- 422 other — prompt rejected (content policy, unsupported
parameter combo, …). Refine the prompt and retry.
- 429 — concurrency limit hit (Free 2, Creator 5, Pro 10,
Business 15). The CLI retries 3x with backoff; after that, the
user should wait or upgrade.
- — a 200 with zero bytes; the CLI deletes
the empty file and reports. Refine the prompt and retry.
- / duplicate name — the cache has no match, or
two cached voices share a name. The error lists the candidate IDs;
pass one directly via .
Every error block includes the HTTP status and, when available, the
header — include that when filing issues with
ElevenLabs support.
Regeneration & Iteration
Every successful generation appends one JSON line to
in the working directory. Schema:
{ts, id, parent_id?, type, prompt, model_id, output_path,
output_format, request_body, request_id?, audiogenVersion}
- — tag a generation with an explicit id (otherwise
the CLI auto-generates one from the output path).
- — mark this generation as a derivative of a
prior record. Use for "make that goblin voice gruffer", "same track
with more brass", etc.
History-file write failures are logged to stderr but never abort the
generation — you got the audio, the bookkeeping is best-effort.
Loop Caveat
- Music has no native loop flag. Generate the track, then loop in
the game engine or HTML . For a natively seamless
loop, you need to craft a (not exposed in this
CLI — use the raw ElevenLabs API or their web UI).
- SFX has native on the default
model. Produces a clip with matching start/end so it can repeat
seamlessly in-engine.
Cost
The live pricing page at https://elevenlabs.io/pricing/api is
authoritative — the numbers below may lag. Approximate API-tier rates
as of April 2026:
- Music: ~$0.30 per minute of output.
- TTS: Flash / Turbo ~$0.05 per 1,000 characters; Multilingual v2
and v3 ~$0.10 per 1,000 characters.
- SFX: ~$0.12 per generation, flat (1 second and 30 seconds cost
the same).
- Free tier: 10,000 credits/month — roughly 60 minutes of Flash
TTS, or a handful of SFX.
Consult
${CLAUDE_SKILL_DIR}/reference.md
for a detailed cost table and worked examples.
When in doubt, quote from the live page, not from this file.
Licensing
- Paid-plan output — user-owned, with perpetual commercial
rights that survive account cancellation. No credit needed.
- Free-plan output — commercial use permitted, but it must credit
ElevenLabs per their terms.
Go by what
reports, never by guessing:
- — generate with
--output-format mp3_44100_64
(the only
format free accounts get), and tell the user once that the audio
needs a credit, such as "Music and sound effects created with
ElevenLabs." in their credits or README.
- a paid plan — say nothing about credits.
- — generate normally. If the default works,
it's a paid plan: no credit. If it fails with the free-tier
hint, it's the free plan: retry with
--output-format mp3_44100_64
and mention the credit as above. If
nothing gets generated, don't bring up credits.
When audiogen runs for another skill that has its own credit rule,
such as gamegen, follow that skill's rule for where the credit goes.
- Voice cloning (IVC / PVC) — requires explicit, recorded consent
from the voice owner. NEVER clone a public figure's voice.
Cloning flows live in the ElevenLabs UI; this skill does not expose
them.
Key Rules
- NEVER clone a public figure's voice — it is TOS-forbidden and
legally hazardous.
- ALWAYS require explicit, recorded consent before cloning a real
person's voice (IVC or PVC). Direct users to the ElevenLabs UI —
this CLI does not implement cloning.
- NEVER pass formats to or — the API rejects
them. TTS accepts WAV.
- NEVER call without a text prompt — the endpoint will
return 400.
- ALWAYS keep SFX durations in — the 30 s ceiling is a
hard API limit.
- ALWAYS quote estimated cost before a batch of 3+ generations.
- ALWAYS treat filenames (, , …) as collision avoidance,
not a version manifest. Use for genuine iteration
threading.
- NEVER edit by hand — it is append-only.
Edge Cases
- Free-tier 422 with — the CLI appends a hint
suggesting
--output-format mp3_44100_64
. Follow it; it also means
the account is on the free plan (see Licensing).
- Music loops — no native API flag. Use engine-side looping or
craft a out-of-band.
- Duplicate voice names — the cache may contain two "Adam"s (e.g.
a premade and a cloned one). will fail with a
disambiguation error listing both IDs; retry with an ID.
- 20-char voice name — if a cached voice happens to have a 20-char
alphanumeric name, the CLI treats it as an ID (passthrough). A
warning is written to stderr. Rename the voice in ElevenLabs or
pass the real ID.
- 0-byte 200 response — the CLI deletes the empty file and
reports
"empty audio response; refine prompt or retry."
. Treat as
transient; refine and retry.
- Non-Latin prompts — the slug function strips non-
characters; if nothing is left, the filename falls back to
(local time zone).
- Stale voice cache — cache is 24 h; pass if a
newly-added voice is not found.
- precedence — shell-exported wins
over any value (Node's default). Unset shell variable if
you want the value to take effect.
Script Location
The CLI is bundled next to this
, at
${CLAUDE_SKILL_DIR}/generate.cjs
. That path works whether the skill was
installed as a plugin or copied into a skills folder. It is
dual-shape: as a skill backend (invoked via this SKILL.md), and as a
standalone CLI. Run it directly from any shell for scripting, CI, or
manual experimentation:
node ${CLAUDE_SKILL_DIR}/generate.cjs music "chiptune boss" \
--length-ms 45000
All flags work identically in both modes. Run
for the
authoritative flag surface; this file is prose,
is canon.