Live Video API
Preview
REST

Rooms & sessions

A room is an isolated real-time session with a fixed capacity, optional cloud recording, and a media region. Manage rooms exclusively from your backend with Basic Auth.

Create on demand

Spin up a room when a session starts — no pre-provisioning required.

Inspect status

Read capacity, participant count, region, recording flag, and metadata.

Graceful end

Disconnect everyone, finalize recording, and stop usage billing.

Hard delete

Remove the room resource after archival for data hygiene.

Default capacity

12

maxParticipants

Hard max

50

per room (Preview)

Empty timeout

300s

auto-end if unused

Recording

Composite

optional cloud MP4

POST
/v1/video/rooms
Preview

Provision a new video room. The room enters ready immediately and becomes active when the first client connects successfully.

Request body

application/json
JSON
{
"name": "Support Session #1042",
"maxParticipants": 4,
"record": true,
"metadata": {
"ticketId": "TKT-1042",
"queue": "billing",
"agentId": "agt_22"
}
}
FieldTypeRequiredDescription
namestringoptionalLabel for dashboards and support. Default: generated name.
maxParticipantsintegeroptionalHard cap on concurrent joins. Default 12, max 50.
recordbooleanoptionalStart cloud recording when room becomes active. Default false.
metadataobjectoptionalApp-defined key/values echoed on GET and webhooks (≤ 4 KB).

Response

JSON
{
"success": true,
"code": "VIDEO_ROOM_CREATED",
"message": "Video room created successfully.",
"requestId": "REQ-1782001000001",
"timestamp": "2026-07-12T10:15:00.000Z",
"data": {
"roomId": "rm_8f3a2c1b0e9d",
"name": "Support Session #1042",
"status": "ready",
"maxParticipants": 4,
"participantCount": 0,
"record": true,
"recordingStatus": "idle",
"region": "af-west",
"metadata": {
"ticketId": "TKT-1042",
"queue": "billing",
"agentId": "agt_22"
},
"createdAt": "2026-07-12T10:15:00.000Z",
"emptyTimeoutSeconds": 300,
"joinUrl": "https://video.sendexa.co/r/rm_8f3a2c1b0e9d"
}
}

Code examples

Bash
curl -X POST 'https://api.sendexa.co/v1/video/rooms' \
-H 'Content-Type: application/json' \
-H 'Authorization: Basic YOUR_DASHBOARD_BASE64_TOKEN' \
-d '{
"name": "Support Session #1042",
"maxParticipants": 4,
"record": true,
"metadata": { "ticketId": "TKT-1042" }
}'
GET
/v1/video/rooms/:roomId

Fetch the current state of a room. Prefer webhooks for participant join/leave; use GET for reconciliation, admin tools, and recovery after process restarts.

FieldTypeRequiredDescription
roomIdpath string
required
Room identifier returned at creation (e.g. rm_8f3a2c1b0e9d).
Bash
curl -X GET 'https://api.sendexa.co/v1/video/rooms/rm_8f3a2c1b0e9d' \
-H 'Authorization: Basic YOUR_DASHBOARD_BASE64_TOKEN'
JSON
{
"success": true,
"code": "VIDEO_ROOM_RETRIEVED",
"message": "Room retrieved.",
"requestId": "REQ-1782001000100",
"timestamp": "2026-07-12T10:20:00.000Z",
"data": {
"roomId": "rm_8f3a2c1b0e9d",
"name": "Support Session #1042",
"status": "active",
"maxParticipants": 4,
"participantCount": 2,
"participants": [
{
"identity": "agent-ada",
"role": "host",
"joinedAt": "2026-07-12T10:16:02.000Z",
"publishing": { "audio": true, "video": true, "screen": false }
},
{
"identity": "user_ama",
"role": "participant",
"joinedAt": "2026-07-12T10:16:45.000Z",
"publishing": { "audio": true, "video": true, "screen": false }
}
],
"record": true,
"recordingStatus": "recording",
"region": "af-west",
"metadata": { "ticketId": "TKT-1042" },
"createdAt": "2026-07-12T10:15:00.000Z",
"startedAt": "2026-07-12T10:16:02.000Z",
"endedAt": null,
"emptyTimeoutSeconds": 300
}
}
POST
/v1/video/rooms/:roomId/end

Gracefully terminate the live session: all connected clients are disconnected, media stops, and if record was enabled the composite finalizes. Status becomes ended. You can still GET the room until it is deleted.

Bash
curl -X POST 'https://api.sendexa.co/v1/video/rooms/rm_8f3a2c1b0e9d/end' \
-H 'Authorization: Basic YOUR_DASHBOARD_BASE64_TOKEN' \
-H 'Content-Type: application/json' \
-d '{}'
JSON
{
"success": true,
"code": "VIDEO_ROOM_ENDED",
"message": "Room ended. Participants disconnected.",
"requestId": "REQ-1782001000200",
"timestamp": "2026-07-12T10:45:00.000Z",
"data": {
"roomId": "rm_8f3a2c1b0e9d",
"status": "ended",
"participantCount": 0,
"record": true,
"recordingStatus": "processing",
"startedAt": "2026-07-12T10:16:02.000Z",
"endedAt": "2026-07-12T10:45:00.000Z",
"durationSeconds": 1738
}
}

When recording completes, you receive video.recording.ready.

DELETE
/v1/video/rooms/:roomId

Permanently remove the room resource. Prefer ending first if the session may still be live. Deleting an active room also forces disconnect (same as end) then purges the resource.

Bash
curl -X DELETE 'https://api.sendexa.co/v1/video/rooms/rm_8f3a2c1b0e9d' \
-H 'Authorization: Basic YOUR_DASHBOARD_BASE64_TOKEN'
JSON
{
"success": true,
"code": "VIDEO_ROOM_DELETED",
"message": "Room deleted.",
"requestId": "REQ-1782001000300",
"timestamp": "2026-07-12T11:00:00.000Z",
"data": {
"roomId": "rm_8f3a2c1b0e9d",
"status": "deleted",
"deletedAt": "2026-07-12T11:00:00.000Z"
}
}

Room object fields

FieldTypeRequiredDescription
roomIdstring
required
Globally unique room ID (prefix rm_).
namestringoptionalOptional display name.
statusstring
required
ready | active | ended | deleted
maxParticipantsinteger
required
Configured capacity.
participantCountinteger
required
Current connected participants.
recordboolean
required
Whether recording was requested.
recordingStatusstringoptionalidle | recording | processing | ready | failed | none
regionstring
required
Media region ID (e.g. af-west).
metadataobjectoptionalEcho of create-time metadata.
emptyTimeoutSecondsinteger
required
Seconds before unused ready rooms auto-end.
createdAt / startedAt / endedAtISO 8601optionalLifecycle timestamps.
Session lifecycle
text
create ──► ready ──(first join)──► active ──(/end or empty timeout)──► ended ──(DELETE)──► deleted
│ │
└── emptyTimeout ─────────┘
└── if record=true → recording processing → video.recording.ready

Tokens can only be issued for rooms in ready or active. Joins against ended / deleted fail at the media layer.

HTTP status codes

CodeStatusDescription
200OKRoom returned, ended, or deleted successfully
201CreatedRoom provisioned (create may return 200 or 201)
400Bad RequestInvalid body (capacity, types, metadata size)
401UnauthorizedMissing or invalid Basic Auth
403ForbiddenLive Video not enabled or insufficient plan
404Not FoundUnknown roomId
409ConflictRoom already ended or not in expected state
429Too Many RequestsRate limit exceeded

Next: issue join tokens →