What is AI Gateway?
Think of AI Gateway as a single front door to many AI models. Instead of managing separate API keys and billing for each provider, you use one unified API key.
The Partnership:
Your App → One AI Gateway API Key → Any of 14 ElevenLabs Models
Think of them in three groups:
| Type | What It Does | Real Example |
|---|---|---|
| Speech to Text | Converts spoken audio → written text | Captioning a live meeting |
| Streaming Text to Speech | Converts text → spoken audio while still generating | Reading an AI reply aloud as it writes |
| Realtime Voice Agents | Full two-way spoken conversation in one session | A customer support phone bot |
| Type | What It Does | Real Example |
|---|---|---|
| Music | Text description → full song or instrumental | "Lo-fi beat with piano" → MP3 |
| Sound Effects | Text description → short audio clip | "Door slamming" → sound file |
| Type | What It Does | Real Example |
|---|---|---|
| Multi-voice Dialogue | Script with multiple speakers → one recording | Two-host podcast, no stitching needed |
This is the most important architecture to grasp. It chains three separate models:
Microphone Audio
↓
[Model 1: Scribe v2 Realtime] ← Speech to Text
↓
Text Transcript
↓
[Model 2: Claude / Any LLM] ← Reasoning
↓
Text Response
↓
[Model 3: Eleven Flash v2.5] ← Text to Speech
↓
Audio Output to User
Key benefit: Each step is swappable independently. Change the voice model without touching the transcription model.
import {
experimental_streamSpeech as streamSpeech,
experimental_streamTranscribe as streamTranscribe,
streamText,
} from 'ai';
// STEP 1: Transcribe microphone input → text
const heard = streamTranscribe({
model: 'elevenlabs/scribe-v2-realtime',
audio: microphoneStream,
inputAudioFormat: { type: 'audio/pcm', rate: 16000 }, // 16kHz audio
});
// STEP 2: Send transcript to a language model → text response
const { textStream } = streamText({
model: 'anthropic/claude-haiku-5.5',
prompt: await heard.text,
});
// STEP 3: Convert LLM text response → spoken audio
const { audioStream } = streamSpeech({
model: 'elevenlabs/eleven-flash-v2.5',
text: textStream,
voice: 'hpp4J3VqNfWAUOO0d1Us', // ElevenLabs voice ID
});
Why streaming matters: The user hears the reply start before the LLM finishes writing it. No waiting.
Unlike the pipeline above, realtime agents handle everything in one model over a single WebSocket connection.
User speaks → [WebSocket] → Eleven Realtime v1 → [WebSocket] → User hears reply
No separate transcription or speech steps needed.
Two model options:
eleven-realtime-v1-max → Higher qualityeleven-realtime-v1-mini → Faster/lighterimport { gateway } from 'ai';
// Server only mints a short-lived token
// Your real API key never reaches the browser
const { token, url } = await gateway.experimental_realtime.getToken({
model: 'elevenlabs/eleven-realtime-v1-max',
});
// Use useRealtime hook from @ai-sdk/react
sessionConfig: {
voice: 'your-elevenlabs-voice-id',
turnDetection: { type: 'semantic-vad' } // ✅ Supported
// turnDetection: { type: 'server-vad' } // ❌ NOT supported
}
Important:
semantic-vad= the model understands meaning to detect when you've finished speaking, not just silence.
Both use the same generateSpeech function. The text parameter describes the sound instead of words to speak.
import { generateSpeech } from 'ai';
const { audio } = await generateSpeech({
model: 'elevenlabs/music-v2.5',
text: 'A mellow lo-fi beat with soft piano', // describe the music
providerOptions: {
elevenlabs: {
musicLengthMs: 30000 // 30 seconds
}
},
});
Music model options:
music-v2.5 → Latestmusic-v2 → Previous versionWhat you can specify in text:
Sound Effects work identically, just use elevenlabs/sound-effects-v2 and describe a short sound.
One API call → one continuous audio file with multiple distinct voices.
import { experimental_streamSpeech as streamSpeech } from 'ai';
// Define your voice IDs
const host = 'hpp4J3VqNfWAUOO0d1Us';
const guest = 'CwhRBWXzGAHq8TQ4Fs17';
const { audioStream } = streamSpeech({
model: 'elevenlabs/eleven-v4',
text: [
{ type: 'text', text: 'Did the deploy go out?', voice: host }, // Line 1
{ type: 'text', text: 'It shipped an hour ago.', voice: guest }, // Line 2
],
providerOptions: {
elevenlabs: {
dialogue: { voices: [host, guest] } // Register all voices used
}
},
});
Multi-voice model options:
eleven-v4 → Standardeleven-v4-turbo → Fastereleven-v3 → Previous generationKey advantage: No audio stitching. One request returns one seamless recording.
┌─────────────────────────────────────────────────────┐
│ ElevenLabs on AI Gateway │
├─────────────────┬───────────────────────────────────┤
│ USE CASE │ MODEL / APPROACH │
├─────────────────┼───────────────────────────────────┤
│ Transcribe audio│ scribe-v2-realtime (streamTranscribe) │
│ Speak text │ eleven-flash-v2.5 (streamSpeech) │
│ Full voice chat │ eleven-realtime-v1-max (WebSocket) │
│ Generate music │ music-v2.5 (generateSpeech) │
│ Sound effects │ sound-effects-v2 (generateSpeech) │
│ Multi-speaker │ eleven-v4 (streamSpeech + array) │
└─────────────────┴───────────────────────────────────┘
One API key. One usage dashboard. All six capabilities.
Ask yourself:
semantic-vad do that silence detection cannot?generateSpeech serve double duty for both music and sound effects?