elevenlabs-sfx

Generated source view for the actual executable misc/elevenlabs-sfx skill. The durable routing article is Media Generation Skills. Source: skills/misc/elevenlabs-sfx/SKILL.md

Runtime Source

Field Value
Category misc
Origin personal
Slug elevenlabs-sfx
Source slug elevenlabs-sfx
Family Media Generation Skills
Source skills/misc/elevenlabs-sfx/SKILL.md

Bundled Resources

No bundled resource files.

Description

Use when the user wants to generate sound effects, audio clips, or ambient sounds, or when they say /elevenlabs-sfx or /sfx. Creates MP3 files using the ElevenLabs Text-to-Sound-Effects API. Supports multiple variations, iterative refinement, and playback. Triggers even if the user doesn't mention "ElevenLabs" — any request for sound effect generation, audio creation, or SFX should activate this skill.

Skill Source

---
name: elevenlabs-sfx
description: >-
  Use when the user wants to generate sound effects, audio clips, or ambient
  sounds, or when they say /elevenlabs-sfx or /sfx. Creates MP3 files using the
  ElevenLabs Text-to-Sound-Effects API. Supports multiple variations, iterative
  refinement, and playback. Triggers even if the user doesn't mention
  "ElevenLabs" — any request for sound effect generation, audio creation, or
  SFX should activate this skill.
origin: personal
source_slug: elevenlabs-sfx
---

# ElevenLabs SFX — Generate Sound Effects

