Zeli AvatarDeveloper docs
v0.1.0Sign in

Guides / Creating avatars

Creating avatars

Bring your own face: upload a custom image or video and get a streaming avatar you can drive from your app. Do it once in the portal, or entirely through the API.

From the portal

Sign in at /portal/avatars, paste an API key, and drop in a photo or a short video. A video gives the most natural head motion; a still image also works. When it finishes preparing you get an avatar id and a snippet to stream it. Manage your keys at /portal/keys.

From the API

Create the same avatar programmatically. A video source gives natural motion; a still image works too.

from zeli import ZeliClient, AvatarConfig, ClientOptions
 
client = ZeliClient(
    api_key="YOUR_API_KEY",
    options=ClientOptions(server_url="https://avatar.zeligate.ai"),
)
 
status = await client.create_avatar("founder.mp4", name="founder")
print(status.avatar_id, status.status)  # e.g. "founder" "preparing"

create_avatar returns an AvatarStatus (preparing or ready). Poll list_avatars until it's ready:

from zeli._avatars import avatar_is_ready
 
while not avatar_is_ready(await client.list_avatars(), status.avatar_id):
    await asyncio.sleep(2.5)

From a single photo (natural motion)

A plain still yields a locked-off "talking photo". create_avatar_from_photo runs the image through the photo-to-avatar pipeline so a single photo gets natural idle head motion. It is gated behind a consent check and returns the generated driving clips.

created = await client.create_avatar_from_photo(
    "headshot.jpg", avatar_id="founder", tones=["neutral", "warm"],
    consent_token="<from your consent flow>",
)
print(created.avatar_id, [c.tone for c in created.clips])

If consent isn't verified you get a ConsentError (with .decision); a rejected key raises AuthenticationError.

Then stream it

Once an avatar is ready, drive it like any built-in avatar — reference it by id:

client = ZeliClient(
    avatar_config=AvatarConfig(avatar_id="founder"),
    api_key="YOUR_API_KEY",
    options=ClientOptions(server_url="https://avatar.zeligate.ai"),
)
 
async with client.connect() as session:
    await session.talk("Hi — welcome to the demo.")
    async for frame in session.video_frames():
        img = frame.to_ndarray(format="rgb24")

See Connecting and Driving the avatar for the full streaming loop.

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