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.