---
title: "Unified Real-Time TTS API: One Aggregator for Multiple Providers"
description: "A unified real-time TTS API and aggregator for multiple voice providers. Stream audio over WebSocket or use OpenAI- and ElevenLabs-compatible SDKs with one key."
canonical: "https://allmodels.io/guides/universal-tts-api"
markdown: "https://allmodels.io/guides/universal-tts-api.md"
author: "AllModels"
datePublished: "2026-10-12"
dateModified: "2026-10-16"
---

# One API for real-time text-to-speech providers

Connect to multiple TTS models through AllModels. Stream audio over WebSocket, use an OpenAI- or ElevenLabs-compatible SDK, and switch models without rebuilding your voice stack.

> AllModels is an independent service and is not affiliated with, endorsed by, or sponsored by the providers whose models it routes to.

## What a unified TTS API is

A unified text-to-speech (TTS) API is a single integration that can generate speech with models from many different providers. Instead of writing one client for Cartesia, another for ElevenLabs, another for MiniMax and another for OpenAI, your application talks to one endpoint with one API key. The model you choose decides which provider does the work. AllModels is a unified TTS API of this kind: you send a model ID such as `cartesia/sonic-3-6` or `minimax/speech-2-8-hd`, and AllModels routes the request to that provider and streams the audio back. The same idea goes by other names: a TTS aggregator API, a text-to-speech abstraction layer, or an "OpenRouter for text-to-speech".

### How AllModels works

