Atmee.aiDocs
APIAPI referenceAvatar sessions

Render an avatar into your own LiveKit room (API-key authenticated)

POST
/v1/avatar_sessions

Starts an avatar session: the avatar is rendered into a LiveKit room that YOU own, on behalf of YOUR agent — the bring-your-own-agent path the livekit-plugins-atmee plugin uses. Nothing here creates a room or a conversation: you mint a LiveKit access token for the avatar participant with your own project's API secret (grant roomJoin for your room, set the participant attribute lk.publish_on_behalf to your agent's identity, and kind: agent) and pass it here. The rendering worker joins your room with that token, waits for your agent, receives its audio over the LiveKit data stream (lk.audio_stream, 16 kHz PCM — livekit-agents' DataStreamAudioOutput) and publishes synced video and audio.

Responds 202 as soon as the worker acknowledged the start (status: initializing), typically within a second; the avatar's tracks appear in your room a few seconds later. Pass ?waitFor=avatar_joined to block until the worker is in the room instead. Billing runs by the minute while the render lasts and stops when the worker reports the end (your agent left, the room closed, you removed the avatar participant), when you call POST /v1/avatar_sessions/{id}/end, or at maxDurationSeconds.

The token is read, not verified — your secret never leaves you. A token your LiveKit server rejects simply never joins and the session fails as AVATAR_DID_NOT_JOIN after the join timeout.

Atmee-hosted room (no LiveKit project of your own, e.g. a Pipecat bot on any transport): omit both livekitUrl and livekitToken. The service then creates a room on Atmee's LiveKit project, the avatar joins it as atmee-avatar-agent publishing on behalf of agentIdentity (default agent), and the response carries livekitUrl and agentToken for your agent to join that room with. The protocol inside the room is the same: stream your agent's audio to the avatar (lk.audio_stream), subscribe to the avatar's video and audio tracks. The room is deleted when the session ends. Requires the sessions scope; the avatar must be on the key's allow-list.

v2 avatars (invite-only) render on a separate GPU pool: the avatar's own configuration decides, there is nothing to set on the request. That pool scales to zero, so the first v2 session after a quiet period can take a few minutes to start: the service waits up to 4 minutes for the pool to start the render and up to 6 for the avatar to join. Use ?waitFor=avatar_joined with a client timeout of at least 7 minutes, or retry on avatar_warming.

Authorization

apiKeyAuth
headerX-Api-Key<token>

Secret embed API key (sk_atmee_...; keys minted before 2026-09 carry sk_live_...), held by the customer's own backend and never sent to a browser. Format: X-Api-Key: sk_atmee_....

Query Parameters

waitFor?string

initializing (default) returns once the worker acknowledged the start; avatar_joined returns once the avatar participant is in your room.

Value in"initializing""avatar_joined"

Request Body

application/json
  1. body

The avatar to render, and the room to render it into.

avatarId*string

The avatar to render. Must be on the key's allow-list.

Formatuuid
livekitUrl?string

Your LiveKit server URL (wss://<project>.livekit.cloud, or a self-hosted ws(s):// address). Omit together with livekitToken for an Atmee-hosted room.

Lengthlength <= 512
livekitToken?string

LiveKit access token for the avatar participant, minted with YOUR project's API key and secret: identity = the avatar's participant identity (the plugin uses atmee-avatar-agent), kind: agent, a roomJoin grant for your room, and the attribute lk.publish_on_behalf = your agent's identity. Read, never verified, by this service. Omit together with livekitUrl for an Atmee-hosted room.

Length16 <= length <= 8192
agentIdentity?string

With your own room: optional cross-check, must equal the token's lk.publish_on_behalf. In an Atmee-hosted room: your agent's participant identity (default agent; atmee-avatar-agent is reserved for the avatar).

Lengthlength <= 256
maxDurationSeconds?integer

Hard ceiling of the session, in seconds (default 3600). Also the most a session can bill if your agent dies without the worker ever reporting. Capped server-side by the key's limits.

Range60 <= value <= 14400
metadata?

Optional free-form metadata to attach to the session (stored as JSONB).

Propertiesproperties <= 50

Response Body

The avatar is starting (or has joined, with waitFor=avatar_joined).

application/json
  1. response
sessionId*string
Formatuuid
status*string

How far the start had progressed when this response was sent.

Value in"initializing""avatar_joined"
avatarParticipantIdentity*string

The identity the avatar joins the room with (from your token; atmee-avatar-agent in a hosted room).

agentIdentity*string

The agent the avatar renders for (the token's lk.publish_on_behalf, or the hosted room's agent).

roomName*string

The room, as granted by your token or created by Atmee.

maxDurationSeconds*integer

The hard ceiling applied to this session.

billingMode*string
Value in"reserve""metered"
livekitUrl?string

Atmee-hosted room only: the LiveKit server (wss://...) your agent joins.

agentToken?string

Atmee-hosted room only: the access token your agent joins the room with (identity agentIdentity, publish, subscribe and data). Valid for the session's ceiling plus the join timeout; treat it as a secret.

Example Request
curl -X POST 'https://api.atmanity.us/v1/avatar_sessions' \  -H 'Content-Type: application/json' \  -d '{  "avatarId": "ac572b6e-802b-4b9e-a602-0786d4441e67"}'
Example Response
{  "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459",  "status": "initializing",  "avatarParticipantIdentity": "string",  "agentIdentity": "string",  "roomName": "string",  "maxDurationSeconds": 0,  "billingMode": "reserve",  "livekitUrl": "string",  "agentToken": "string"}
Render an avatar into your own LiveKit room (API-key authenticated) — Atmee Docs