Build
Rooms: Live Video and Voice
Create and manage VoltKit RTC rooms: hosts and co-hosts, admitting viewers, moderation, room metadata, lifetime and the limits that apply.
A room is a live conversation with sub-second latency. Hosts and co-hosts publish camera and microphone; everyone else watches and listens, and can be brought on stage at any time.
Use a room when viewers may become speakers. When they will not, and there may be a very large number of them, use Broadcast instead.
Create a room
curl -X POST "$VOLTKIT_RTC_URL/v1/rooms" \
-H "X-API-Key: $VOLTKIT_RTC_SECRET" \
-H "Content-Type: application/json" \
-d '{"roomId":"show-42","hostIdentity":"user-7"}'
roomId is optional; leave it out and one is generated. It may be 1 to 128 letters, digits, dots, dashes or underscores.
The reply carries a hostToken for the host and the wsUrl clients connect to.
Create or rejoin in one call
POST answers 409 room-exists when the id is taken, which is right for "create this". For "go live", where the host may be reconnecting after a dropped call, use PUT:
curl -X PUT "$VOLTKIT_RTC_URL/v1/rooms/show-42" \
-H "X-API-Key: $VOLTKIT_RTC_SECRET" \
-H "Content-Type: application/json" \
-d '{"hostIdentity":"user-7"}'
It returns 201 when it created the room and 200 with a fresh host token when the room already existed.
Admit people
Mint one token per person, with the role your backend decides:
curl -X POST "$VOLTKIT_RTC_URL/v1/rooms/show-42/tokens" \
-H "X-API-Key: $VOLTKIT_RTC_SECRET" \
-H "Content-Type: application/json" \
-d '{"identity":"user-99","role":"viewer"}'
Roles are host, cohost, moderator and viewer. See Authentication for what each may do.
See who is in a room
curl "$VOLTKIT_RTC_URL/v1/rooms/show-42" -H "X-API-Key: $VOLTKIT_RTC_SECRET"
curl "$VOLTKIT_RTC_URL/v1/rooms/show-42/participants" -H "X-API-Key: $VOLTKIT_RTC_SECRET"
curl "$VOLTKIT_RTC_URL/v1/rooms" -H "X-API-Key: $VOLTKIT_RTC_SECRET"
The first returns the room with its participants and published tracks; the last lists every live room in your project. To be told about joins and leaves as they happen, use Webhooks rather than polling.
Bring a viewer on stage
A viewer raises their hand; the host accepts and promotes them to co-host. From the client SDK:
await viewer.raiseHand({ requestRole: "cohost" }); // the viewer asks
await host.promote("user-99", "cohost"); // the host says yes
await host.promote("user-99", "viewer"); // and later, back to the audience
A promoted viewer may reconnect onto the publishing node; the SDK handles that. Ask the user to start their camera and microphone after acceptance, then publish once ready. roleChanged is authoritative. The demo allows three co-hosts and six total people; a promotion does not free an audience place.
Moderation
The host can manage non-host participants. Moderators can mute/remove viewers and handle hands; only the host assigns roles or ends the room. From the client:
| Action | SDK call | Effect |
|---|---|---|
| Mute a microphone | forceMute(identity, "audio", true) | Blocked on the server. The participant cannot switch it back on themselves. |
| Release a microphone | forceMute(identity, "audio", false) | Allows its owner to turn it on; does not activate it for them. |
| Pause/release camera and screen | forceMute(identity, "video", true/false) | The same moderation rule applies to video sources. |
| Remove someone | kick(identity, reason) | Disconnected at once |
| Change a role | promote(identity, role) | Takes effect immediately |
| End the room | endRoom() | Host only. Everyone is disconnected. |
Handle pending hands with lowerHand(identity) to decline; acceptance through promote() clears the request with reason granted. A viewer may cancel with lowerHand(). Moderation is enforced by the service, not by the app. A modified client cannot unmute itself or ignore a removal.
Room metadata
Attach your own data to a room when you create it, such as a layout or a title:
curl -X POST "$VOLTKIT_RTC_URL/v1/rooms" \
-H "X-API-Key: $VOLTKIT_RTC_SECRET" \
-H "Content-Type: application/json" \
-d '{"roomId":"show-42","hostIdentity":"user-7","metadata":{"layout":"grid","title":"Friday live"}}'
Every client receives it when it joins. The service never reads it.
How long a room lasts
- A room that people have left closes shortly after the last one leaves (30 seconds by default), and its id becomes free to use again.
- A room nobody has joined yet is kept longer (10 minutes by default), so you can create it before the host has finished loading the page.
- End one yourself with
DELETE /v1/rooms/{roomId}.
When a room closes, its chat history goes with it.
Limits
Each project has a ceiling on concurrent rooms and on viewers per room, shown on the Settings tab of the project. Past them, the API answers:
| Status | Code | Meaning |
|---|---|---|
429 | room-quota | The project is at its concurrent room limit |
429 | viewer-quota | The room is at its viewer limit |
503 | capacity-exhausted | The service has no capacity for a new room right now. Retry shortly. |
Ask support to raise a limit.
Last updated . Something unclear or wrong? Tell us.