Every model in the [AllModels TTS catalogue](https://allmodels.io/models?type=tts) has a `provider/model` ID. You authenticate once with an AllModels API key, which replaces the separate keys and billing accounts you would otherwise keep with each provider. AllModels then offers three ways to call the same models:

- **Native WebSocket** at `wss://api.allmodels.io/v1/tts`. You send text as it is produced and receive audio as binary messages. This is the AllModels-native real-time interface.
- **OpenAI-compatible** at `https://api.allmodels.io/oai`. Point the official OpenAI SDK at this base URL and keep calling `audio.speech.create`.
- **ElevenLabs-compatible** at `https://api.allmodels.io/el`. Point the official ElevenLabs SDK at this base URL and keep calling its text-to-speech methods, including streaming.

All three reach the same catalogue. If your codebase already uses the OpenAI or ElevenLabs SDK, you can move to AllModels by changing the base URL and API key.

### One catalogue, one key, one balance

As an aggregator, AllModels also gives you one place to compare and control providers. `GET /v1/models` lists every TTS model, the providers that serve it and its price per 1,000 characters. When a model is available from more than one provider, a `provider` preference chooses between them: `only` pins the request to the providers you list, `order` puts them first and `ignore` leaves them out. Usage from every provider is charged to one prepaid AllModels balance instead of a separate bill per provider.

### Change the model, keep everything else

Your API key, endpoint, client and request code stay exactly the same from one provider to the next. To use a different TTS model, change the model ID. AllModels takes care of the rest: it connects to the provider, handles its API and returns the audio to your application.

## Stream real-time audio from any client

Choose a client, a mode and a language. Highlighted lines are the AllModels base URL and the model and voice values you change to try another model.

### Native WebSocket, streaming — JavaScript · Node.js · ws

Client: Native · Mode: Streaming · Language: JS

Connect to `wss://api.allmodels.io/v1/tts`, send text as it is produced and receive audio as binary messages. [Streaming guide](https://allmodels.io/docs/streaming-realtime).

```javascript
import { once } from "node:events";
import { createWriteStream } from "node:fs";
import WebSocket from "ws";

const url = new URL("wss://api.allmodels.io/v1/tts");
url.searchParams.set("model", "grok/grok-tts");
url.searchParams.set("voice", "eve");
url.searchParams.set("format", "pcm");

const output = createWriteStream("reply.pcm");
const ws = new WebSocket(url, {
  headers: { Authorization: `Bearer ${process.env.ALLMODELS_API_KEY}` }
});

// Audio arrives as binary WebSocket messages.
ws.on("message", (data, isBinary) => {
  if (isBinary) output.write(data);
});

await once(ws, "open");
// Send text as your LLM or application produces it.
ws.send(JSON.stringify({ type: "text", text: "Your order has shipped. " }));
ws.send(JSON.stringify({ type: "text", text: "It arrives tomorrow." }));
ws.send(JSON.stringify({ type: "flush" }));
ws.send(JSON.stringify({ type: "close" }));

await once(ws, "close");
output.end();
```

### Native WebSocket, streaming — Python · websockets

Client: Native · Mode: Streaming · Language: Python

Connect to `wss://api.allmodels.io/v1/tts`, send text as it is produced and receive audio as binary messages. [Streaming guide](https://allmodels.io/docs/streaming-realtime).

```python
import asyncio
import json
import os

import websockets

URL = (
    "wss://api.allmodels.io/v1/tts"
    "?model=grok%2Fgrok-tts&voice=eve&format=pcm"
)

async def receive_audio(socket):
    with open("reply.pcm", "wb", buffering=0) as output:
        async for message in socket:
            if isinstance(message, bytes):
                output.write(message)

async def main():
    async with websockets.connect(
        URL,
        additional_headers={
            "Authorization": f"Bearer {os.environ['ALLMODELS_API_KEY']}"
        },
    ) as socket:
        receiver = asyncio.create_task(receive_audio(socket))
        for text in ["Your order has shipped. ", "It arrives tomorrow."]:
            await socket.send(json.dumps({"type": "text", "text": text}))
        await socket.send(json.dumps({"type": "flush"}))
        await socket.send(json.dumps({"type": "close"}))
        await receiver

asyncio.run(main())
```

### HTTP, single request — JavaScript · Node.js · fetch

Client: Native · Mode: Request · Language: JS

Already have the complete text? POST it to `https://api.allmodels.io/oai/audio/speech` and save the audio file. [TTS docs](https://allmodels.io/docs/text-to-speech).

```javascript
import { writeFile } from "node:fs/promises";

const response = await fetch("https://api.allmodels.io/oai/audio/speech", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ALLMODELS_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "grok/grok-tts",
    voice: "eve",
    input: "Your order has shipped. It arrives tomorrow.",
    response_format: "mp3"
  })
});

if (!response.ok) throw new Error(await response.text());
await writeFile("speech.mp3", Buffer.from(await response.arrayBuffer()));
```

### HTTP, single request — Python · requests

Client: Native · Mode: Request · Language: Python

Already have the complete text? POST it to `https://api.allmodels.io/oai/audio/speech` and save the audio file. [TTS docs](https://allmodels.io/docs/text-to-speech).

```python
import os

import requests

response = requests.post(
    "https://api.allmodels.io/oai/audio/speech",
    headers={"Authorization": f"Bearer {os.environ['ALLMODELS_API_KEY']}"},
    json={
        "model": "grok/grok-tts",
        "voice": "eve",
        "input": "Your order has shipped. It arrives tomorrow.",
        "response_format": "mp3",
    },
    timeout=60,
)
response.raise_for_status()

with open("speech.mp3", "wb") as output:
    output.write(response.content)
```

### OpenAI SDK, streaming — JavaScript · openai

Client: OpenAI SDK · Mode: Streaming · Language: JS

Set the OpenAI SDK base URL to `https://api.allmodels.io/oai` and call `audio.speech.create`. Audio streams back as it is generated. [OpenAI TTS docs](https://allmodels.io/docs/openai/text-to-speech).

```javascript
import { createWriteStream } from "node:fs";
import { Readable } from "node:stream";
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.ALLMODELS_API_KEY,
  baseURL: "https://api.allmodels.io/oai"
});

const response = await client.audio.speech.create({
  model: "grok/grok-tts",
  voice: "eve",
  input: "Your order has shipped. It arrives tomorrow.",
  response_format: "pcm",
  stream_format: "audio"
});

Readable.fromWeb(response.body).pipe(createWriteStream("speech.pcm"));
```

### OpenAI SDK, streaming — Python · openai

Client: OpenAI SDK · Mode: Streaming · Language: Python

Set the OpenAI SDK base URL to `https://api.allmodels.io/oai` and stream the response to a file as it is generated. [OpenAI TTS docs](https://allmodels.io/docs/openai/text-to-speech).

```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ALLMODELS_API_KEY"],
    base_url="https://api.allmodels.io/oai",
)

with client.audio.speech.with_streaming_response.create(
    model="grok/grok-tts",
    voice="eve",
    input="Your order has shipped. It arrives tomorrow.",
    response_format="pcm",
) as response:
    response.stream_to_file("speech.pcm")
```

### OpenAI SDK, single request — JavaScript · openai

Client: OpenAI SDK · Mode: Request · Language: JS

Set the OpenAI SDK base URL to `https://api.allmodels.io/oai` and request a complete audio file. [OpenAI TTS docs](https://allmodels.io/docs/openai/text-to-speech).

```javascript
import { writeFile } from "node:fs/promises";
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.ALLMODELS_API_KEY,
  baseURL: "https://api.allmodels.io/oai"
});

const audio = await client.audio.speech.create({
  model: "grok/grok-tts",
  voice: "eve",
  input: "Your order has shipped. It arrives tomorrow.",
  response_format: "mp3"
});

await writeFile("speech.mp3", Buffer.from(await audio.arrayBuffer()));
```

### OpenAI SDK, single request — Python · openai

Client: OpenAI SDK · Mode: Request · Language: Python

Set the OpenAI SDK base URL to `https://api.allmodels.io/oai` and request a complete audio file. [OpenAI TTS docs](https://allmodels.io/docs/openai/text-to-speech).

```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ALLMODELS_API_KEY"],
    base_url="https://api.allmodels.io/oai",
)

audio = client.audio.speech.create(
    model="grok/grok-tts",
    voice="eve",
    input="Your order has shipped. It arrives tomorrow.",
    response_format="mp3",
)

audio.write_to_file("speech.mp3")
```

### ElevenLabs SDK, streaming — JavaScript · @elevenlabs/elevenlabs-js

Client: ElevenLabs SDK · Mode: Streaming · Language: JS

Set the ElevenLabs SDK base URL to `https://api.allmodels.io/el` and stream audio chunks as they are generated. [ElevenLabs TTS docs](https://allmodels.io/docs/elevenlabs/text-to-speech).

```javascript
import { createWriteStream } from "node:fs";
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const client = new ElevenLabsClient({
  apiKey: process.env.ALLMODELS_API_KEY,
  baseUrl: "https://api.allmodels.io/el"
});

const audio = await client.textToSpeech.stream("eve", {
  text: "Your order has shipped. It arrives tomorrow.",
  modelId: "grok/grok-tts",
  outputFormat: "mp3_44100_128"
});

const output = createWriteStream("speech.mp3");
for await (const chunk of audio) {
  output.write(Buffer.from(chunk));
}
output.end();
```

### ElevenLabs SDK, streaming — Python · elevenlabs

Client: ElevenLabs SDK · Mode: Streaming · Language: Python

Set the ElevenLabs SDK base URL to `https://api.allmodels.io/el`. `convert_realtime` sends text over a WebSocket as it is produced and returns audio as it arrives. [ElevenLabs TTS docs](https://allmodels.io/docs/elevenlabs/text-to-speech).

```python
import os
from elevenlabs.client import ElevenLabs

client = ElevenLabs(
    api_key=os.environ["ALLMODELS_API_KEY"],
    base_url="https://api.allmodels.io/el",
)

def generated_text():
    # Yield text as your LLM or application produces it.
    yield "Your order has shipped. "
    yield "It arrives tomorrow."

audio = client.text_to_speech.convert_realtime(
    "eve",
    text=generated_text(),
    model_id="grok/grok-tts",
    output_format="pcm_24000",
)

with open("reply.pcm", "wb", buffering=0) as output:
    for chunk in audio:
        output.write(chunk)
```

### ElevenLabs SDK, single request — JavaScript · @elevenlabs/elevenlabs-js

Client: ElevenLabs SDK · Mode: Request · Language: JS

Set the ElevenLabs SDK base URL to `https://api.allmodels.io/el` and convert complete text to an audio file. [ElevenLabs TTS docs](https://allmodels.io/docs/elevenlabs/text-to-speech).

```javascript
import { writeFile } from "node:fs/promises";
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const client = new ElevenLabsClient({
  apiKey: process.env.ALLMODELS_API_KEY,
  baseUrl: "https://api.allmodels.io/el"
});

const audio = await client.textToSpeech.convert("eve", {
  text: "Your order has shipped. It arrives tomorrow.",
  modelId: "grok/grok-tts",
  outputFormat: "mp3_44100_128"
});

const chunks = await Array.fromAsync(audio, (chunk) => Buffer.from(chunk));
await writeFile("speech.mp3", Buffer.concat(chunks));
```

### ElevenLabs SDK, single request — Python · elevenlabs

Client: ElevenLabs SDK · Mode: Request · Language: Python

Set the ElevenLabs SDK base URL to `https://api.allmodels.io/el` and convert complete text to an audio file. [ElevenLabs TTS docs](https://allmodels.io/docs/elevenlabs/text-to-speech).

```python
import os
from elevenlabs.client import ElevenLabs

client = ElevenLabs(
    api_key=os.environ["ALLMODELS_API_KEY"],
    base_url="https://api.allmodels.io/el",
)

audio = client.text_to_speech.convert(
    "eve",
    text="Your order has shipped. It arrives tomorrow.",
    model_id="grok/grok-tts",
    output_format="mp3_44100_128",
)

with open("speech.mp3", "wb") as output:
    for chunk in audio:
        output.write(chunk)
```

## Use the client your team already knows

### OpenAI-compatible

Endpoint: `https://api.allmodels.io/oai`

Already using the OpenAI SDK? Set its base URL to AllModels and keep calling `audio.speech.create`, now with an AllModels model ID. Streaming and single requests both work.

- [Read the OpenAI TTS docs](https://allmodels.io/docs/openai/text-to-speech)

### ElevenLabs-compatible

Endpoint: `https://api.allmodels.io/el`

Already using the ElevenLabs SDK? Set its base URL to AllModels and keep using its convert, stream and realtime methods, now with an AllModels model ID.

- [Read the ElevenLabs TTS docs](https://allmodels.io/docs/elevenlabs/text-to-speech)

## Real-time TTS API basics

### What is a unified TTS API?

A unified TTS API gives applications one integration surface for multiple text-to-speech models. With AllModels, the chosen model ID determines the route while authentication and the core request flow remain consistent.

### Does AllModels support real-time audio?

Yes. The native interface streams over WebSocket at `/v1/tts`, the ElevenLabs Python SDK streams text in over a compatible WebSocket, and both SDKs can stream audio back over HTTP. Streaming support varies by model.

### Can I use every provider feature?

Yes. Common settings use the standard fields, and any provider-specific setting, such as voice settings, goes in `provider_options` and is passed directly to the provider.

### Is there an OpenRouter for text-to-speech?

Yes. AllModels works like OpenRouter for voice: one API key and one endpoint give you text-to-speech models from multiple providers, selected by `provider/model` ID. It also accepts the official OpenAI and ElevenLabs SDKs, so existing code only needs a new base URL and key.

### How is a TTS aggregator API different from an open-source abstraction library?

An open-source abstraction library runs inside your application and still needs your own account, API key and billing with every provider it wraps. An aggregator API such as AllModels is a hosted service: one key and one prepaid balance cover the whole [TTS catalogue](https://allmodels.io/models?type=tts), and you call it with the OpenAI or ElevenLabs SDK you already use, or over a WebSocket.

### How do I compare providers?

Browse the [TTS catalogue](https://allmodels.io/models?type=tts) to compare available models, routes, pricing, languages, voices, and API examples before changing the model ID in your application.

## One integration in three steps

1. **Choose a model.** Pick a TTS model from the [live catalogue](https://allmodels.io/models?type=tts) by its `provider/model` ID.
2. **Use one API key.** Authenticate with AllModels instead of a separate key for every provider.
3. **Stream or generate.** Stream over WebSocket for live audio, or request a complete file over HTTP.

## Start with one TTS integration.

Choose a model now and keep the freedom to change it later.

- [Start free](https://dash.allmodels.io/signup)
- [Browse TTS models](https://allmodels.io/models?type=tts)
- [Read the AllModels documentation](https://allmodels.io/docs)
- [View the canonical HTML guide](https://allmodels.io/guides/universal-tts-api)
