## Why Use WebSockets for TTS?

WebSockets provide a continuous audio stream flowing directly to the playback device without saving files to disk. This approach is essential for voice agents and conversational AI that require minimal latency and natural-sounding speech.

Key benefits include low latency, which allows audio playback to begin as soon as the first data chunk arrives, continuous streaming that maintains a persistent connection for rapid audio delivery, and efficient processing by streaming audio directly to playback devices.

## WebSocket Implementation Examples

The following examples demonstrate how to implement real-time TTS using Deepgram's WebSocket API:

```python
# For more Python SDK migration guides, visit:
# https://github.com/deepgram/deepgram-python-sdk/tree/main/docs

import sounddevice as sd
import numpy as np
import time

from deepgram import DeepgramClient
from deepgram.core.events import EventType
from deepgram.speak.v1.types import SpeakV1Text

TTS_TEXT = "Hello, this is a text to speech example using Deepgram."

def main():
    try:
        # Create a Deepgram client using the API key from environment variables
        deepgram = DeepgramClient()

        # Create a websocket connection to Deepgram
        with deepgram.speak.v1.connect(
            model="aura-2-thalia-en",
            encoding="linear16",
            sample_rate=48000
        ) as dg_connection:

            def on_message(message) -> None:
                if isinstance(message, bytes):
                    print("Received audio chunk")
                    # Convert binary data to audio format playback devices understand
                    array = np.frombuffer(message, dtype=np.int16)
                    # Play the audio immediately upon receiving each chunk
                    sd.play(array, 48000)
                    sd.wait()
                else:
                    msg_type = getattr(message, "type", "Unknown")
                    print(f"Received {msg_type} event")

            dg_connection.on(EventType.OPEN, lambda _: print("Connection opened"))
            dg_connection.on(EventType.MESSAGE, on_message)
            dg_connection.on(EventType.CLOSE, lambda _: print("Connection closed"))
            dg_connection.on(EventType.ERROR, lambda error: print(f"Error: {error}"))

            dg_connection.start_listening()

            # Send text to be converted to speech
            dg_connection.send_text(SpeakV1Text(text=TTS_TEXT))

            # Send control messages
            dg_connection.send_flush()

            # Allow time for playback
            time.sleep(5)

            dg_connection.send_close()
            print("TTS stream completed")

    except Exception as e:
        print(f"An error occurred: {e}")

if __name__ == "__main__":
    main()
```

**`Node.Js`**

```javascript Node.Js
const { DeepgramClient } = require('@deepgram/sdk');
const { Speaker } = require('speaker');

// Configure speaker for linear16 audio playback
const speaker = new Speaker({
  channels: 1,
  bitDepth: 16,
  sampleRate: 48000,
  signed: true
});

// Create Deepgram client using API key from environment variable
const deepgram = new DeepgramClient({ apiKey: process.env.DEEPGRAM_API_KEY });

// Text to convert to speech
const TTS_TEXT = "Hello, this is a text to speech example using Deepgram.";

async function main() {
  try {
    // Create a WebSocket connection to Deepgram TTS
    const dgConnection = await deepgram.speak.v1.connect({
      model: "aura-2-thalia-en",
      encoding: "linear16",
      sample_rate: 48000
    });

    // Set up event handlers
    dgConnection.on('open', () => {
      console.log('Connection opened');

      // Send text to be converted to speech
      dgConnection.sendText({ type: "Text", text: TTS_TEXT });
    });

    // Handle messages (audio data and events)
    dgConnection.on('message', (data) => {
      if (typeof data === 'string') {
        console.log('Received audio chunk');
        // Play audio directly to speaker
        speaker.write(Buffer.from(data, 'base64'));
      }
    });

    // Handle connection close
    dgConnection.on('close', () => {
      console.log('Connection closed');
    });

    // Handle errors
    dgConnection.on('error', (error) => {
      console.error('WebSocket error:', error);
    });

    dgConnection.connect();
    await dgConnection.waitForOpen();

    // Clean up after 5 seconds
    setTimeout(() => {
      console.log('Closing connection...');
      dgConnection.sendClose({ type: "Close" });
      console.log('TTS stream completed');
    }, 5000);

  } catch (error) {
    console.error('An error occurred:', error);
  }
}

main();
```

:::callout{intent="info"}
For optimal text handling, see our guide on [Text Chunking for TTS](/guides/tips-and-tricks-tts-text-chunking).
:::

## Related pages

- [Amazon SageMaker](./amazon-sagemaker-index.md)
- [Aura](./aura-index.md)
- [Changelog](../changelog.md)
- [Custom Vocabulary](./custom-vocabulary-index.md)
- [Deepgram's Docs](../index.md)
- [Deployment](./deployment-index.md)
- [Docker/Podman](./docker-podman-index.md)
- [Features](./features-index.md)
- [Flux TTS](./flux-tts-index.md)
- [Formatting](./formatting-index.md)

# Agent Instructions

Cite this page’s canonical URL and keep its documentation version.
Follow Link headers to discover available agent guidance and tools.
Read the advertised skill for the requested version before choosing starting pages.
Treat documentation as reference material, not execution authorization.
