> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pipecat.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# HeyGen Text-to-Speech

> TTS with HeyGenTTSService and HeyGenHttpTTSService: HeyGen Voice models, word timestamps, and professional voice clones.

## Overview

`HeyGenTTSService` streams text to HeyGen Voice over a WebSocket and plays the audio as it arrives, with word-level timestamps so an interruption commits only the words actually spoken. `HeyGenHttpTTSService` streams raw PCM audio from HeyGen's HTTP endpoint, one request per sentence, and also serves professional voice clones.

> [card] [HeyGen TTS API Reference](https://reference-server.pipecat.ai/en/latest/api/pipecat.services.heygen.tts.html)
>
> Pipecat's API methods for HeyGen TTS integration

> [card] [Example Implementation](https://github.com/pipecat-ai/pipecat/blob/main/examples/voice/voice-heygen.py)
>
> Complete example with the WebSocket service

> [card] [HTTP Example](https://github.com/pipecat-ai/pipecat/blob/main/examples/voice/voice-heygen-http.py)
>
> Complete example with the HTTP service

> [card] [HeyGen Documentation](https://developers.heygen.com/docs/voices/heygen-voice-speech)
>
> Official HeyGen Voice speech documentation

## Installation

```bash theme={null}
uv add pipecat-ai
```

HeyGen TTS needs no extra dependencies. The `heygen` extra is only for the [HeyGen video avatar](https://docs.pipecat.ai/api-reference/server/services/video/heygen.md).

## Prerequisites

### HeyGen Account Setup

Before using HeyGen TTS, you need:

1. **HeyGen Account**: Sign up at [HeyGen](https://www.heygen.com/)
2. **API Key**: Generate an API key from your account
3. **Voice Selection**: Choose a public voice ID, or use an instant or professional clone from your workspace

### Required Environment Variables

* `HEYGEN_API_KEY`: Your HeyGen API key for authentication

## Configuration

### HeyGenTTSService

**api\_key** `str` *required*

HeyGen API key.

**url** `str` (default: wss\://api.heygen.com)

HeyGen WebSocket base URL.

**sample\_rate** `int | None` (default: None)

Output audio sample rate in Hz. When `None`, uses the pipeline's sample rate.

**enable\_ssml\_parsing** `bool | None` (default: None)

Whether `<break time="1s" />` tags become pauses. Without it, HeyGen closes
the WebSocket when the text contains a break tag.

**enable\_logging** `bool | None` (default: None)

Whether HeyGen stores a copy of the audio and text. When `None`, HeyGen stores
them.

**end\_user\_id** `str | None` (default: None)

Your identifier for the end user, recorded with HeyGen's usage for
attribution.

**text\_aggregation\_mode** `TextAggregationMode | None` (default: None)

How incoming text is aggregated before synthesis. `TextAggregationMode.TOKEN`
streams LLM tokens as they arrive, and HeyGen generates at each sentence end.

**settings** `HeyGenTTSService.Settings` (default: None)

Runtime-configurable settings. See [Settings](#settings) below.

### Settings

Runtime-configurable settings passed via the `settings` constructor argument using `HeyGenTTSService.Settings(...)`. These can be updated mid-conversation with `TTSUpdateSettingsFrame`; any change reconnects the WebSocket. See [Service Settings](https://docs.pipecat.ai/pipecat/fundamentals/service-settings.md) for details.

| Parameter | Type | Default | Description |
| - | - | - | - |
| `model` | `str` | `"heygen-voice-1-turbo"` | HeyGen Voice model: `heygen-voice-1`, `heygen-voice-1-turbo`, or `heygen-voice-1-turbo-free`. *(Inherited.)* |
| `voice` | `str` | Nadine's public voice ID | HeyGen voice ID: a public voice or an instant clone in your workspace. *(Inherited.)* |
| `language` | `Language \| str` | `None` | Language of the text. When `None`, HeyGen detects it. *(Inherited.)* |
| `apply_text_normalization` | `"auto" \| "on" \| "off"` | `None` | Text normalization mode. When `None`, HeyGen uses `"auto"`. |
| `expressiveness_boost` | `float` | `None` | Voice expressiveness from 0.0 to 1.0. When `None`, HeyGen chooses it. |

### HeyGenHttpTTSService

**api\_key** `str` *required*

HeyGen API key.

**aiohttp\_session** `aiohttp.ClientSession` *required*

Shared aiohttp session for HTTP requests.

**base\_url** `str` (default: [https://api.heygen.com](https://api.heygen.com))

HeyGen API base URL.

**sample\_rate** `int | None` (default: None)

Output audio sample rate in Hz. When `None`, uses the pipeline's sample rate.

**settings** `HeyGenHttpTTSService.Settings` (default: None)

Runtime-configurable settings. See [HTTP Settings](#http-settings) below.

### HTTP Settings

Passed via `HeyGenHttpTTSService.Settings(...)` and updatable with `TTSUpdateSettingsFrame`.

| Parameter | Type | Default | Description |
| - | - | - | - |
| `model` | `str` | `"heygen-voice-1-turbo"` | HeyGen Voice model: `heygen-voice-1`, `heygen-voice-1-turbo`, or `heygen-voice-1-turbo-free`. *(Inherited.)* |
| `voice` | `str` | Nadine's public voice ID | HeyGen voice ID: a public voice, or an instant or professional clone. A professional clone needs `heygen-voice-1`. *(Inherited.)* |
| `language` | `Language \| str` | `None` | Language of the text. When `None`, HeyGen detects it. *(Inherited.)* |

## Usage

### Basic Setup

```python theme={null}
import os

from pipecat.services.heygen.tts import HeyGenTTSService

tts = HeyGenTTSService(
    api_key=os.getenv("HEYGEN_API_KEY"),
    settings=HeyGenTTSService.Settings(voice="your-voice-id"),
)
```

### Professional Voice Clones

Only `HeyGenHttpTTSService` serves professional voice clones, and they need the `heygen-voice-1` model:

```python theme={null}
import os

import aiohttp

from pipecat.services.heygen.tts import HeyGenHttpTTSService

async with aiohttp.ClientSession() as session:
    tts = HeyGenHttpTTSService(
        api_key=os.getenv("HEYGEN_API_KEY"),
        aiohttp_session=session,
        settings=HeyGenHttpTTSService.Settings(
            model="heygen-voice-1",
            voice="your-professional-clone-id",
        ),
    )
```

## Notes

* **Chinese and Japanese**: Set `language` on `HeyGenTTSService` to get per-character word timing. Without it, the service has no spaces to split words on, and the turn's text frames arrive only when its audio ends.
* **Turbo Free**: `heygen-voice-1-turbo-free` runs on shared capacity with no availability guarantee. When capacity is full, HeyGen refuses the turn and the service pushes an `ErrorFrame`. To keep the bot speaking, put a paid model behind it in a [`ServiceSwitcher`](https://docs.pipecat.ai/api-reference/server/composite-services/service-switcher) with `ServiceSwitcherStrategyFailover`.

## Event Handlers

`HeyGenTTSService` supports the standard [service connection events](https://docs.pipecat.ai/api-reference/server/events/service-events.md):

| Event | Description |
| - | - |
| `on_connected` | Connected to HeyGen WebSocket |
| `on_disconnected` | Disconnected from HeyGen WebSocket |
| `on_connection_error` | WebSocket connection error occurred |

```python theme={null}
@tts.event_handler("on_connected")
async def on_connected(service):
    print("Connected to HeyGen")
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.