Video calls

Video calls

The Video calls module manages browser-based meeting rooms backed by LiveKit. This is the layer you use when speakers should join through a web interface, when you need a webinar-style guest view, or when a room should later feed another pipeline such as egress, recording, or restreaming.

Compared with transport-first modules, a video call is centered around room policy and participant experience: media mode, participant limit, chat, screen sharing, webinar restrictions, and optional room recording behavior. The room lifecycle and the public token flow work together, so the API is best understood as room provisioning + join preparation.

The private control methods manage the room object itself. The public helper methods complete the join flow: findLKRoomNameById resolves the LiveKit room name and room restrictions, and createToken mints the participant token used by the browser client.

If room lifecycle actions are driven from an operator workflow, the create, start, and stop examples below also include ready-to-adapt vMix Script tabs. The join and token helpers remain browser-facing rather than vMix-specific.

Examples by preset

The create payload naturally breaks into a few practical room presets. In practice, the most useful shapes are a standard team room, a webinar-friendly room, a lightweight audio room, and a room that is expected to record a composite output.

{
  "name": "Team standup room",
  "user_id": "USER_ID",
  "mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
  "max_participants": 20,
  "allow_webinar_mode": false,
  "allow_chat": true,
  "allow_share_screen": true,
  "record": false,
  "record_mode": "ROOM_COMPOSITE_GRID",
  "active": true
}
{
  "name": "Guest webinar room",
  "user_id": "USER_ID",
  "mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
  "max_participants": 200,
  "allow_webinar_mode": true,
  "allow_chat": true,
  "allow_share_screen": false,
  "record": false,
  "record_mode": "ROOM_COMPOSITE_GRID",
  "active": true
}
{
  "name": "Audio briefing room",
  "user_id": "USER_ID",
  "mediaType": "MEDIA_TYPE_AUDIO_ONLY",
  "max_participants": 50,
  "allow_webinar_mode": false,
  "allow_chat": true,
  "allow_share_screen": false,
  "record": false,
  "record_mode": "ROOM_COMPOSITE_GRID",
  "active": true
}
{
  "name": "Recorded speaker room",
  "user_id": "USER_ID",
  "mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
  "max_participants": 50,
  "allow_webinar_mode": true,
  "allow_chat": true,
  "allow_share_screen": true,
  "record": true,
  "record_mode": "ROOM_COMPOSITE_SPEAKER",
  "active": true
}

Workflow examples

These scenarios explain why a room exists in a production design, not just what the create payload looks like.

Create a managed speaker room and distribute browser join links

Use a video call when guests should join from a browser instead of publishing through OBS or a standalone encoder. The room object becomes the stable meeting identity, while findLKRoomNameById and createToken power the actual speaker join step.

Run a webinar room with restricted audience behavior

When guests need a view-only or restricted-experience path, keep webinar mode enabled and decide whether chat and screen sharing should remain available. This keeps the room useful for public events without exposing full speaker privileges to everyone.

Use a room as the upstream for a downstream output

A room can feed another stage in the pipeline, such as a room composite egress or another module that depends on the meeting output. In that setup, the room object defines participant policy while the output side handles delivery.

Public join flow

The public side of the module is intentionally small but important. Resolve the room first, then mint the participant token.

  • findLKRoomNameById: maps your Callaba room id to the active LiveKit room name and returns room-level flags such as webinar mode, chat, screen sharing, and record settings.
  • createToken: creates a participant token for the resolved room. The browser client uses that token to join.
Create video call
Collapse
POST
/api/conferences/create

Create a new managed video call room in Callaba Engine.

This method provisions the room object that the browser join flow depends on. The payload focuses on room policy rather than transport details: media mode, participant capacity, webinar restrictions, chat, screen sharing, recording behavior, and whether the room should be active right after creation.

Examples by preset are especially useful here because most real rooms fall into a few recognizable patterns: standard team rooms, webinar-style rooms, audio-only rooms, and recorded rooms for speaker-focused output.

Workflow-oriented use cases: create a stable browser room for speakers, pre-provision a webinar room before the event starts, or define a recorded room whose layout should later be used for composite output.

Standard team room

Use this when a small or medium team should join with full audio and video, chat, and screen sharing enabled.

