Rooms API
Create real-time video/audio rooms and issue participant tokens (webinars, breakout rooms, multi-host shows). Moderation, lifecycle, recording, and host reactions are available — see Recording for capture endpoints.
Create uses POST /rooms (canonical). PUT /rooms with the same JSON body is accepted as a compatibility alias — PUT /rooms/:id is only for updates.
Create a room
curl -s -X POST https://api.dcast.pro/api/v1/rooms \
-H "Authorization: Bearer pk_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"title": "My Room",
"type": "INSTANT",
"maxParticipants": 50,
"enableRecording": false,
"enableChat": true
}'Get participant token
curl -s -X POST https://api.dcast.pro/api/v1/rooms/{id}/token \
-H "Authorization: Bearer pk_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"participantName": "John",
"participantId": "optional-id",
"isHost": true
}'Body aliases: name is accepted as an alias of participantName, and identity is accepted as an alias of participantId. Canonical wins when both are supplied. At least one of participantName / name is required.
Room types
INSTANT, SCHEDULED, RECURRING, WEBINAR, BREAKOUT, TRANSLATION.
List participants
Canonical pagination shape.
curl -s -H "Authorization: Bearer pk_YOUR_KEY_HERE" \
"https://api.dcast.pro/api/v1/rooms/{id}/participants?page=1&limit=50"
# Response
{
"success": true,
"data": {
"participants": [
{
"id": "...",
"roomId": "...",
"userId": "user_abc",
"displayName": "John",
"role": "HOST",
"status": "JOINED",
"livekitIdentity": "...",
"joinedAt": "2026-05-25T18:42:11.000Z",
"leftAt": null,
"user": { "id": "user_abc", "name": "John", "username": "john", "avatar": "..." },
...
}
],
"pagination": { "page": 1, "limit": 50, "total": 12, "pages": 1 }
}
}Host reaction
Broadcast an emoji reaction from the host to all participants.
curl -s -X POST https://api.dcast.pro/api/v1/rooms/{id}/reactions \
-H "Authorization: Bearer pk_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"emoji":"❤️"}'Body field is emoji. The legacy type field is still accepted for back-compatibility — new integrations should use emoji. Only the room host (or API key owner of the room) may post.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /rooms | List rooms (canonical pagination) |
| POST | /rooms | Create room |
| PUT | /rooms | Alias of POST create (same body) |
| GET | /rooms/:id | Room details |
| POST | /rooms/:id/token | Generate participant token |
| PUT | /rooms/:id | Update room settings (same shape as PATCH) |
| PATCH | /rooms/:id | Update room settings. Response matches GET /rooms/:id shape (no internal columns leak). |
| DELETE | /rooms/:id | Delete room |
| GET | /rooms/:id/participants | List participants (canonical pagination) |
| POST | /rooms/:id/participants/:participantId/admit | Admit from lobby |
| POST | /rooms/:id/participants/:participantId/kick | Remove participant |
| POST | /rooms/:id/participants/:participantId/mute | Mute participant |
| POST | /rooms/:id/start | Start room session |
| POST | /rooms/:id/end | End room session |
| POST | /rooms/:id/record/start | Start recording |
| POST | /rooms/:id/record/stop | Stop recording |
| GET | /rooms/:id/record/status | Recording status |
| POST | /rooms/:id/reactions | Host reaction. Body: {"emoji":"❤️"} (legacy type accepted). |
| Polls (host create / close, anyone vote) | ||
| GET | /rooms/:id/polls | List polls (host-only). |
| POST | /rooms/:id/polls | Create poll. Body: {"question":"...","options":["a","b"],"allowMultiple":false,"showResults":true,"isAnonymous":false} |
| POST | /rooms/:id/polls/:pollId/vote | Vote. Body {"optionId":"opt_1","participantId":"part-1"}. Idempotent (per participantId — re-vote changes choice). |
| POST | /rooms/:id/polls/:pollId/close | Host closes the poll (sets isActive=false, closedAt). |
| Quizzes (host create / close, participants answer once) | ||
| GET | /rooms/:id/quizzes | List quizzes (host-only). |
| POST | /rooms/:id/quizzes | Create. Body: {"question":"...","options":["a","b","c"],"correctOptionId":"opt_2","points":10,"timeLimit":30} |
| POST | /rooms/:id/quizzes/:quizId/answer | Submit. Server computes isCorrect + pointsEarned. 409 ALREADY_ANSWERED on second submission per participant. |
| POST | /rooms/:id/quizzes/:quizId/close | Host closes the quiz. |
Polls & quizzes — quick example
# 1. Host creates a poll
curl -s -X POST -H "Authorization: Bearer pk_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"question":"Best dialect?","options":["LF","CRLF","whatever"]}' \
https://api.dcast.pro/api/v1/rooms/{roomId}/polls
# → 201 with options auto-id'd: [{"id":"opt_1","text":"LF"}, ...]
# 2. Participant votes (idempotent: re-vote with the same participantId updates the choice)
curl -s -X POST -H "Authorization: Bearer pk_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"optionId":"opt_1","participantId":"part-abc"}' \
https://api.dcast.pro/api/v1/rooms/{roomId}/polls/{pollId}/vote
# 3. Host closes — further votes return 409 POLL_CLOSED
curl -s -X POST -H "Authorization: Bearer pk_YOUR_KEY_HERE" \
https://api.dcast.pro/api/v1/rooms/{roomId}/polls/{pollId}/close
# Quizzes follow the same shape but require correctOptionId at create time,
# and answer submissions are single-shot per participant (409 on retry).Recording start preconditions
POST /rooms/:id/record/start starts a LiveKit room-composite egress, which requires at least one publishing participant to be connected. If you call it on a freshly-created room with zero participants, the response is:
HTTP 422
{ "success": false,
"error": {
"code": "PRECONDITION_FAILED",
"message": "Room composite recording requires at least one connected participant. Wait for a publisher to join the room (POST /rooms/:id/token then connect) and retry."
}
}Every precondition answers 422 with the same error.code, PRECONDITION_FAILED; the message names the cause (no connected publisher, no LiveKit session yet — mint a participant token via POST /rooms/:id/token first — or recording not enabled). Other answers:
400 BAD_REQUEST“Room is not live” — the room must beLIVE.503 RECORDING_UNAVAILABLE— the recorder failed to start; retry.
Security & scope
Rooms endpoints are creator-scoped. Foreign room ids return 404 NOT_FOUND. Participant tokens are scoped to a single room and expire on session end. pk_* keys cannot moderate other creators' rooms, cannot harvest participant lists across accounts, and cannot bypass the room's maxParticipants cap.
