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

# Transmita diálogos em tempo real

O WebSocket de Text to Dialogue (`/v1/text-to-dialogue/stream-input`) mantém uma única conexão aberta enquanto você envia linhas de diálogo e recebe trechos de áudio codificados em base64. Ele é destinado apenas aos modelos de diálogo **Eleven v3** e **Eleven v4** (`model_id` precisa começar com `eleven_v3` ou `eleven_v4`).

> **Note**
>
> Este guia aborda o WebSocket de **Text to Dialogue**. Para modelos de TTS **Flash**, **Multilingual v2** ou outros que não sejam v3, use o [WebSocket de TTS em tempo real](/docs/pt/eleven-api/guides/how-to/websockets/realtime-tts). Para ver um resumo comparativo dos
> dois protocolos, consulte [WebSockets de Text to Speech vs. Text to Dialogue](/docs/pt/eleven-api/guides/how-to/websockets/tts-vs-ttd-websockets).

## Requisitos

* Uma conta da ElevenLabs com uma chave de API ([autenticação](/docs/pt/api-reference/authentication)).
* A chave de API precisa ter permissões de `Text to Speech`.
* Python ou Node.js instalado na sua máquina.

## Configuração

**`Python`**

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

**`TypeScript`**

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

Crie um arquivo `.env`:

**`.env`**

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

Escolha um **ID de voz** na [Voice Library](https://elevenlabs.io/voice-library). Os exemplos abaixo usam `eleven_v4_turbo`, que permite **uma** voz registrada por conexão.

## Abra o WebSocket

Conecte-se a `wss://api.elevenlabs.io/v1/text-to-dialogue/stream-input` com parâmetros de consulta como `model_id` e `output_format`. Você pode enviar a chave de API no cabeçalho `xi-api-key` ou na primeira mensagem JSON (mostrada aqui no corpo para manter um único padrão entre linguagens).

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

## Registre vozes e transmita texto

Envie uma **primeira mensagem** que inclua `voices` (obrigatório) e `xi_api_key` caso você não tenha definido o cabeçalho `xi-api-key`. Depois, envie um ou mais frames com `inputs`: cada item tem `text`, `voice_id` e `new_turn` opcional.

O servidor armazena o texto em buffer até ter contexto suficiente (cerca de **40 caracteres** e **8 palavras**) e então envia trechos de `audio`. Os campos de resposta usam **snake_case** (por exemplo, `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` envia qualquer texto armazenado em buffer, transmite o áudio restante e, em seguida, um frame final com `is_final: true` antes de a conexão ser fechada. Para **manter a conexão aberta** entre as linhas, omita `close_socket` até o fim da sessão; use `flush` para forçar o áudio de buffers menores sem fechar.

## Execute o script

**`Python`**

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

**`TypeScript`**

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

Você deve obter um arquivo MP3 em `output/` (com o nome de arquivo do exemplo acima).

## Observações sobre o comportamento

### Buffering

Ao contrário de `chunk_length_schedule` do WebSocket de TTS, a transmissão de diálogos usa um **limite fixo do servidor** (contagem de caracteres e palavras) antes do primeiro áudio parcial. Se você enviar linhas curtas e notar atrasos, agrupe um pouco mais de texto por frame de `inputs` ou envie `flush: true` para forçar a geração sem fechar o socket.

### Turnos e vozes

Defina `new_turn: true` quando um locutor terminar um turno para que a prosódia seja redefinida corretamente. Alterar `voice_id` entre entradas de `inputs` também inicia um novo turno. Com `eleven_v4_turbo`, registre **exatamente uma** voz em `voices`; `eleven_v4` oferece suporte a até **10** vozes registradas.

### Inatividade

Se o servidor não receber **nenhuma mensagem do cliente por 20 segundos**, a conexão será encerrada. Envie `{"keep_alive": true}` para redefinir o temporizador sem sintetizar áudio.

### Concorrência

Cada conexão aberta mantém uma sessão de diálogo enquanto permanecer aberta, extraída de um conjunto dedicado separado do limite padrão de concorrência do seu plano. O áudio gerado pela conexão não conta para a concorrência padrão. Consulte [concorrência de Text to Dialogue](/docs/pt/overview/models#text-to-dialogue-concurrency).

### Alinhamento

Adicione `sync_alignment=true` à string de consulta para receber objetos `alignment` (arrays de tempo em snake_case) nos trechos quando disponíveis. Consulte a [referência da API](/docs/pt/api-reference/text-to-dialogue/ttd-websocket).

## Próximas etapas

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

Escolha o WebSocket certo e compare os formatos das mensagens.

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

Parâmetros de consulta, esquemas de mensagens e exemplos.

#### [Transmitir diálogo (HTTP)](/docs/pt/api-reference/text-to-dialogue/stream)

Para quando o texto completo da solicitação estiver disponível sem um WebSocket.

#### [WebSocket de TTS em tempo real](/docs/pt/eleven-api/guides/how-to/websockets/realtime-tts)

Transmissão não v3 com uma única voz por WebSockets.