Skip to main content
A session is one live avatar stream: it binds an avatar to a room (livekit or daily) and exposes an ingestion WebSocket you stream audio into. The avatar joins your room as a participant and publishes lip-synced avatar video generated from that audio.

Lifecycle

  1. POST /api/sessions - create the session. The response carries ingestion.url and a single-use ingestion.wsToken (15 minute TTL).
  2. Open the WebSocket and send start - see the WebSocket protocol.
  3. Optionally send POST /api/sessions/{id}/heartbeat to keep the session marked active.
  4. POST /api/sessions/{id}/end or DELETE /api/sessions/{id} to terminate. Both can return 202 while session cleanup finishes - poll GET /api/sessions/{id} until session.status is ENDED.
  5. If the WebSocket drops or the token expires, POST /api/sessions/{id}/reconnect mints a fresh wsToken. The status endpoint never returns tokens or room credentials.

Endpoints

The room object

Every session needs a room describing where the avatar publishes: livekit_room_id (top level, optional) overrides the resolved room name. Legacy top-level fields byolr, livekitUrl, and livekitToken are rejected with ROOM_LEGACY_FIELDS; unknown fields fail with REQUEST_FIELD_UNKNOWN; waitForIngestion fails with WAIT_FOR_INGESTION_REMOVED.

inputProvider

Optional hint naming the upstream speech provider feeding the socket: deepgram, gemini, gnani, elevenlabs, openai, cartesia, sarvam, or custom. Provider-driven modes change how utterance boundaries are detected; omit it (or use custom) for plain PCM streaming. On reconnect, a provided inputProvider must match the stored value (INPUT_PROVIDER_MISMATCH).

Reading responses

  • Create returns the session summary twice: nested under session and mirrored at the top level (room, egressType, roomUrl, roomToken, inputProvider).
  • workerStatus progresses PENDING - ASSIGNING - ASSIGNED/ACTIVE - ENDING - ENDED (or FAILED). workerAssignment is opaque placement metadata; keep jobId handy for support.
  • ingestion.ready tells you whether url/wsToken are present. On GET /api/sessions/{id}, ready can be true while url/wsToken are absent - use reconnect to mint a token.
  • cost_usd is the session’s USD cost as a decimal string. It is "0.0000" for every session during the private beta (usage is metered in credits instead). When paid plans launch, new sessions will carry their real cost; sessions created during the beta keep 0 permanently.