---
title: "Mint a realtime session"
method: POST
path: "/v1/realtime/livekit/session"
tags: ["Realtime"]
---

# Mint a realtime session

`POST /v1/realtime/livekit/session`

## Request

- Base URL: `https://realtimeavatar.ai/api`
- URL: `https://realtimeavatar.ai/api/v1/realtime/livekit/session`
- Auth: HTTP bearer

Requires an API key with the `realtime:write` scope.

## Headers

- `X-RTA-Release-Evidence` '1'
- `X-RTA-Observability` 'identity-v1'

## Request body

- LiveKitSessionRequest
  - `avatar_id` string, required
  - `background_id` string
  - `capacity_pool` string
  - `mode` 'avatar' | 'voice'
  - `create_room` boolean
  - `dispatch_agent` boolean
  - `instructions` string
  - `initial_context` object[]
    - `role` 'system' | 'user' | 'assistant', required
    - `content` string, required
  - `initial_say` string
  - `llm` object, nullable
    - `backend` 'local' | 'gemini' | 'openai' | 'external': Which model answers the turns. `external` is enabled per workspace for server-to-server callers and needs endpoint configuration that is not part of this document; a workspace without it is refused with 403.
    - `model` string, nullable
  - `max_session_seconds` integer
  - `participant_identity` string
  - `participant_name` string
  - `character_name` string
  - `queue_ticket_id` string
  - `room_name` string: Optional room label. RTA appends the session identity; use the returned grant's room name to connect. A new call never joins an existing session.
  - `source_kind` 'source_video': The realtime source. Creation is image-only — every avatar grows its own PLATFORM-GENERATED looping source video from the uploaded portrait — so this is always "source_video".
  - `source_video_url` string, uri, nullable: Normally omitted: the avatar's platform-generated idle loop is resolved server-side. Overriding it with a custom video URL is a legacy channel for existing integrations — custom video is not part of the public contract.
  - `stt_mode` 'server' | 'off'
  - `transcription` object: Optional speech recognition hints. Omit language_codes or send [] for automatic multilingual detection. Custom vocabulary biases recognition; at most 100 relevant terms is recommended. It is not a character instruction or a guarantee of recognition accuracy or latency.
    - `language_codes` string[]
    - `custom_vocabulary` string[]
  - `camera` boolean
  - `video_cache_id` string, nullable
  - `voice` union
    - object
      - `provider` 'cartesia', required
      - `model` 'cartesia/sonic-2' | 'cartesia/sonic-2-latest' | 'cartesia/sonic-3' | 'cartesia/sonic-3-latest' | 'cartesia/sonic-turbo' | 'cartesia/sonic-turbo-latest'
      - `voice_id` string, required
      - `speed` number, nullable
      - `emotion` string, nullable
      - `language` string, nullable
    - object
      - `provider` 'breezeblue', required
      - `model` string
      - `voice_id` string, required
      - `guidance_scale` number, nullable
      - `instructions` string, nullable
      - `language` string, nullable
    - object
      - `provider` 'fish', required
      - `model` 'speech-1.6' | 's1' | 's2-pro' | 'drama-3' | 'speech-1.5' | 's1-mini'
      - `voice_id` string, required
      - `speed` number, nullable
      - `emotion` string, nullable
      - `language` string, nullable
  - `voice_id` string, nullable
  - `clip_library` object[]: The session's motion-state map. Normally omitted: the avatar's PLATFORM-GENERATED library (idle / listen / gesture clips rendered from the portrait at creation) is injected automatically. An explicit [] opts the call out of clips. Supplying custom clip URLs is a legacy channel for existing integrations — custom video is not part of the public contract.
    - `clip_id` string, required
    - `source_video_url` string, uri: The clip's video URL — for a platform-generated library this is the generated clip's hosted URL, filled in server-side at hydration.
    - `video_cache_id` string
    - `max_seconds` number
    - `trigger` 'idle' | 'listen' | 'think' | 'directive'
    - `loop` boolean
    - `weight` number
    - `crossfade_ms` integer
    - `trim_start_ms` integer
    - `trim_end_ms` integer
    - `when` string
    - `hint` string
  - `clip_behavior` object
    - `idle` object
      - `clips` string[], required
      - `weight` number
      - `weights` object
    - `on` object
      - `userSpeechStarted` object
        - `clips` string[], required
    - `actions` object
  - `choreography` object
    - `idle_dwell_min_seconds` number
    - `idle_dwell_max_seconds` number
    - `special_weight` number
    - `start_grace_seconds` number
    - `crossfade_ms` integer
    - `crossfade_easing` 'linear' | 'smooth' | 'ease_out'
    - `wrap_crossfade_ms` integer
  - `behavior` object
    - `gestures_enabled` boolean
  - `expression_profile` string
  - `render_backend` 'warp' | 'generative'
  - `support_edits` object
    - `instruction` string, required
    - `reference_url` string, uri
    - `live_edit` object: EXPERIMENTAL ("runtime edit") — let the look follow the conversation mid-call. Less settled than the fixed `instruction` lane: the shape may still change, and the re-dress does not reach every capacity tier yet, so a live session is accepted and runs normally but may hold its opening set for the whole call. Absent means `instruction` is fixed for the session, which is the incumbent behavior.
      - `rules` string, required
      - `cooldown_seconds` integer
      - `renderer` 'editor' | 'generative'
      - `objects` 'editor' | 'generative'
  - `transcript_webhook` object
    - `url` string, uri, required
    - `secret` string, required
  - `content_policy` 'minor-sexual-content-v1' | 'safe-content-v1': Server-authored content enforcement policy. API-key integrators may request it; browser mints strip it. No default. Requires worker enforcement before emission; transport alone does not provide protection.
  - `recording` 'off' | 'audio' | 'video' | 'audio_video' | 'participants' | 'tracks': Server-owned recording policy; omitted means off. Legacy audio includes user and avatar audio. participants saves one continuous audio/video file per participant, without mixing their voices. tracks saves each published participant audio/video track separately; list recordings by session after capture.
  - `connection_history` boolean
  - `client_metadata` object
  - `fast_endpointing` boolean: DEPRECATED, no-op. Accepted and ignored. The faster hesitation ceiling this requested is now the default for every session, so sending it changes nothing. Safe to stop sending; the field is retained only so existing callers do not break.
  - `require_ready_clip_library` boolean
  - `scene` object: Preview, enabled per workspace. A prepared scene from POST /v1/scenes, played forward over its full length in place of the avatar's source video; the avatar keeps the voice and persona. Cannot be combined with mode voice, render_backend generative, source_video_url, video_cache_id or a non-empty clip_library.
    - `video_cache_id` string, required: The prepared scene's artifact id, as returned by POST /v1/scenes when status is ready.
    - `first_frames` integer: Frames in the first clip. The loop closes seamlessly at the wrap only when a continuation follows it.
    - `total_frames` integer: Frames in the whole artifact (first plus continuation).
    - `attach_continuation` boolean: Preview. Set when this scene is a first clip alone: the joined scene (the same first clip plus its continuation) that this workspace prepares after the mint may then be attached to the live call. Linking needs the first clip's md5 and bytes declared on both prepares. Absent or false plays this scene for the whole call.

