> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Stream dialogen realtime

De Text to Dialogue-WebSocket (`/v1/text-to-dialogue/stream-input`) houdt één verbinding open terwijl je dialoogregels verstuurt en base64-gecodeerde audiochunks ontvangt. Deze is uitsluitend bedoeld voor dialoogmodellen van **Eleven v3** en **Eleven v4** (`model_id` moet beginnen met `eleven_v3` of `eleven_v4`).

> **Note**
>
> Deze handleiding behandelt de **Text to Dialogue**-WebSocket. Gebruik voor **Flash**, **Multilingual v2** of andere
> niet-v3 TTS-modellen de [Realtime TTS-WebSocket ](/docs/nl/eleven-api/guides/how-to/websockets/realtime-tts). Zie voor een overzicht naast elkaar van
> beide protocollen [Text to Speech- en Text to Dialogue-WebSockets ](/docs/nl/eleven-api/guides/how-to/websockets/tts-vs-ttd-websockets).

## Vereisten

* Een ElevenLabs-account met een API-sleutel ([authenticatie](/docs/nl/api-reference/authentication)).
* De API-sleutel moet machtigingen voor `Text to Speech` hebben.
* Python of Node.js geïnstalleerd op je computer.

## Instellen

**`Python`**

```python Python
pip install python-dotenv websockets
```

**`TypeScript`**

```typescript TypeScript
npm install dotenv ws
npm install @types/dotenv @types/ws --save-dev
```

Maak een `.env`-bestand:

**`.env`**

```bash .env
ELEVENLABS_API_KEY=your_elevenlabs_api_key_here
```

