When
AUTH_REQUIRED=true, all endpoints below require a token via the Authorization: Bearer <token> header or the api_key query parameter. The header is recommended by default.Why Sayna wraps LiveKit
- Prevents exposing LiveKit API keys or admin endpoints to client applications.
- Enforces Sayna authentication and authorization for every management call.
- Keeps multi-tenant isolation consistent across REST and WebSocket flows.
Published audio tracks
When a WebSocket session is audio-enabled and joins a LiveKit room, the Sayna agent participant publishes synthesized speech on an audio track named"tts-audio". If that session’s config message also includes a loading_audio object, the agent publishes a second audio track named "loading-audio" carrying the loading-indicator sound.
The two tracks are independent and can be audible at the same time. LiveKit client SDKs automatically play every subscribed audio track, so participants hear both without any extra client-side handling.
Because
"loading-audio" is a real published track, it is included in room-composite egress recordings alongside "tts-audio". This is correct behavior — the recording faithfully reflects what the human participant heard.Room ownership and access control
Room access is controlled via themetadata.auth_id field stored in room metadata. When authentication is enabled:
- Room creation: When you request a token for a room that doesn’t exist, Sayna creates it and sets
metadata.auth_idto your tenant ID. - Room access: All room-scoped operations verify that
room.metadata.auth_idmatches your authenticatedauth.id. - Access denied: Unauthorized access returns
404 Not Found(masked for security) or403 Forbiddendepending on the operation.
Room names are no longer modified or prefixed. You send and receive clean room names exactly as specified.
Backward compatibility
Whenauth.id is absent (unauthenticated mode), all rooms are accessible. This maintains compatibility with deployments that don’t require authentication.
Endpoint overview
Typical flow
1
Create a room and get a token
Call
POST /livekit/token with your room name. If the room doesn’t exist, Sayna creates it and sets metadata.auth_id to your tenant ID before returning the token.2
List rooms
Call
GET /livekit/rooms to discover active rooms. Only rooms with matching metadata.auth_id are returned.3
Inspect a room
Use
GET /livekit/rooms/{room_name} to fetch participant identities and metadata.4
Moderate participants
Disconnect a participant with
DELETE /livekit/participant or mute a track with POST /livekit/participant/mute.5
Handle SIP calls
Initiate outbound calls with
POST /sip/call or transfer existing SIP participants with POST /sip/transfer.