Render an avatar into your own LiveKit room (API-key authenticated)
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.
apiKeyAuthX-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_....
waitFor?stringinitializing (default) returns once the worker acknowledged the
start; avatar_joined returns once the avatar participant is in
your room.
"initializing""avatar_joined"application/json- body
The avatar to render, and the room to render it into.
avatarId*stringThe avatar to render. Must be on the key's allow-list.
uuidlivekitUrl?stringYour LiveKit server URL (wss://<project>.livekit.cloud, or a
self-hosted ws(s):// address). Omit together with livekitToken
for an Atmee-hosted room.
length <= 512livekitToken?stringLiveKit 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.
16 <= length <= 8192agentIdentity?stringWith 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).
length <= 256maxDurationSeconds?integerHard 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.
60 <= value <= 14400metadata?Optional free-form metadata to attach to the session (stored as JSONB).
properties <= 50The avatar is starting (or has joined, with waitFor=avatar_joined).
application/json- response
sessionId*stringuuidstatus*stringHow far the start had progressed when this response was sent.
"initializing""avatar_joined"avatarParticipantIdentity*stringThe identity the avatar joins the room with (from your token; atmee-avatar-agent in a hosted room).
agentIdentity*stringThe agent the avatar renders for (the token's lk.publish_on_behalf, or the hosted room's agent).
roomName*stringThe room, as granted by your token or created by Atmee.
maxDurationSeconds*integerThe hard ceiling applied to this session.
billingMode*string"reserve""metered"livekitUrl?stringAtmee-hosted room only: the LiveKit server (wss://...) your agent
joins.
agentToken?stringAtmee-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.
curl -X POST 'https://api.atmanity.us/v1/avatar_sessions' \ -H 'Content-Type: application/json' \ -d '{ "avatarId": "ac572b6e-802b-4b9e-a602-0786d4441e67"}'{ "sessionId": "f6567dd8-e069-418e-8893-7d22fcf12459", "status": "initializing", "avatarParticipantIdentity": "string", "agentIdentity": "string", "roomName": "string", "maxDurationSeconds": 0, "billingMode": "reserve", "livekitUrl": "string", "agentToken": "string"}Render a video clip from an image and a prompt POST
Renders a short mp4 (1 to 15 seconds, 25 fps) of the person or character in image, moving as prompt describes, optionally speaking audio.
Read a session's state, end reason and cost GET
Reads either kind of API session: a conversation (POST /v1/sessions, kind: conversation) or a render into your own room (POST /v1/avatar_sessions, kind: render).

