> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/docs/media/elevenlabs-soundfx.md).

# ElevenLabs Sound Effects API Reference

**NOTE:** Our ElevenLabs API Key is stored in environment variables in project root `.env.local`

Local lookup for generating draft sound effects for FactionOS: The War Effort. This is a working API reference and production checklist, not a runtime media promotion record. Generated files remain drafts until source, rights, provenance, metadata, loudness, accessibility, fallback, byte budget, browser evidence, and media gates are complete.

Official source: <https://elevenlabs.io/docs/api-reference/text-to-sound-effects/convert>

Machine-readable official source used for this page: <https://elevenlabs.io/docs/api-reference/text-to-sound-effects/convert/llms.txt>

## Quick Facts

| Item                        | Value                                           |
| --------------------------- | ----------------------------------------------- |
| Product                     | ElevenLabs Sound Effects API                    |
| Operation                   | Create sound effect                             |
| Method                      | `POST`                                          |
| Default base URL            | `https://api.elevenlabs.io`                     |
| Path                        | `/v1/sound-generation`                          |
| Full URL                    | `https://api.elevenlabs.io/v1/sound-generation` |
| Auth                        | `xi-api-key: $ELEVENLABS_API_KEY`               |
| Request content type        | `application/json`                              |
| Response content type       | `application/octet-stream`                      |
| Success response            | Binary audio bytes                              |
| Billing header              | `character-cost`                                |
| Documented validation error | `422` JSON body with `detail[]` entries         |

Other documented production base URLs:

```
https://api.us.elevenlabs.io
https://api.eu.residency.elevenlabs.io
https://api.in.residency.elevenlabs.io
https://api.sg.residency.elevenlabs.io
```

Use the default base URL unless a data-residency requirement says otherwise.

## Request Shape

`text` is the only required body field.

| Location | Field              | Required | Type           | Default                   | Notes                                                                                                                |
| -------- | ------------------ | -------: | -------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Body     | `text`             |      Yes | string         | none                      | Prompt describing the sound effect to generate.                                                                      |
| Body     | `loop`             |       No | boolean        | `false`                   | Requests a seamless loop. Official docs say this is only available for `eleven_text_to_sound_v2`.                    |
| Body     | `duration_seconds` |       No | number or null | `null`                    | Duration in seconds. Must be at least `0.5` and at most `30`. `null` lets ElevenLabs infer duration from the prompt. |
| Body     | `prompt_influence` |       No | number or null | `0.3`                     | Range `0` to `1`. Higher values follow the prompt more closely and reduce variation.                                 |
| Body     | `model_id`         |       No | string         | `eleven_text_to_sound_v2` | Sound generation model ID.                                                                                           |
| Query    | `output_format`    |       No | enum           | provider default          | Format is `codec_sample_rate_bitrate` where bitrate exists, for example `mp3_44100_128`.                             |
| Header   | `xi-api-key`       |  Usually | string         | none                      | The API reference marks it optional in the schema, but private generation should send it.                            |

Recommended FactionOS defaults for browser SFX drafts:

```json
{
  "model_id": "eleven_text_to_sound_v2",
  "loop": false,
  "prompt_influence": 0.45
}
```

Use `duration_seconds` for short cues so candidates stay comparable. Let the model infer duration only for exploratory ambience or loops.

## Output Formats

Official enum values:

```
mp3_22050_32
mp3_24000_48
mp3_44100_32
mp3_44100_64
mp3_44100_96
mp3_44100_128
mp3_44100_192
pcm_8000
pcm_16000
pcm_22050
pcm_24000
pcm_32000
pcm_44100
pcm_48000
ulaw_8000
alaw_8000
opus_48000_32
opus_48000_64
opus_48000_96
opus_48000_128
opus_48000_192
```

Official tier notes:

* `mp3_44100_192` requires Creator tier or above.
* `pcm_44100` requires Pro tier or above.
* `ulaw_8000` is commonly used for Twilio-style telephony inputs.

FactionOS runtime currently serves MP3 SFX from `apps/web/public/sfx/`. Prefer `mp3_44100_128` for app-ready browser candidates unless a specific audition requires a smaller file or a higher-quality master. If a production pass starts from PCM, export the final runtime file back to MP3 and record the source/master relationship in credits or the media catalog.

## Minimal cURL

Always write the response to a file. The success body is audio bytes, not JSON.

