Partner API base path is /api/v1 on https://api.dcast.pro. This site documents the live surface; use the Quickstart QA curls to validate keys and routes.

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

MethodEndpointDescription
GET/roomsList rooms (canonical pagination)
POST/roomsCreate room
PUT/roomsAlias of POST create (same body)
GET/rooms/:idRoom details
POST/rooms/:id/tokenGenerate participant token
PUT/rooms/:idUpdate room settings (same shape as PATCH)
PATCH/rooms/:idUpdate room settings. Response matches GET /rooms/:id shape (no internal columns leak).
DELETE/rooms/:idDelete room
GET/rooms/:id/participantsList participants (canonical pagination)
POST/rooms/:id/participants/:participantId/admitAdmit from lobby
POST/rooms/:id/participants/:participantId/kickRemove participant
POST/rooms/:id/participants/:participantId/muteMute participant
POST/rooms/:id/startStart room session
POST/rooms/:id/endEnd room session
POST/rooms/:id/record/startStart recording
POST/rooms/:id/record/stopStop recording
GET/rooms/:id/record/statusRecording status
POST/rooms/:id/reactionsHost reaction. Body: {"emoji":"❤️"} (legacy type accepted).
Polls (host create / close, anyone vote)
GET/rooms/:id/pollsList polls (host-only).
POST/rooms/:id/pollsCreate poll. Body: {"question":"...","options":["a","b"],"allowMultiple":false,"showResults":true,"isAnonymous":false}
POST/rooms/:id/polls/:pollId/voteVote. Body {"optionId":"opt_1","participantId":"part-1"}. Idempotent (per participantId — re-vote changes choice).
POST/rooms/:id/polls/:pollId/closeHost closes the poll (sets isActive=false, closedAt).
Quizzes (host create / close, participants answer once)
GET/rooms/:id/quizzesList quizzes (host-only).
POST/rooms/:id/quizzesCreate. Body: {"question":"...","options":["a","b","c"],"correctOptionId":"opt_2","points":10,"timeLimit":30}
POST/rooms/:id/quizzes/:quizId/answerSubmit. Server computes isCorrect + pointsEarned. 409 ALREADY_ANSWERED on second submission per participant.
POST/rooms/:id/quizzes/:quizId/closeHost 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 be LIVE.
  • 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.

Rooms API — dcast.pro API docs