Kies een **stem-ID** uit de [Voice Library](https://elevenlabs.io/voice-library). In de onderstaande voorbeelden wordt `eleven_v4_turbo` gebruikt, waarmee je **één** geregistreerde stem per verbinding kunt gebruiken.

## Open de WebSocket

Maak verbinding met `wss://api.elevenlabs.io/v1/text-to-dialogue/stream-input` met queryparameters zoals `model_id` en `output_format`. Je kunt de API-sleutel in de header `xi-api-key` of in het eerste JSON-bericht versturen (hier in de body weergegeven voor één consistent patroon in alle talen).

**`text-to-dialogue-websocket.py`**

```python text-to-dialogue-websocket.py
import asyncio
import base64
import json
import os

from dotenv import load_dotenv
import websockets

load_dotenv()
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
VOICE_ID = "21m00Tcm4TlvDq8ikWAM"
MODEL_ID = "eleven_v4_turbo"

URI = (
    "wss://api.elevenlabs.io/v1/text-to-dialogue/stream-input"
    f"?model_id={MODEL_ID}&output_format=mp3_44100_128"
)
```

**`text-to-dialogue-websocket.ts`**

```typescript text-to-dialogue-websocket.ts
import * as dotenv from "dotenv";
import * as fs from "node:fs";
import WebSocket from "ws";

dotenv.config();
const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;
const voiceId = "21m00Tcm4TlvDq8ikWAM";
const modelId = "eleven_v4_turbo";

const uri = `wss://api.elevenlabs.io/v1/text-to-dialogue/stream-input?model_id=${modelId}&output_format=mp3_44100_128`;
const websocket = new WebSocket(uri);

const outputDir = "./output";
try {
  fs.accessSync(outputDir, fs.constants.R_OK | fs.constants.W_OK);
} catch {
  fs.mkdirSync(outputDir);
}
const writeStream = fs.createWriteStream(`${outputDir}/dialogue-ws.mp3`, { flags: "a" });
```

## Registreer stemmen en stream tekst

Stuur een **eerste bericht** met `voices` (verplicht) en `xi_api_key` als je de header `xi-api-key` niet hebt ingesteld. Stuur vervolgens een of meer frames met `inputs`: elk item heeft `text`, `voice_id` en optioneel `new_turn`.

De server buffert tekst totdat er voldoende context is (ongeveer **40 tekens** en **8 woorden**) en verstuurt daarna `audio`-chunks. Responsevelden gebruiken **snake\_case** (bijvoorbeeld `is_final`).

**`text-to-dialogue-websocket.py`**

```python text-to-dialogue-websocket.py
async def stream_dialogue():
    async with websockets.connect(URI) as websocket:
        await websocket.send(
            json.dumps(
                {
                    "voices": [VOICE_ID],
                    "xi_api_key": ELEVENLABS_API_KEY,
                }
            )
        )

        line = (
            "This is a longer line of dialogue used to exceed the minimum buffer so the model "
            "starts generating streamed audio for the registered voice. "
        )
        await websocket.send(
            json.dumps(
                {
                    "inputs": [
                        {"text": line, "voice_id": VOICE_ID, "new_turn": False},
                    ],
                }
            )
        )

        await websocket.send(json.dumps({"close_socket": True}))

        os.makedirs("output", exist_ok=True)
        out_path = "output/dialogue-ws.mp3"
        with open(out_path, "wb") as audio_file:
            while True:
                raw = await websocket.recv()
                msg = json.loads(raw)
                if msg.get("error"):
                    raise RuntimeError(msg)
                if msg.get("audio"):
                    audio_file.write(base64.b64decode(msg["audio"]))
                if msg.get("is_final"):
                    break
        print(f"Wrote {out_path}")


asyncio.run(stream_dialogue())
```

**`text-to-dialogue-websocket.ts`**

```typescript text-to-dialogue-websocket.ts
websocket.on("open", () => {
  websocket.send(
    JSON.stringify({
      voices: [voiceId],
      xi_api_key: ELEVENLABS_API_KEY,
    })
  );

  const line =
    "This is a longer line of dialogue used to exceed the minimum buffer so the model starts generating streamed audio for the registered voice. ";

  websocket.send(
    JSON.stringify({
      inputs: [{ text: line, voice_id: voiceId, new_turn: false }],
    })
  );

  websocket.send(JSON.stringify({ close_socket: true }));
});

websocket.on("message", (data) => {
  const msg = JSON.parse(data.toString());
  if (msg.error) {
    console.error(msg);
    return;
  }
  if (msg.audio) {
    writeToLocal(msg.audio, writeStream);
  }
});

function writeToLocal(base64str: string, stream: fs.WriteStream) {
  stream.write(Buffer.from(base64str, "base64"));
}

websocket.on("close", () => {
  writeStream.end();
});
```

`close_socket` verstuurt alle gebufferde tekst, de resterende audio en vervolgens een laatste frame met `is_final: true` voordat de verbinding wordt gesloten. Als je de verbinding **open wilt houden** tussen regels, laat je `close_socket` weg tot de sessie eindigt; gebruik `flush` om audio voor kortere buffers te forceren zonder te sluiten.

## Voer het script uit

**`Python`**

```python Python
python text-to-dialogue-websocket.py
```

**`TypeScript`**

```typescript TypeScript
npx tsx text-to-dialogue-websocket.ts
```

Je zou een MP3-bestand moeten krijgen in `output/` (met de bestandsnaam uit het bovenstaande voorbeeld).

## Opmerkingen over gedrag

### Bufferen

In tegenstelling tot de TTS-WebSocket `chunk_length_schedule` gebruikt dialoogstreaming een **vaste serverdrempel** (aantal tekens en woorden) vóór de eerste gedeeltelijke audio. Als je korte regels verstuurt en vertraging hoort, bundel dan iets meer tekst per `inputs`-frame of stuur `flush: true` om generatie te forceren zonder de socket te sluiten.

### Beurten en stemmen

Stel `new_turn: true` in wanneer een spreker een beurt afrondt, zodat de prosodie netjes wordt gereset. Het wijzigen van `voice_id` tussen `inputs`-items start ook een nieuwe beurt. Met `eleven_v4_turbo` registreer je **precies één** stem in `voices`; `eleven_v4` ondersteunt maximaal **10** geregistreerde stemmen.

### Inactiviteit

Als de server **20 seconden geen clientbericht ontvangt**, wordt de verbinding beëindigd. Stuur `{"keep_alive": true}` om de timer te resetten zonder audio te synthetiseren.

### Gelijktijdigheid

Elke open verbinding houdt één dialoogsessie vast zolang deze open blijft en komt uit een afzonderlijke pool, los van de standaardlimiet voor gelijktijdigheid van je abonnement. Audio die via de verbinding wordt gegenereerd, telt niet mee voor de standaardgelijktijdigheid. Zie [gelijktijdigheid van Text to Dialogue](/docs/nl/overview/models#text-to-dialogue-concurrency).

### Uitlijning

Voeg `sync_alignment=true` toe aan de querystring om, waar beschikbaar, op chunks `alignment`-objecten te ontvangen (timingarrays in snake\_case). Zie de [API-referentie](/docs/nl/api-reference/text-to-dialogue/ttd-websocket).

## Volgende stappen

#### [TTS- versus TTD-WebSockets](/docs/nl/eleven-api/guides/how-to/websockets/tts-vs-ttd-websockets)

Kies de juiste WebSocket en vergelijk berichtstructuren.

#### [Text to Dialogue-WebSocket (API)](/docs/nl/api-reference/text-to-dialogue/ttd-websocket)

Queryparameters, berichtschema's en voorbeelden.

#### [Dialoog streamen (HTTP)](/docs/nl/api-reference/text-to-dialogue/stream)

Wanneer de volledige requesttekst beschikbaar is zonder WebSocket.

#### [Realtime TTS-WebSocket](/docs/nl/eleven-api/guides/how-to/websockets/realtime-tts)

Niet-v3-streaming met één stem via WebSockets.