```bash
mkdir -p tmp/media-generation/elevenlabs-sfx

curl --fail-with-body --show-error --silent \
  --request POST \
  "https://api.elevenlabs.io/v1/sound-generation?output_format=mp3_44100_128" \
  --header "xi-api-key: ${ELEVENLABS_API_KEY}" \
  --header "Content-Type: application/json" \
  --data '{
    "text": "Short low gritty orc effort grunt for a fantasy strategy game UI, dry mix, no speech, no music, punchy transient, under one second",
    "duration_seconds": 0.8,
    "prompt_influence": 0.45,
    "model_id": "eleven_text_to_sound_v2"
  }' \
  --output tmp/media-generation/elevenlabs-sfx/orc-active-v01.mp3
```

If the request fails, do not treat the output path as an audio file. Inspect the HTTP status and error body first.

## Node Fetch Example

This avoids adding a local SDK dependency for one-off draft generation.

```js
import { mkdir, writeFile } from "node:fs/promises";

const apiKey = process.env.ELEVENLABS_API_KEY;
if (!apiKey) throw new Error("ELEVENLABS_API_KEY is required");

const outDir = "tmp/media-generation/elevenlabs-sfx";
await mkdir(outDir, { recursive: true });

const response = await fetch(
  "https://api.elevenlabs.io/v1/sound-generation?output_format=mp3_44100_128",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "xi-api-key": apiKey,
    },
    body: JSON.stringify({
      text: "Bright elven completion shimmer for a fantasy strategy game UI, soft crystal sparkle, no voice, no melody, clean tail",
      duration_seconds: 1.1,
      prompt_influence: 0.5,
      model_id: "eleven_text_to_sound_v2",
    }),
  },
);

if (!response.ok) {
  throw new Error(`${response.status} ${await response.text()}`);
}

const audio = Buffer.from(await response.arrayBuffer());
await writeFile(`${outDir}/elf-complete-v01.mp3`, audio);
console.log("character-cost", response.headers.get("character-cost"));
```

## Error Shape

The documented validation response is `422`. Example shape:

```json
{
  "detail": [
    {
      "loc": ["body", "duration_seconds"],
      "msg": "Input should be less than or equal to 30",
      "type": "less_than_equal"
    }
  ]
}
```

Common local causes:

* Missing or empty `text`.
* `duration_seconds` below `0.5` or above `30`.
* `prompt_influence` outside `0` to `1`.
* `output_format` not in the enum above.
* `loop: true` with a model that does not support looping.

## FactionOS Production Rules

* Keep `ELEVENLABS_API_KEY` in `.env.local` or the shell environment. Never put provider keys in browser code, markdown examples with real values, committed manifests, filenames, captions, metadata, or screenshots.
* Stage raw provider outputs under `tmp/media-generation/` or another ignored staging directory.
* Do not commit generated candidates directly into runtime paths.
* Do not include actual provider-run prompts, raw request bodies, absolute local paths, secrets, transcripts, logs, or provider response bodies in stable docs or release evidence.
* Every audio cue must have an equivalent visible and screen-reader-readable signal. Audio is optional and defaults to opt-in runtime playback.
* Runtime promotion for app SFX goes through `apps/web/src/lib/sfxAssets.ts`, `apps/web/public/sfx/CREDITS.md`, media catalog or promotion records, and the media gates.
* Public-demo promotion also needs mirror/cache review in `public-demo/`.

Relevant local files:

| Purpose                      | Path                                                          |
| ---------------------------- | ------------------------------------------------------------- |
| Runtime SFX manifest         | `apps/web/src/lib/sfxAssets.ts`                               |
| File-backed playback adapter | `apps/web/src/lib/fileVoiceSynth.ts`                          |
| Audio runtime boundary       | `apps/web/src/lib/audioRuntime.ts`                            |
| Synthetic fallback           | `apps/web/src/lib/voiceSynth.ts`                              |
| World cue derivation         | `apps/web/src/lib/worldCues.ts`                               |
| Runtime SFX files            | `apps/web/public/sfx/`                                        |
| Runtime SFX provenance       | `apps/web/public/sfx/CREDITS.md`                              |
| Audio production slate       | `docs/ongoing-projects/game-design-audio-production-slate.md` |
| Synthetic sound map          | `docs/ongoing-projects/synthetic-sound-map.md`                |
| Media release posture        | `docs/media/media-assets.md`                                  |

## Local Naming Targets

### Faction Bark SFX

Target runtime naming:

```
apps/web/public/sfx/<faction>-<kind>.mp3
```

Factions:

