Skip to main content

Endpoints

The audio paths mirror ElevenLabs’ own, with ElevenLabs’ own request bodies. Point the ElevenLabs SDK at the gateway with base_url="https://gateway.langwatch.ai" and the virtual key in place of the ElevenLabs key. The key goes in the xi-api-key header the SDK already sends. The ElevenLabs key itself stays on the organization’s ElevenLabs model provider. An SDK that still sends it gets 401 invalid_api_key, because the gateway reads that header as a virtual key. The audio paths are served only by an ElevenLabs credential. A key that cannot reach ElevenLabs answers 400 model_provider_not_bound and no provider is called. There is no fallback to another provider.

Text to speech

The response is ElevenLabs’ audio bytes and headers, unchanged, relayed as ElevenLabs sends them. /stream and /stream/with-timestamps take the same body and query string and reach the same paths on ElevenLabs. They are gated and metered exactly like the plain path.
/stream/with-timestamps answers with a stream of JSON objects, each carrying audio_base64, alignment and normalized_alignment:
The request body is capped at 1 MB; over the cap: 413 payload_too_large. The audio response is capped at 32 MiB, counted as it is relayed: a longer response is cut at the cap.

Speech to text

The response is ElevenLabs’ transcript JSON, unchanged. Transcription is metered by the audio duration ElevenLabs reports on it.

Request and response headers

The X-LangWatch-End-User-Id, X-LangWatch-Metadata and Traceparent request headers work as on Chat Completions. The audio paths return the same response headers as Chat Completions, plus ElevenLabs’ own response headers. A forwarded ElevenLabs error carries X-LangWatch-Provider: elevenlabs and the vendor’s Retry-After when it sent one.

Streaming

All three text to speech paths answer with a chunked body that is written and flushed as ElevenLabs sends it. If ElevenLabs fails mid-stream the connection is closed without the terminating chunk, so the HTTP client reports a truncated body. Speech to text does not stream. The transcript is returned complete.

Single-use tokens

The path is ElevenLabs’ own. The gateway checks the key’s budgets and its open-session cap, mints the token with the stored ElevenLabs key, and returns ElevenLabs’ body with langwatch.session_id added. The same id is on the X-LangWatch-Session-Id response header. A token is valid for 15 minutes and opens one socket. The socket runs from your client to ElevenLabs and does not pass through the gateway. The gateway does not see what the socket used, so your client reports it. Any other token_type answers 400 bad_request. ElevenLabs’ token route takes no model, so the gateway reads one from the model_id query parameter. It is resolved through the key’s aliases and allowlist and is the model the session is billed under. Pass the model your socket will use. Outside the allowlist: 400 model_not_allowed. model_id is not forwarded to ElevenLabs. The route is served only by an ElevenLabs credential, and a customer on a residency host is minted on that host.

Opening the socket

The query parameter that carries the token differs per socket.
eleven_v3 and eleven_v4 models run on the Text to Dialogue socket, not on stream-input. Mint a ttd_websocket token for it. ElevenLabs’ reference does not list that token type, and the Text to Dialogue socket accepts no other: a tts_websocket token is refused with close code 1008 and invalid_token_type.

Reporting usage and closing

ElevenLabs sockets send no usage. Count it in your client and post it to the session:
id names the report. Reports with different ids add up, and a report resent with the same id is recorded once. A report with no id and no final is read as the session total and closes the session. Add "final": true to any report to close the session after it is recorded. To close without usage:
The response body and the charge for a session that never reports are described on Realtime voice.

Relayed sockets

The gateway also serves the ElevenLabs sockets itself. The client opens the socket on the gateway with its virtual key, the gateway opens the same path at ElevenLabs with the stored key and passes frames both ways. Use this when the client should hold no ElevenLabs credential at all and should not report its own usage. A single-use token keeps the socket client to ElevenLabs and saves the hop. Pass the virtual key as Authorization: Bearer, as the xi-api-key header, or as the xi-api-key or authorization query parameter. The gateway removes the key parameters from the query string and forwards the rest as written (output_format, audio_format, language_code and so on). model_id goes through the key’s aliases and allowlist; outside the allowlist the request answers 400 model_not_allowed before the upgrade.
If the first frame carries xi-api-key, xi_api_key or authorization, the gateway strips those fields from that frame. Every other frame is forwarded byte for byte, in both directions.

How relayed sockets are metered

ElevenLabs sockets state no usage, so the gateway counts what the client sends.
  • Speech. The characters of every text field the client sends: text on stream-input and on each context of multi-stream-input, and each inputs[].text on Text to Dialogue. The keep-alive " " counts one character and the closing "" counts none.
  • Transcription. The seconds of audio sent: the decoded length of each audio_base_64 chunk divided by the byte rate of audio_format. pcm_16000, the default, is 32,000 bytes per second, and ulaw_8000 is 8,000.
The gateway reads client text frames for those fields only. Usage is recorded at most every 10 seconds while the socket runs and once more when it closes. Do not post usage for a relayed socket. A relayed socket is closed by the gateway on an exhausted budget (1008), a revoked key (1008) and a deploy (1012). The codes and what the client should do are on Realtime voice.

Post-call webhook

This is the URL to paste into the ElevenLabs workspace webhook settings, for Conversational AI sessions brokered by the gateway. {model_provider_id} is the id of the ElevenLabs model provider row in Settings, Model Providers. Store the webhook secret from ElevenLabs on that same provider row, under ELEVENLABS_WEBHOOK_SECRET. The route takes no virtual key. Each delivery authenticates itself: the gateway relays the raw bytes and the ElevenLabs-Signature header to LangWatch, which computes the HMAC with the provider’s stored secret and accepts a signature timestamp at most 30 minutes old. What happens with a delivery: Responses: The webhook is the fast path. Two minutes after a mint, LangWatch also reads the conversation back from ElevenLabs by its own id, so a session bills even when no delivery arrives.

Errors

The full table is on Errors.
Last modified on October 12, 2026