> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nativeport.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nativeport.ai/_mcp/server.

# ElevenLabs

Fronts [ElevenLabs](https://elevenlabs.io/docs/api-reference) audio generation together with the voice/model catalog at `https://api.elevenlabs.io`; the secret `xi-api-key` header comes from the gateway. The path following `/elevenlabs/` is relayed upstream, restricted to generation `POST`s and catalog-read `GET`s:

```
GET|POST /elevenlabs/<api path>   → https://api.elevenlabs.io/<api path>
```

Admission is default-deny against a fixed allowlist: the generation `POST`s alongside the catalog `GET`s listed below are what passes, and any other path draws a `404` until the endpoint concerned is added to the allowlist. Kept out: `PATCH` and `DELETE` (`/v1/convai/agents` included), plus the account, workspace, and history reads. Mounted methods: `GET`, `POST`.

## Common paths

| Path                                                     | Purpose                           |
| -------------------------------------------------------- | --------------------------------- |
| `POST /elevenlabs/v1/text-to-speech/{voice_id}`          | Text to speech (returns audio)    |
| `POST /elevenlabs/v1/text-to-speech/{voice_id}/stream`   | Streaming text to speech          |
| `POST /elevenlabs/v1/sound-generation`                   | Generate sound effects            |
| `POST /elevenlabs/v1/speech-to-text`                     | Transcribe audio                  |
| `GET /elevenlabs/v1/voices`, `GET /elevenlabs/v2/voices` | List voices                       |
| `GET /elevenlabs/v1/models`                              | List models                       |
| `GET /elevenlabs/v1/convai/conversation/get-signed-url`  | Signed URL for a ConvAI WebSocket |

## Credential handling

* **`xi-api-key` is injected** as a header; a client-supplied one is overwritten.
* **An `xi-api-key` query parameter from the client is discarded** (any encoding).
* **`Authorization` is removed** before the request goes upstream.

## Responses (binary audio included)

Nothing is transformed on the way back. Text-to-speech and sound generation yield binary audio (PCM or `audio/mpeg`), with chunked delivery on the `/stream` variants; the gateway relays the bytes exactly.

```bash
curl -X POST "$GATEWAY/elevenlabs/v1/text-to-speech/JBFqnCBsd6RMkjVDRZzb" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello from the gateway", "model_id": "eleven_multilingual_v2"}' \
  --output speech.mp3
```

## WebSocket / realtime use

**No WebSocket endpoint is proxied** — bearer gating and forwarding cover plain HTTP alone.

When realtime is needed, obtain a short-lived credential **via** the gateway first, then open your socket straight against ElevenLabs:

1. Call `GET /elevenlabs/v1/convai/conversation/get-signed-url` via the gateway.
2. Use the credential it returns to open the WebSocket directly against ElevenLabs.

As before, the master key never lands on the client.

Field-level request and response detail lives in [ElevenLabs' API reference](https://elevenlabs.io/docs/api-reference); the gateway modifies neither.