```
orc
human
elf
undead
lobster
```

Bark kinds:

```
idle
active
complete
error
celebration
```

Final production target: 25 dedicated bark files. Speech-backed errors are runtime fallback only; the final goal is a dedicated SFX file for every `faction + kind`.

Suggested duration bands:

| Bark kind     | Suggested duration | Prompt character                                              |
| ------------- | -----------------: | ------------------------------------------------------------- |
| `idle`        | `0.5` to `0.8` sec | Low-energy acknowledgement, nonverbal, unobtrusive.           |
| `active`      | `0.6` to `1.0` sec | Alert, ready, on-task, more transient.                        |
| `complete`    | `0.9` to `1.3` sec | Satisfying resolution, slight lift, no melody.                |
| `error`       | `0.5` to `0.9` sec | Harsh but not painful, attention-grabbing, not an alarm loop. |
| `celebration` | `1.2` to `2.0` sec | Short flourish, triumphant, no spoken words.                  |

Faction prompt anchors:

| Faction | Prompt anchor                                                     |
| ------- | ----------------------------------------------------------------- |
| Orc     | Low, gritty, leather/wood/war-drum body, rough effort, nonverbal. |
| Human   | Clean martial UI, cloth, shield, steel, confident but compact.    |
| Elf     | Airy crystal, bowstring, leaf shimmer, precise, light high end.   |
| Undead  | Hollow bone, grave wind, low rattle, spectral, dark but readable. |
| Lobster | Fast shell clicks, wet chitter, tiny claws, comic but useful.     |

Example bark prompt template:

```
{duration}s {faction} {kind} cue for a fantasy strategy game UI,
{materials and action}, nonverbal, no speech, no music, no long reverb tail,
dry mix, mono-compatible, clean start, game-ready transient
```

### World Cues

Current typed world cue keys:

```
camp_hit
camp_collapse
ram_crash
ram_break_triumph
skirmisher_red_slash
flare_attention
```

Suggested runtime names when these are promoted:

```
apps/web/public/sfx/world-camp-hit.mp3
apps/web/public/sfx/world-camp-collapse.mp3
apps/web/public/sfx/world-ram-crash.mp3
apps/web/public/sfx/world-ram-break-triumph.mp3
apps/web/public/sfx/world-skirmisher-red-slash.mp3
apps/web/public/sfx/world-flare-attention.mp3
```

Suggested cue briefs:

| Cue                    |           Duration | Prompt direction                                  |
| ---------------------- | -----------------: | ------------------------------------------------- |
| `camp_hit`             | `0.6` to `0.9` sec | Heavy thud or impact, low-mid, not musical.       |
| `camp_collapse`        | `1.2` to `1.8` sec | Crumble plus compact victory lift, no voice.      |
| `ram_crash`            | `0.8` to `1.2` sec | Wooden ram hits stone gate, urgent transient.     |
| `ram_break_triumph`    | `1.0` to `1.6` sec | Wood splinter break plus brief release.           |
| `skirmisher_red_slash` | `0.4` to `0.8` sec | Fast sharp slash, failure marker, not too loud.   |
| `flare_attention`      | `0.5` to `0.9` sec | Priority attention sting, clear but fatigue-safe. |

World cue mapping shape in `SFX_FILES.world`:

```ts
world: {
  camp_hit: [`${SFX_BASE}/world-camp-hit.mp3`],
  camp_collapse: [`${SFX_BASE}/world-camp-collapse.mp3`],
  ram_crash: [`${SFX_BASE}/world-ram-crash.mp3`],
  ram_break_triumph: [`${SFX_BASE}/world-ram-break-triumph.mp3`],
  skirmisher_red_slash: [`${SFX_BASE}/world-skirmisher-red-slash.mp3`],
  flare_attention: [`${SFX_BASE}/world-flare-attention.mp3`],
}
```

## Generation Workflow

1. Pick one semantic cue ID from the audio production slate.
2. Generate 3 to 5 candidates into `tmp/media-generation/elevenlabs-sfx/`.
3. Use stable candidate names, for example `human-active-v01.mp3`.
4. Audition candidates with the app music and UI density in mind.
5. Trim, normalize, and transcode the approved candidate.
6. Write provenance in `apps/web/public/sfx/CREDITS.md` or the relevant catalog record.
7. Copy only the approved runtime file into `apps/web/public/sfx/`.
8. Add the mapping in `apps/web/src/lib/sfxAssets.ts`.
9. Verify fallback, muted audio, reduced-motion equivalent, and visible UI state still work.
10. Run the relevant media gates before claiming promotion.