Standard team room
curl --request POST \
--url http://localhost/api/conferences/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Team standup room",
"user_id": "USER_ID",
"mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
"max_participants": 20,
"allow_webinar_mode": false,
"allow_chat": true,
"allow_share_screen": true,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"active": true
}'
Webinar-ready room

Use this when the room should support guest or view-only behavior and keep speaker privileges more controlled.

Webinar-ready room
curl --request POST \
--url http://localhost/api/conferences/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Guest webinar room",
"user_id": "USER_ID",
"mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
"max_participants": 200,
"allow_webinar_mode": true,
"allow_chat": true,
"allow_share_screen": false,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"active": true
}'
Audio-only room

Use this when the meeting should behave more like an audio briefing or lightweight discussion space.

Audio-only room
curl --request POST \
--url http://localhost/api/conferences/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Audio briefing room",
"user_id": "USER_ID",
"mediaType": "MEDIA_TYPE_AUDIO_ONLY",
"max_participants": 50,
"allow_webinar_mode": false,
"allow_chat": true,
"allow_share_screen": false,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"active": true
}'
Recorded speaker room

Use this when the room should later feed a composite output workflow and recording is part of the room policy.

Recorded speaker room
curl --request POST \
--url http://localhost/api/conferences/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Recorded speaker room",
"user_id": "USER_ID",
"mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
"max_participants": 50,
"allow_webinar_mode": true,
"allow_chat": true,
"allow_share_screen": true,
"record": true,
"record_mode": "ROOM_COMPOSITE_SPEAKER",
"active": true
}'
Request body parameters
Identity
name
string

Dashboard label: Room Name.

Human-readable room name. The dashboard validates this field and shows the same character guidance used elsewhere in the product: A-Z, a-z, 0-9, and -.

user_id
string

Owner id of the room. The dashboard store does not ask for this explicitly because the backend injects the authenticated user id before create and update calls.

Media and access
mediaType
string

Dashboard label: Media type.

Supported room modes are MEDIA_TYPE_VIDEO_AUDIO, MEDIA_TYPE_VIDEO_ONLY, and MEDIA_TYPE_AUDIO_ONLY.

max_participants
integer

Dashboard label: Max participants.

Maximum number of participants allowed to join the meeting simultaneously.

allow_webinar_mode
boolean

Controls whether the room should support webinar-style guest behavior in addition to the speaker path.

allow_chat
boolean

Controls whether chat should remain available in the browser room experience.

allow_share_screen
boolean

Controls whether speakers should be allowed to share their screen inside the room.

Recording
record
boolean

Controls whether the room should be treated as record-enabled.

record_mode
string

Composite recording mode for the room. Real product values include ROOM_COMPOSITE_GRID, ROOM_COMPOSITE_AND_CHAT, and ROOM_COMPOSITE_SPEAKER.

Runtime
active
boolean

Dashboard label: Enabled.

Controls whether the room should be active right after provisioning.

Create video call
curl --request POST \
--url http://localhost/api/conferences/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Main stage room",
"user_id": "USER_ID",
"mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
"max_participants": 50,
"allow_webinar_mode": true,
"allow_chat": true,
"allow_share_screen": true,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"active": true
}'
Response
Identity
_id
string

Mongo-style identifier of the room object.

id
string

Convenience alias for _id.

name / user_id
mixed

Stored room name and owning user id.

Media and access
mediaType / max_participants
mixed

Media mode and participant limit stored on the room object.

allow_webinar_mode / allow_chat / allow_share_screen
mixed

Room-level participant experience flags returned with the room object.

Recording
record / record_mode
mixed

Recording intent and composite mode stored for the room.

Runtime
sid / active / created / modified
mixed

Room runtime and timestamp fields returned by the backend.

Operation result
success
boolean

The model exposes success: true as a virtual field in successful responses.

Response: Create video call
JSON
{
"_id": "69f013c1aa11bb22cc33dd44",
"id": "69f013c1aa11bb22cc33dd44",
"name": "Main stage room",
"user_id": "69360341db559495f643de6a",
"mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
"allow_webinar_mode": true,
"allow_chat": true,
"allow_share_screen": true,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"max_participants": 50,
"sid": "RM_x7h6k4example",
"active": true,
"created": "2026-03-24T16:00:00.000Z",
"modified": "2026-03-24T16:00:00.000Z",
"success": true
}
Get video calls count
Expand
POST
/api/conferences/getCount

