Skip to main content
Pipecat provides two HeyGen integrations that plug into different layers of your pipeline. The right choice depends on who owns the room your end user joins. This page covers both integrations, when to use each, and how they connect to LiveAvatar.
This page assumes you already have a working Pipecat pipeline. If not, start with the Pipecat quickstart, or pick a different integration path.
Upstream Pipecat plugin references:

Prerequisites

  • A LiveAvatar account and API key. Sign up at app.liveavatar.com.
  • A working Pipecat pipeline with your own STT, LLM, and TTS services.

Installation

Both integrations are available in the pipecat-ai plugin for HeyGen:

Configuration

The integrations read your LiveAvatar key from the environment:
You can also pass api_key="..." directly when constructing either class.

Two integrations, two architectures

Pipecat exposes LiveAvatar in two places in the pipeline. The choice comes down to who shares the room with the end user.
  • HeyGenTransport — the Pipecat bot, the HeyGen avatar, and the end user all join the same LiveKit room as participants.
  • HeyGenVideoService — only the HeyGen avatar and the end user share a room. The Pipecat bot sits outside it as invisible plumbing, relaying audio up to LiveAvatar and avatar frames back down through its own transport.
In both cases your pipeline still owns STT, LLM, and TTS. LiveAvatar only renders the avatar.

HeyGenTransport — LiveAvatar owns the room

The transport joins the bot, avatar, and end user into a LiveKit room that LiveAvatar manages. Your pipeline runs STT → LLM → TTS as usual; synthesized audio is forwarded to the avatar, which lip-syncs and publishes audio + video into the same room. The end user subscribes to the avatar directly. No separate output transport — transport.output() ships TTS audio straight to LiveAvatar.

Required fields

HeyGenTransport defaults to the legacy Streaming API. To use LiveAvatar you must set service_type=ServiceType.LIVE_AVATAR and pass a matching LiveAvatarNewSessionRequest. session_request and service_type must match: LiveAvatarNewSessionRequest pairs with ServiceType.LIVE_AVATAR.

Minimal example

Pipeline placement

No HeyGenVideoService node. TTS audio is consumed directly by transport.output():
Avatar video is subscribed by the client SDK directly from LiveKit and does not flow through the Pipecat pipeline.

Notes

  • Don’t mix with HeyGenVideoService. Two integrations in the same pipeline = duplicate session and WebSocket. Pick one.
  • Sample rate is fixed at 24 kHz internally; the transport resamples automatically. Overriding audio_out_sample_rate does not propagate.
  • Client kick-off: use on_client_connected, not a participant-join handler. The avatar joins as participant_id == "heygen" and is filtered, so only real users trigger the event.

HeyGenVideoService — your transport owns the room

The video service runs as a node inside your pipeline. Your bot keeps its own transport (Daily, LiveKit, WebRTC, etc.) and talks to the end user there. Inside the pipeline, TTS audio is sent up to LiveAvatar, which streams avatar audio + video frames back into the pipeline; the bot then republishes those frames through its transport. Internally the service still uses a HeyGen-managed LiveKit room for inbound avatar frames and a WebSocket for control — both are abstracted away. Your transport stays separate and is the only one your end user joins.

Required fields

HeyGenVideoService defaults to the legacy Streaming API. To use LiveAvatar you must set service_type=ServiceType.LIVE_AVATAR and pass a LiveAvatarNewSessionRequest. LiveAvatarNewSessionRequest only requires avatar_id. Other fields (mode, video_settings, is_sandbox, avatar_persona, livekit_config) are optional.

Minimal example

Pipeline placement

HeyGenVideoService must sit after TTS and before transport.output():
It consumes TTSAudioRawFrame and emits OutputAudioRawFrame + OutputImageRawFrame downstream.

Picking one

  • Use HeyGenTransport if you do not already run a transport, want the simplest path to a working avatar bot, and are fine with LiveAvatar managing the LiveKit room.
  • Use HeyGenVideoService if you already run Daily, LiveKit, or another transport; need the bot in the media path for recording, fan-out, or custom routing; or want avatar video to share the same room as everything else your bot publishes.

Examples

The pipecat-ai/pipecat repo ships runnable examples for both integrations under examples/video-avatar/. Both use sandbox mode, so they run end-to-end without billing.

1. Clone and install

2. Configure API keys

Create .env at the repo root:

3. Run examples

HeyGenTransport

LiveAvatar owns the LiveKit room. The script prints a room URL — connect a LiveKit client (e.g. meet.livekit.io) using the livekit_url and client token from the logs to talk to the bot.

HeyGenVideoService

Avatar bolted onto a separate transport. Pick webrtc for a built-in browser-based test, or daily to use Daily. WebRTC (easiest local test — open the printed URL, default http://localhost:7860):
Daily:
Both examples set is_sandbox=True and pin avatar_id="dd73ea75-1218-4ef3-92ce-606d5f7fbc0a". Swap in your own avatar_id and drop is_sandbox to run against production avatars.

Resources

HeyGenTransport reference

Upstream Pipecat reference for the transport-layer integration.

HeyGenVideoService reference

Upstream Pipecat reference for the service-node integration.