Suggested local checks after adding or remapping SFX:

```bash
npm run media:check
npm run media:drafts:check
npm run media:gates:check
npm run typecheck --workspaces --if-present
```

If public-demo media changes too, also run:

```bash
npm run media:demo:check
```

## Prompt Recipes

Use these as starting points. Keep prompts specific to sound, not story text.

### Bark Examples

```json
{
  "text": "Short low gritty orc idle acknowledgement for a fantasy strategy game UI, rough throat and leather movement, nonverbal, no speech, no music, dry close mix",
  "duration_seconds": 0.7,
  "prompt_influence": 0.45,
  "model_id": "eleven_text_to_sound_v2"
}
```

```json
{
  "text": "Compact human active command cue for a fantasy strategy game UI, shield tap and cloth snap, confident martial feel, no voice, no melody, clean transient",
  "duration_seconds": 0.8,
  "prompt_influence": 0.5,
  "model_id": "eleven_text_to_sound_v2"
}
```

```json
{
  "text": "Bright elven complete cue for a fantasy strategy game UI, crystal shimmer and bowstring release, satisfying but subtle, no speech, no music, short tail",
  "duration_seconds": 1.1,
  "prompt_influence": 0.5,
  "model_id": "eleven_text_to_sound_v2"
}
```

```json
{
  "text": "Harsh undead error cue for a fantasy strategy game UI, hollow bone rattle and cold grave wind, attention grabbing, nonverbal, no scream, no music",
  "duration_seconds": 0.8,
  "prompt_influence": 0.55,
  "model_id": "eleven_text_to_sound_v2"
}
```

```json
{
  "text": "Tiny lobster celebration cue for a fantasy strategy game UI, fast shell clicks and bubbly claw flourish, comic but crisp, no speech, no music",
  "duration_seconds": 1.3,
  "prompt_influence": 0.5,
  "model_id": "eleven_text_to_sound_v2"
}
```

### World Cue Examples

```json
{
  "text": "Heavy camp hit impact for a fantasy strategy game map, blunt wood and earth thud, low-mid punch, no music, no voice, very short clean transient",
  "duration_seconds": 0.7,
  "prompt_influence": 0.5,
  "model_id": "eleven_text_to_sound_v2"
}
```

```json
{
  "text": "Battle ram crashes into a stone gate for a fantasy strategy game alert, heavy wood impact and stone dust, urgent but not alarm-like, no voice, no music",
  "duration_seconds": 1.0,
  "prompt_influence": 0.55,
  "model_id": "eleven_text_to_sound_v2"
}
```

```json
{
  "text": "Priority flare attention sting for a fantasy strategy game UI, bright spark ignition and compact signal tone, clear but not harsh, no melody, no voice",
  "duration_seconds": 0.7,
  "prompt_influence": 0.5,
  "model_id": "eleven_text_to_sound_v2"
}
```

### Loop Example

Use looping only for ambience or music-bed-like assets, not one-shot UI cues.

```json
{
  "text": "Seamless quiet haunted battlefield ambience loop, distant wind through dead banners, low tension, no melody, no impacts, no voices",
  "loop": true,
  "duration_seconds": 12,
  "prompt_influence": 0.4,
  "model_id": "eleven_text_to_sound_v2"
}
```

## Post-Generation QA

Before a candidate becomes a runtime file:

* Confirm it is not speech unless the cue is explicitly speech.
* Confirm it does not contain recognizable copyrighted music, melody, or voice.
* Confirm it is not too loud compared with existing speech and music.
* Confirm it still reads when played quietly.
* Confirm it does not mask urgent UI announcements.
* Trim silence at the start so UI response feels immediate.
* Avoid long reverb tails on frequently repeated cues.
* Remove metadata that could expose prompts, local paths, account identifiers, timestamps that matter, or other provider run details.

Useful local probes:

```bash
ffprobe -hide_banner apps/web/public/sfx/human-active.mp3
```

```bash
ffmpeg -i tmp/media-generation/elevenlabs-sfx/human-active-v01.mp3 \
  -ac 1 -ar 44100 -codec:a libmp3lame -b:a 128k \
  apps/web/public/sfx/human-active.mp3
```

Adjust loudness per cue family during mastering; do not blindly normalize every asset to the same perceived level if it changes gameplay meaning.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/docs/media/elevenlabs-soundfx.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