## Response `200`

LiveKit session grant

- LiveKitSessionGrant
  - `usage_account_id` string: Returned only for X-RTA-Observability: identity-v1 after successful platform billing attachment. The authoritative billing hold tenant ID; never client metadata or provider identity. Omitted by default and on failed or queued responses. Older servers may omit it.
  - `releaseIdentity` object: Returned only for X-RTA-Release-Evidence: 1. Omitted by default for strict SDK compatibility. Missing deployment or worker evidence remains null.
    - `deploymentId` string, nullable, required
    - `workerRevision` string, nullable, required
    - `provenance` object, required
      - `deploymentSource` 'cloudflare-worker-version', required
      - `workerSource` 'authenticated-worker-heartbeat', nullable, required
      - `workerId` string, nullable, required
      - `podStartedAtMs` integer, nullable, required
      - `workerObservedAt` string, date-time, nullable, required
  - `status` 'ready', required
  - `session_id` string, required
  - `room_name` string, required
  - `livekit_url` string, required
  - `participant_token` string, required
  - `participant_identity` string, required
  - `agent_name` string, required
  - `capacity_pool` string, required
  - `reservation_expires_at` string, date-time, required
  - `max_sessions_per_gpu` integer, required
  - `stt_mode` 'server' | 'off', required
  - `camera` boolean
  - `room_created` boolean, required
  - `dispatch_created` boolean, required
  - `join_timeout_seconds` integer, required
  - `idle_timeout_seconds` integer, required
  - `max_session_seconds` integer, required
  - `recording` union
    - object
      - `sessionId` string, required
      - `recordingId` string, required
      - `mode` 'audio' | 'video' | 'audio_video', required
      - `createdAt` string, date-time, required
      - `retainedUntil` string, date-time, required
      - `participant` object
        - `participantIdentity` string, required
        - `role` 'user' | 'avatar', required
      - `mediaStartedAt` string, date-time
      - `mediaEndedAt` string, date-time
      - `mediaStartOffsetMs` integer: First playable native media timestamp relative to mediaStartedAt. Playback retains this offset; it does not reset the file clock to zero.
      - `mediaMutedIntervalsMs` object[]: Intervals of hidden camera video relative to mediaStartedAt, using native media timestamps. Audio playback continues through these intervals.
        - `startMs` integer, required
        - `endMs` integer, required
      - `status` 'pending' | 'recording' | 'processing' | 'expired', required
    - object
      - `sessionId` string, required
      - `recordingId` string, required
      - `mode` 'audio' | 'video' | 'audio_video', required
      - `createdAt` string, date-time, required
      - `retainedUntil` string, date-time, required
      - `participant` object
        - `participantIdentity` string, required
        - `role` 'user' | 'avatar', required
      - `mediaStartedAt` string, date-time
      - `mediaEndedAt` string, date-time
      - `mediaStartOffsetMs` integer: First playable native media timestamp relative to mediaStartedAt. Playback retains this offset; it does not reset the file clock to zero.
      - `mediaMutedIntervalsMs` object[]: Intervals of hidden camera video relative to mediaStartedAt, using native media timestamps. Audio playback continues through these intervals.
        - `startMs` integer, required
        - `endMs` integer, required
      - `status` 'ready', required
      - `mediaType` 'audio/mp4' | 'video/mp4' | 'audio/ogg' | 'video/webm', required
      - `sizeBytes` integer, required
      - `durationMs` integer, nullable, required
    - object
      - `sessionId` string, required
      - `recordingId` string, required
      - `mode` 'audio' | 'video' | 'audio_video', required
      - `createdAt` string, date-time, required
      - `retainedUntil` string, date-time, required
      - `participant` object
        - `participantIdentity` string, required
        - `role` 'user' | 'avatar', required
      - `mediaStartedAt` string, date-time
      - `mediaEndedAt` string, date-time
      - `mediaStartOffsetMs` integer: First playable native media timestamp relative to mediaStartedAt. Playback retains this offset; it does not reset the file clock to zero.
      - `mediaMutedIntervalsMs` object[]: Intervals of hidden camera video relative to mediaStartedAt, using native media timestamps. Audio playback continues through these intervals.
        - `startMs` integer, required
        - `endMs` integer, required
      - `status` 'failed', required
      - `errorCode` 'recording_failed' | 'recording_unavailable', required
  - `recording_mode` 'off' | 'audio' | 'video' | 'audio_video' | 'participants' | 'tracks': Server-owned recording policy; omitted means off. Legacy audio includes user and avatar audio. participants saves one continuous audio/video file per participant, without mixing their voices. tracks saves each published participant audio/video track separately; list recordings by session after capture.
  - `recordings` union[]
    - union
      - object
        - `sessionId` string, required
        - `recordingId` string, required
        - `mode` 'audio' | 'video' | 'audio_video', required
        - `createdAt` string, date-time, required
        - `retainedUntil` string, date-time, required
        - `participant` object
          - `participantIdentity` string, required
          - `role` 'user' | 'avatar', required
        - `mediaStartedAt` string, date-time
        - `mediaEndedAt` string, date-time
        - `mediaStartOffsetMs` integer: First playable native media timestamp relative to mediaStartedAt. Playback retains this offset; it does not reset the file clock to zero.
        - `mediaMutedIntervalsMs` object[]: Intervals of hidden camera video relative to mediaStartedAt, using native media timestamps. Audio playback continues through these intervals.
          - `startMs` integer, required
          - `endMs` integer, required
        - `status` 'pending' | 'recording' | 'processing' | 'expired', required
      - object
        - `sessionId` string, required
        - `recordingId` string, required
        - `mode` 'audio' | 'video' | 'audio_video', required
        - `createdAt` string, date-time, required
        - `retainedUntil` string, date-time, required
        - `participant` object
          - `participantIdentity` string, required
          - `role` 'user' | 'avatar', required
        - `mediaStartedAt` string, date-time
        - `mediaEndedAt` string, date-time
        - `mediaStartOffsetMs` integer: First playable native media timestamp relative to mediaStartedAt. Playback retains this offset; it does not reset the file clock to zero.
        - `mediaMutedIntervalsMs` object[]: Intervals of hidden camera video relative to mediaStartedAt, using native media timestamps. Audio playback continues through these intervals.
          - `startMs` integer, required
          - `endMs` integer, required
        - `status` 'ready', required
        - `mediaType` 'audio/mp4' | 'video/mp4' | 'audio/ogg' | 'video/webm', required
        - `sizeBytes` integer, required
        - `durationMs` integer, nullable, required
      - object
        - `sessionId` string, required
        - `recordingId` string, required
        - `mode` 'audio' | 'video' | 'audio_video', required
        - `createdAt` string, date-time, required
        - `retainedUntil` string, date-time, required
        - `participant` object
          - `participantIdentity` string, required
          - `role` 'user' | 'avatar', required
        - `mediaStartedAt` string, date-time
        - `mediaEndedAt` string, date-time
        - `mediaStartOffsetMs` integer: First playable native media timestamp relative to mediaStartedAt. Playback retains this offset; it does not reset the file clock to zero.
        - `mediaMutedIntervalsMs` object[]: Intervals of hidden camera video relative to mediaStartedAt, using native media timestamps. Audio playback continues through these intervals.
          - `startMs` integer, required
          - `endMs` integer, required
        - `status` 'failed', required
        - `errorCode` 'recording_failed' | 'recording_unavailable', required
  - `connection_history` object
    - `endpoint` string, starts_with, required
    - `token` string, required
    - `expiresAt` string, date-time, required

