> 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.

# Trasmetti dialoghi in tempo reale

Il WebSocket Text to Dialogue (`/v1/text-to-dialogue/stream-input`) mantiene aperta una singola connessione mentre invii battute di dialogo e ricevi chunk audio codificati in base64. È pensato solo per i modelli di dialogo **Eleven v3** e **Eleven v4** (`model_id` deve iniziare con `eleven_v3` o `eleven_v4`).

> **Note**
>
> Questa guida tratta il WebSocket **Text to Dialogue**. Per **Flash**, **Multilingual v2** o altri
> modelli TTS non v3, usa il [WebSocket TTS in tempo reale ](/docs/it/eleven-api/guides/how-to/websockets/realtime-tts). Per un riepilogo affiancato di
> entrambi i protocolli, consulta [WebSocket Text to Speech e Text to Dialogue ](/docs/it/eleven-api/guides/how-to/websockets/tts-vs-ttd-websockets).

## Requisiti

* Un account ElevenLabs con una chiave API ([autenticazione](/docs/it/api-reference/authentication)).
* La chiave API deve disporre delle autorizzazioni `Text to Speech`.
* Python o Node.js installato sul tuo computer.

## Configurazione

**`Python`**

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

**`TypeScript`**

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

Crea un file `.env`:

**`.env`**

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

Scegli un **ID voce** dalla [Voice Library](https://elevenlabs.io/voice-library). Gli esempi seguenti usano `eleven_v4_turbo`, che consente **una** voce registrata per connessione.

## Apri il WebSocket

Connettiti a `wss://api.elevenlabs.io/v1/text-to-dialogue/stream-input` con parametri query quali `model_id` e `output_format`. Puoi inviare la chiave API nell'header `xi-api-key` oppure nel primo messaggio JSON (mostrata qui nel body per usare lo stesso schema in tutte le lingue).

**`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" });
```

## Registra le voci e trasmetti il testo

Invia un **primo messaggio** che includa `voices` (obbligatorio) e `xi_api_key` se non hai impostato l'header `xi-api-key`. Quindi invia uno o più frame con `inputs`: ogni elemento contiene `text`, `voice_id` e, facoltativamente, `new_turn`.

Il server memorizza il testo nel buffer finché non ha abbastanza contesto (circa **40 caratteri** e **8 parole**), quindi invia chunk `audio`. I campi di risposta usano lo stile **snake\_case** (ad esempio `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` invia il testo rimasto nel buffer, invia l'audio rimanente e poi un frame finale con `is_final: true` prima della chiusura della connessione. Per **mantenere aperta la connessione** tra una battuta e l'altra, ometti `close_socket` finché la sessione non termina; usa `flush` per forzare l'audio per buffer più brevi senza chiudere.

## Esegui lo script

**`Python`**

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

**`TypeScript`**

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

Dovresti ottenere un file MP3 in `output/` (con il nome file dell'esempio precedente).

## Note sul comportamento

### Buffering

A differenza di `chunk_length_schedule` del WebSocket TTS, lo streaming dei dialoghi usa una **soglia fissa del server** (conteggio di caratteri e parole) prima del primo audio parziale. Se invii battute brevi e senti ritardi, raggruppa un po' più testo per ogni frame `inputs` oppure invia `flush: true` per forzare la generazione senza chiudere il socket.

### Turni e voci

Imposta `new_turn: true` quando un interlocutore termina il proprio turno, così la prosodia viene reimpostata correttamente. Anche modificare `voice_id` tra le voci `inputs` avvia un nuovo turno. Con `eleven_v4_turbo`, registra **esattamente una** voce in `voices`; `eleven_v4` supporta fino a **10** voci registrate.

### Inattività

Se il server non riceve **nessun messaggio dal client per 20 secondi**, la connessione termina. Invia `{"keep_alive": true}` per reimpostare il timer senza sintetizzare audio.

### Concorrenza

Ogni connessione aperta mantiene una sessione di dialogo finché resta aperta, attinta da un pool dedicato separato dal limite di concorrenza standard del tuo piano. L'audio generato tramite la connessione non viene conteggiato nella concorrenza standard. Consulta [Concorrenza di Text to Dialogue](/docs/it/overview/models#text-to-dialogue-concurrency).

### Allineamento

Aggiungi `sync_alignment=true` alla query string per ricevere oggetti `alignment` (array di temporizzazione in snake\_case) nei chunk quando disponibili. Consulta il [Riferimento API](/docs/it/api-reference/text-to-dialogue/ttd-websocket).

## Passaggi successivi

#### [WebSocket TTS e TTD](/docs/it/eleven-api/guides/how-to/websockets/tts-vs-ttd-websockets)

Scegli il WebSocket giusto e confronta le strutture dei messaggi.

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

Parametri query, schemi dei messaggi ed esempi.

#### [Trasmetti dialoghi (HTTP)](/docs/it/api-reference/text-to-dialogue/stream)

Quando il testo completo della richiesta è disponibile senza un WebSocket.

#### [WebSocket TTS in tempo reale](/docs/it/eleven-api/guides/how-to/websockets/realtime-tts)

Streaming non v3 a voce singola tramite WebSocket.