Docs index: /llms.txt · every page as Markdown: add .md

‹ Platforms

LiveKit

Give a LiveKit voice agent a face with the bitHuman Python plugin.

bitHuman cloudYour computer or serverAPI secretLiveKit plugin 1.8.9

To add a talking avatar to a LiveKit voice agent, install the livekit-plugins-bithuman Python plugin and start a bithuman.AvatarSession beside your agent’s session. Pass avatar_id= to render the avatar in the bitHuman cloud, or model_path= to render it inside your worker; either way the avatar speaks the agent’s replies with its lips in sync.

livekit-plugins-bithuman works on LiveKit Cloud or your own LiveKit server; the avatar joins the room as a participant.

Before you start

It is a Python plugin; there is no Node.js plugin. The avatar renders in one of two ways:

A bitHuman cloud avatarThe avatar on your server
You passavatar_id= (an agent code)model_path= (an avatar file)
The avatar rendersin the bitHuman cloud, in the USinside your worker’s process
Its audio and videoare published into your room by bitHumanstay on your machine until your worker publishes them
Pricethe cloud rate (pricing)the self-hosted rate
Guidethis pageVoice agent

Either way, the plugin serves the agent’s own model, Essence 2 or Expression 2.

  • Python 3.10–3.14 and a LiveKit project (its URL and credentials).
  • A bitHuman agent code: A23WJF0199 (the wise-pup sample avatar) or your own (create your own avatar).
  • An API secret, and an OpenAI key for the voice model in the example.

Install

pip install "livekit-agents[openai,silero]" livekit-plugins-bithuman python-dotenv

To render the avatar inside your worker with model_path=, also install "bithuman[expression-2]".

Authenticate

In a LiveKit worker, name the secret BITHUMAN_MASTER_SECRET and pass a minted token. BITHUMAN_MASTER_SECRET is your API secret under another name, so the plugin never finds it and copies it into the room.

For a cloud avatar, the worker mints a one-hour token that can start only this agent’s avatar in this room (POST /v1/runtime-tokens/mint with "scope": "livekit-cloud"), as in the worker below. Pass the minted token as api_secret=: for a cloud avatar the plugin requires api_secret (api_token= is not used for cloud avatars).

Warning: Without api_secret=, the plugin reads BITHUMAN_API_SECRET from the environment and copies it into the avatar’s participant attributes, which everyone in the room can read. Keep BITHUMAN_API_SECRET unset in the worker.

export BITHUMAN_MASTER_SECRET="<your API secret>"
export BITHUMAN_AGENT_ID=A23WJF0199
export LIVEKIT_URL=wss://your-project.livekit.cloud
export LIVEKIT_API_KEY=… LIVEKIT_API_SECRET=…
export OPENAI_API_KEY=…
Your serverYour agent workerBITHUMAN_MASTER_SECRET stays in this processbitHuman cloudThe cloud avatarstarts with a one-hour token for this agent androomYour LiveKit roomYour appjoins with a room token from your server, nevera bitHuman secretmint a tokenvideo and voice
LiveKit: the secret stays on your server. Your LiveKit agent worker holds the API secret as BITHUMAN_MASTER_SECRET and mints a one-hour runtime token for each session. The bitHuman cloud avatar joins your room with that token and publishes its video and voice. Your app joins the room with a room token from your server and never holds a bitHuman secret.

Run your first avatar

A complete worker (agent.py):

import os

import aiohttp
from dotenv import load_dotenv
from livekit.agents import Agent, AgentSession, JobContext, WorkerOptions, cli
from livekit.agents.voice.room_io import RoomOptions
from livekit.plugins import bithuman, openai, silero
from openai.types.realtime.realtime_audio_input_turn_detection import ServerVad

load_dotenv()

async def livekit_cloud_token(agent_code: str, room_name: str) -> str:
    """A one-hour token that can only start this agent's avatar in this room."""
    async with aiohttp.ClientSession() as http:
        async with http.post(
            "https://api.bithuman.ai/v1/runtime-tokens/mint",
            headers={"api-secret": os.environ["BITHUMAN_MASTER_SECRET"]},
            json={"agent_code": agent_code, "scope": "livekit-cloud",
                  "room_name": room_name, "livekit_url": os.environ["LIVEKIT_URL"]},
        ) as resp:
            resp.raise_for_status()
            return (await resp.json())["scoped_token"]

async def entrypoint(ctx: JobContext):
    await ctx.connect()
    await ctx.wait_for_participant()
    agent_code = os.environ["BITHUMAN_AGENT_ID"]

    session = AgentSession(
        llm=openai.realtime.RealtimeModel(
            voice="coral",
            # end the user's turn after 0.5 s of silence (the default waits longer)
            turn_detection=ServerVad(type="server_vad", silence_duration_ms=500, create_response=True, interrupt_response=True),
        ),
        vad=silero.VAD.load(),
    )
    avatar = bithuman.AvatarSession(
        avatar_id=agent_code,
        api_secret=await livekit_cloud_token(agent_code, ctx.room.name),
    )
    await avatar.start(session, room=ctx.room)
    await session.start(
        agent=Agent(instructions="You are a friendly assistant. Keep answers short."),
        room=ctx.room,
        room_options=RoomOptions(audio_output=False),   # the avatar publishes the audio
    )

if __name__ == "__main__":
    cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))
python agent.py dev
# → join the room from the LiveKit Agents Playground (agents-playground.livekit.io); the avatar appears and answers

Performance

A cloud avatar renders in the bitHuman cloud; with model_path= the avatar renders where your worker runs, as Python does:

ConfigurationEssence 2Expression 2
NVIDIA RTX 4090 Cloud API · GPU
4.1× real timeNVIDIA RTX 4090 · cloud API · measured 2026-09-27
17.0× real timeNVIDIA RTX 4090 · cloud API · measured 2026-09-23
Intel Core i7-13700F (x86_64) Linux · Python CPU only (no GPU)
1.2× real timeIntel Core i7-13700F (x86_64), CPU only (no GPU) · bithuman 2.12.1 · measured 2026-10-08
2.4× real timeIntel Core i7-13700F (x86_64), CPU only (no GPU) · bithuman 2.12.1 · measured 2026-10-08
Apple M4 macOS · Python
6.9× real timeApple M4 · bithuman 2.11.12 · measured 2026-09-25
8.4× real timeApple M4 · bithuman 2.11.12 · measured 2026-09-25

Times real time: seconds of avatar video rendered per second. At 1.0× or more, an avatar holds a live conversation. Select a figure for its release and date. All configurations and how we measure.

This section moved: docs.bithuman.ai/platforms/livekit#run-your-first-avatar

This section moved: docs.bithuman.ai/platforms/livekit/app#integrate-into-your-app

This section moved: docs.bithuman.ai/platforms/livekit/app#platform-notes

This section moved: docs.bithuman.ai/platforms/livekit/app#reference

This section moved: docs.bithuman.ai/platforms/livekit/troubleshooting