## Other responses

- `401`: Missing, malformed, revoked, or expired key.
- `403`: The key lacks the scope for this operation, or the tenant is not active.
- `429`: Either the workspace session limit was reached (code "concurrency_limit_reached", top-level maxConcurrentSessions, liveSessions, activeSessions, connectingSessions, pendingSessions), or session capacity is unavailable (the queue contract). Queue responses classify full seats, no workers, or draining workers in x-rta-capacity-refusal; absent or unknown headers mean capacity_full. Starting and connecting sessions count toward the workspace limit. End a session or wait for pending starts to clear before retrying; avoid parallel duplicate starts. Plan refusals are not queue positions. Retain requestId for support.
- `default`: Error. Route-dependent: 400 (a field this route cannot honour — see `portraitUrl` on `UpdateAvatarRequest`), 402 (insufficient credits or spend limit), 404 (no such avatar, voice, or key for this tenant — the message often reads "does not belong to this tenant", which is a missing id and not a permission failure), 408 (the request was cancelled), 409 (the resource is not in a state that accepts this write — a stale `expectedRevision`, a render already in flight, or a mint that asked for a clip library still building), 411 (`POST /v1/assets/remote` only — the origin serving `remoteUrl` sent no `content-length`, so the platform will not stream it), 422 (strict schema rejection, or a motion description the safety screen refused), 429 (rate limited), 502 (upstream render failed), 503 (a dependency this route needs is unavailable — retryable, and nothing was written), 504 (the upstream request budget expired), 500 (unhandled). Switch on `code` where present, else `status`.

## Changes

- **2026-10-20** `e9e3e998e673`: 1 warning
  - removed the optional property `mint_timing` from the response with the `200` status

[Operation history](https://skmtc.dev/realtimeavatar/apis/realtime-avatar-api/changes/v1/realtime/livekit/session/post.md)

---

[API](https://skmtc.dev/realtimeavatar/apis/realtime-avatar-api.md) · [All operations](https://skmtc.dev/realtimeavatar/apis/realtime-avatar-api/llms.txt) · [OpenAPI document](https://skmtc.dev/realtimeavatar/apis/realtime-avatar-api/revisions/e9e3e998e673?raw)