Generate sound effects using the [ElevenLabs Text-to-Sound-Effects API](https://elevenlabs.io/docs/api-reference/text-to-sound-effects/convert).
For **in-browser playback** after you have assets, see `wiki/tools/web-kits-audio.md`.

Adapted from doxdox `/sfx` skill (2026-03-28). Executable source: `skills/misc/elevenlabs-sfx/SKILL.md`.

## Configuration

Resolve configuration in this order (first found wins):

### 1. Environment variables (highest priority)

```bash
export ELEVENLABS_API_KEY="xi-..."
```

### 2. Config file (fallback)

`~/.config/elevenlabs-sfx/config.yml`:

```yaml
api_key: "xi-..."
default_duration: null    # auto duration (0.5-30s, or null for auto)
prompt_influence: 0.3     # 0.0-1.0, how closely to follow the prompt
```

### 3. Defaults (lowest priority)

- Duration: auto (API decides)
- Prompt influence: 0.3
- Variations: 1

## Gotchas

- **Billing**: Each generation costs ElevenLabs credits. Multiple variations = multiple charges. Always confirm the number of variations before generating.
- **API key scope**: `ELEVENLABS_API_KEY` is visible to the whole agent session. Users should create a dedicated key with usage limits on the ElevenLabs dashboard.
- **Duration limits**: Min 0.5s, max 30s. The API silently clamps values outside this range.
- **Rate limits**: ElevenLabs enforces per-key rate limits. HTTP 429 → wait 5 seconds and retry once.
- **Output format**: The API returns raw MP3 bytes. If the response is JSON instead of binary, it's an error.
- **File sizes**: Typical outputs are 50–500KB. Long durations (30s) can reach ~1MB.
- **Playback**: `afplay` on macOS, `aplay` on Linux. If neither is available, skip playback and tell the user to open the file manually.
- **Looping sounds**: Add `"loop": true` to the request body for audio that transitions smoothly when looped.

## Step 1: Load configuration

Resolve the API key. Check env var first, then config file:

```bash
if [ -n "$ELEVENLABS_API_KEY" ]; then
  API_KEY="$ELEVENLABS_API_KEY"
elif [ -f ~/.config/elevenlabs-sfx/config.yml ]; then
  API_KEY=$(grep '^api_key:' ~/.config/elevenlabs-sfx/config.yml | sed 's/api_key: *["'\'']\{0,1\}\([^"'\'']*\)["'\'']\{0,1\}/\1/')
else
  echo "No API key found." >&2
  exit 1
fi
```

If no API key is found, tell the user their options:

- Set `ELEVENLABS_API_KEY` env var
- Create `~/.config/elevenlabs-sfx/config.yml` with their key
- Get a key at https://elevenlabs.io/app/settings/api-keys

Also load optional settings from the config file if present (`default_duration`, `prompt_influence`).

## Step 2: Craft the prompt

The API works best with descriptive, specific prompts. Help the user refine their idea:

- If the input is vague (e.g. "a sound for my game"), ask what kind of sound, mood, and context.
- If the input is reasonable but could be better, suggest an enhanced version:
  - "laser beam" → "short punchy sci-fi laser beam with a sharp attack and quick decay"
  - "rain" → "soft steady rain on a rooftop with occasional distant thunder"
  - "explosion" → "deep cinematic explosion with debris and rumble tail"
- Share the prompt you plan to send and get confirmation before calling the API.
- Discuss:
  - **Duration**: 0.5–30s, or auto (API decides from prompt)
  - **Loop**: should the sound loop without an audible seam?
  - **Variations**: how many to generate (default 1, up to 5). Each variation uses the same prompt but produces different results.
  - **Output path**: default `outputs/sfx/` in the project root (create if missing). Use `.claude/elevenlabs-sfx/` only when the user is in a Claude Code session and prefers that layout.

If the user's input is already very specific, confirm and proceed.

## Step 3: Generate

1. Derive a base filename from the description: lowercase words joined by underscores (e.g. `laser_beam`). Core concept only, not the full prompt.

2. Create the output directory:

```bash
mkdir -p outputs/sfx
```

3. Name files: single generation → `{base}.mp3`. Multiple variations → `{base}_v1.mp3`, `{base}_v2.mp3`, etc. If files already exist, continue numbering from the highest existing number.

4. For **each variation**, call the API. Run calls in parallel for multiple variations:

```bash
curl -s -w "\n%{http_code}" -X POST https://api.elevenlabs.io/v1/sound-generation \
  -H "xi-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "PROMPT_HERE", "duration_seconds": DURATION_OR_OMIT, "prompt_influence": 0.3}' \
  --output outputs/sfx/FILENAME.mp3 &
```

Add `"loop": true` to the JSON body if the user requested a looping sound. **Omit** `duration_seconds` entirely for auto duration — do not send `null`.

Use `wait` to collect all background jobs.

5. **Validate outputs** with `file`:

```bash
file outputs/sfx/FILENAME.mp3
```

Expected: "Audio file" or "MPEG". If a file contains JSON/text instead of audio, read it for the error:

- HTTP 401: invalid API key
- HTTP 429: rate limited — wait 5s, retry once
- HTTP 422: invalid parameters (duration range, prompt length)
- Other: show the raw error to the user

## Step 4: Playback

```bash
if command -v afplay &> /dev/null; then
  PLAYER="afplay"
elif command -v aplay &> /dev/null; then
  PLAYER="aplay"
else
  PLAYER=""
fi
```

If a player is available, play each file with a brief announcement ("Playing v1...", "Playing v2..."). If not, tell the user the files are at `outputs/sfx/` and they can open them manually.

## Step 5: Pick and iterate

Report all filenames, file sizes, and the prompt used. Then ask the user to:

- **Pick** — choose which variation(s) to keep (e.g. "keep v2"). Delete the rest.
- **Regenerate** — same prompt, new batch of variations
- **Tweak** — adjust the prompt or duration and re-generate
- **Keep all** — keep everything as-is

Repeat steps 2–5 as many times as the user wants.

## After generation (optional)

If the SFX is for a web app, mention that generated MP3s can be wired into `@web-kits/audio` patches or served as static assets with `prefers-reduced-motion` gating per `wiki/tools/web-kits-audio.md`.

## Related skills

- **`wiki/tools/web-kits-audio.md`** — declarative in-browser playback; use after you have MP3 assets
- **`frontend-design`** — UI surfaces that trigger micro-interaction sounds
- **`taste-soft`** / **`design-engineering-polish`** — polish and micro-interaction timing

Timeline

1 page links here