Scheduled & Persistent Rooms

A room is an addressable container a live multi-party call runs inside. Unlike a group, a room is not tied to a member roster, anyone in your app holding the room id can attempt to join, and the room's policy is the gate. "Scheduled" versus "persistent" is not a fixed type, it is simply how you compose the room's knobs. The platform gives you the container and the controls; it imposes no meeting model of its own.

The room model

  • Hosts, the creator plus anyone they designate. Hosts can open a room that requires a host, and gain in-call moderation authority.
  • Schedule, optional scheduledStartAt / scheduledEndAt timestamps. These are metadata, the platform does not enforce a join window, your app drives any countdown or availability UX.
  • Status, ACTIVE or CLOSED. A closed room rejects joins.
  • Policy, the per-room knobs below.

Room policy

  • waitingRoom, non-host joiners are held in the waiting room until a host or co-host admits them.
  • requireHost, non-host joiners cannot open the call, they wait until a host is present.
  • maxParticipants, a per-room participant cap, on top of the plan cap.
  • autoCloseWhenEmpty, the room flips to CLOSED when the last participant leaves, a one-shot meeting. Leave it off for a reusable room.

REST API

POST   /api/rooms              // Create a room
GET    /api/rooms              // List rooms you created or host
GET    /api/rooms/{roomId}     // One room, including live-call state
PATCH  /api/rooms/{roomId}     // Update name / schedule / policy / hosts (creator)
DELETE /api/rooms/{roomId}     // Delete a room (creator)

Authorization: Bearer <droponair-jwt>

Joining the live call

A room has no separate invite step, the first joiner opens the call. joinRoom(roomId) returns a callId, and that callId works with every existing group-call signaling method (SDP/ICE, screen share, moderation, leave) - pass an empty string for the groupId argument. Room-call events arrive on the same group-call event callback and carry roomId. If a host is required but absent, or the room is closed, or the joiner lands in the waiting room, the join resolves to HOST_REQUIRED, ROOM_CLOSED, or WAITING_ROOM_PENDING respectively.

const room = await client.createRoom({
  name: 'Weekly sync',
  scheduledStartAt: Date.now() + 3_600_000,   // metadata only
  policy: { waitingRoom: true, requireHost: true },
});

const callId = await client.joinRoom(room.roomId);
client.sendGroupCallSignal('GROUP_CALL_SDP_OFFER', callId, '', peerUserId, sdp);

Availability. Room counts are plan-controlled (maxRoomsPerApp). See the pricing page for tiers, or your DropOnAir dashboard Subscription page to see what's enabled on your app. Verify support via GET /api/info, the features array includes "scheduled_rooms".

Requires SDK 0.14.0+ on JavaScript, Android, and iOS.