Return the total number of video call rooms visible to the authenticated user.

Use this with paginated listings when the dashboard or your own control panel needs the current room count before fetching room objects.

Request body parameters
This method has no parameters
Get video calls count
curl --request POST \
--url http://localhost/api/conferences/getCount \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"filter": {
"active": true
}
}'
Response
count
integer

Total number of video call rooms currently visible to the authenticated user.

Response: Get video calls count
JSON
{
"count": 1
}
Get all video calls
Expand
POST
/api/conferences/getAll

Return the list of video call rooms for the current user.

This is the normal control-plane listing method for management views. It returns the room objects themselves, not a wrapped envelope, so the response can be rendered directly as a room list.

Request body parameters
limit
integer

Optional page size for the list query.

skip
integer

Optional offset for paginated listing.

sort
object

Optional sort descriptor. The dashboard store defaults to { created: 1 }.

filter
object

Optional filter object forwarded to the backend query.

Get all video calls
curl --request POST \
--url http://localhost/api/conferences/getAll \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"limit": 10,
"skip": 0,
"sort": {
"created": 1
}
}'
Response
array of video call room objects
array

The backend returns a bare array of room objects, not a wrapped object.

Response: Get all video calls
JSON
[
{
"_id": "69f013c1aa11bb22cc33dd44",
"id": "69f013c1aa11bb22cc33dd44",
"name": "Main stage room",
"user_id": "69360341db559495f643de6a",
"mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
"allow_webinar_mode": true,
"allow_chat": true,
"allow_share_screen": true,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"max_participants": 50,
"sid": "RM_x7h6k4example",
"active": true,
"created": "2026-03-24T16:00:00.000Z",
"modified": "2026-03-24T16:00:00.000Z",
"success": true
}
]
Get video call by id
Expand
POST
/api/conferences/getById

Load one video call room by its id.

Use this when an operator opens the room editor, when you need to inspect the current room policy, or before deciding whether to start, stop, or update the room.

Request body parameters
id
string

Identifier of the room you want to load.

Get video call by id
curl --request POST \
--url http://localhost/api/conferences/getById \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "VIDEO_CALL_ID"
}'
Response
video call room object
object

The backend returns the stored room object for the requested id.

Response: Get video call by id
JSON
{
"_id": "69f013c1aa11bb22cc33dd44",
"id": "69f013c1aa11bb22cc33dd44",
"name": "Main stage room",
"user_id": "69360341db559495f643de6a",
"mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
"allow_webinar_mode": true,
"allow_chat": true,
"allow_share_screen": true,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"max_participants": 50,
"sid": "RM_x7h6k4example",
"active": true,
"created": "2026-03-24T16:00:00.000Z",
"modified": "2026-03-24T16:00:00.000Z",
"success": true
}
Update video call
Expand
POST
/api/conferences/update

Update an existing video call room.

The update contract mirrors create. In practice this is how you change room policy over time: webinar behavior, chat availability, screen sharing, recording mode, participant limit, or the active-state intent.

Request body parameters
id
string

Identifier of the room being updated.

room payload fields
mixed

The update contract mirrors create and reuses the same room-policy fields.

Update video call
curl --request POST \
--url http://localhost/api/conferences/update \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "VIDEO_CALL_ID",
"name": "Main stage room",
"user_id": "USER_ID",
"mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
"max_participants": 50,
"allow_webinar_mode": true,
"allow_chat": true,
"allow_share_screen": true,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"active": true
}'
Response
updated video call room object
object

The backend returns the updated room object.

Response: Update video call
JSON
{
"_id": "69f013c1aa11bb22cc33dd44",
"id": "69f013c1aa11bb22cc33dd44",
"name": "Main stage room updated",
"user_id": "69360341db559495f643de6a",
"mediaType": "MEDIA_TYPE_VIDEO_AUDIO",
"allow_webinar_mode": true,
"allow_chat": true,
"allow_share_screen": true,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"max_participants": 50,
"sid": "RM_x7h6k4example",
"active": false,
"created": "2026-03-24T16:00:00.000Z",
"modified": "2026-03-24T16:10:00.000Z",
"success": true
}
Start video call
Expand
POST
/api/conferences/start

Start a video call room by id.

Starting the room marks it active and ensures the LiveKit room exists for the join flow. Use this when the room should begin accepting participants again after being paused or prepared ahead of an event.

