Zeli AvatarDeveloper docs

Get started / Quickstart (Python)

Quickstart

A minimal end-to-end program: connect to your avatar server, send a message, and print the conversation as it streams back using the hosted service.

Building for the browser?

This quickstart is the Python SDK. The JavaScript and TypeScript path is a token minted on your server and streamToVideoElement on the page. See Quickstart (JavaScript).

Install zeli-avatar from PyPI with pip install zeli-avatar. Create an API key and set ZELI_API_KEY and ZELI_AVATAR_ID in your backend environment.

Before you start

server_urlstringRequired

Hosted base URL: https://zeli-avatar.zelibot.xyz. Passed via ClientOptions.

avatar_idstringOptional

A prepared avatar's id, from Copy ID in the portal or from your create call. The avatar's name is only a label, so pass the id. Omit to use the server default. See Avatars & tones.

api_keystringRequired

Your backend API key. Required for hosted server-side requests. See Authentication.

1. Create a client

import asyncio
import os
from zeli import ZeliClient, AvatarConfig, ClientOptions, ZeliEvent, Message
 
client = ZeliClient(
    api_key=os.environ["ZELI_API_KEY"],
    avatar_config=AvatarConfig(
        avatar_id=os.environ["ZELI_AVATAR_ID"],  # Copy ID from your avatar library
    ),
    options=ClientOptions(server_url="https://zeli-avatar.zelibot.xyz"),
)

2. Subscribe to events

Handlers can be sync or async. Register them before connecting.

@client.on(ZeliEvent.SESSION_READY)
async def _ready(info):
    print("session ready:", info.session_id)
 
@client.on(ZeliEvent.MESSAGE_RECEIVED)
async def _message(message: Message):
    print(f"{message.role.value}: {message.content}")

3. Connect and drive the avatar

async def main():
    async with client.connect() as session:
        print("connected to avatar:", session.avatar)
        await session.send_message("Hi! Introduce yourself in one sentence.")
        await asyncio.sleep(12)  # let the reply stream back
 
    print("\nTranscript:")
    for msg in client.get_message_history():
        print(f"  {msg.role.value}: {msg.content}")
 
asyncio.run(main())

async with client.connect() as session: opens the session and tears it down cleanly on exit. Prefer it over calling session.close() yourself.

What just happened

  1. The SDK negotiated a WebRTC media connection to the server.
  2. It opened the control channel and emitted SESSION_READY.
  3. send_message ran the server's conversational loop; the reply streamed back as MESSAGE_STREAM_EVENT_RECEIVED chunks and a final MESSAGE_RECEIVED, while the avatar spoke it on the video track.

Next steps

Zeli Avatar · real-time avatars over WebRTC · self-hostable · AU data residency · source