Request body parameters
id
string

Identifier of the room to start.

Start video call
curl --request POST \
--url http://localhost/api/conferences/start \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "VIDEO_CALL_ID"
}'
Response
success
boolean

The backend returns { success: true } when the room has been activated and the room-creation path completes successfully.

Response: Start video call
JSON
{
"success": true
}
Stop video call
Expand
POST
/api/conferences/stop

Stop a video call room by id.

Stopping the room marks it inactive and tears down the active LiveKit room state behind it. This is the operational counterpart to start when the meeting should no longer accept new participants.

Request body parameters
id
string

Identifier of the room to stop.

Stop video call
curl --request POST \
--url http://localhost/api/conferences/stop \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "VIDEO_CALL_ID"
}'
Response
success
boolean

The backend returns { success: true } when the room has been stopped successfully.

Response: Stop video call
JSON
{
"success": true
}
Remove video call
Expand
DELETE
/api/conferences/remove

Remove a video call room by id.

This removes the stored room object and also attempts to clean up the runtime room and egress state tied to it. Use remove when the room should disappear from the control plane entirely, not just be stopped.

Query parameters
id
string

Identifier of the room to delete.

Remove video call
curl --request DELETE \
--url http://localhost/api/conferences/remove \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "VIDEO_CALL_ID"
}'
Response
success
boolean

The backend returns { success: true } after the room object and linked runtime state have been removed.

Response: Remove video call
JSON
{
"success": true
}
Find LiveKit room name by id
Expand
POST
/api/conferences-public/findLKRoomNameById

Resolve the active LiveKit room name for a Callaba video call room id.

This is the first public helper in the browser join flow. Besides the room name itself, it returns the room-level behavior flags that the join UI needs to know, such as webinar mode, chat, screen sharing, and whether recording is enabled.

Request body parameters
id
string

Identifier of the Callaba room you want to resolve into the active LiveKit room name.

Find LiveKit room name by id
curl --request POST \
--url http://localhost/api/conferences-public/findLKRoomNameById \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "VIDEO_CALL_ID"
}'
Response
LKRoomName
string

LiveKit room name used by the browser join flow.

allow_webinar_mode / allow_chat / allow_share_screen
mixed

Room behavior flags needed by the join UI.

record / record_mode
mixed

Recording-related room flags returned alongside the lookup result.

success
boolean

Indicates whether the active room could be resolved.

Response: Find LiveKit room name by id
JSON
{
"id": "69f013c1aa11bb22cc33dd44",
"LKRoomName": "34d4f497-f95b-4543-8d15-fde0b77d8abc",
"allow_webinar_mode": true,
"allow_chat": true,
"allow_share_screen": true,
"record": false,
"record_mode": "ROOM_COMPOSITE_GRID",
"success": true
}
Create participant token
Expand
POST
/api/conferences-public/createToken

Create a participant token for the browser join flow.

This is the second public helper in the room-entry path. After the client knows the active LiveKit room name, it requests a participant token for a speaker, guest, or hidden egress-style participant and uses that token to join the room.

Request body parameters
Room
room_id
string

Callaba room id for the conference being joined.

LKRoomName
string

Resolved LiveKit room name returned by findLKRoomNameById.

Participant
participant_id
string

Stable participant identity used in the token grant.

participant_name
string

Optional display name shown in the room UI.

hidden
boolean

Optional hidden-mode flag used for egress-style or non-visible participants.

egress_mode_token
string

Optional token used only when a hidden participant should be allowed into a room whose webinar-mode policy would otherwise block that path.

Create participant token
curl --request POST \
--url http://localhost/api/conferences-public/createToken \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"room_id": "VIDEO_CALL_ID",
"LKRoomName": "34d4f497-f95b-4543-8d15-fde0b77d8abc",
"participant_name": "Jane Speaker",
"participant_id": "participant-123",
"hidden": false
}'
Response
participant_token
string

LiveKit participant token used by the browser client to join the room.

LKRoomName
string

Echoes the LiveKit room name used for the token grant.

success
boolean

Indicates whether the token was created successfully.

Response: Create participant token
JSON
{
"participant_token": "<livekit_participant_token>",
"LKRoomName": "34d4f497-f95b-4543-8d15-fde0b77d8abc",
"success": true
}