Skip to main content
Daily’s knock-to-join feature lets you gate entry to a room. Participants who arrive are held in a waiting state until an owner explicitly admits them. This guide covers room configuration, the waiting participant flow, and the admin flow.

Room configuration

Knock-to-join requires two properties on the room:
Any participant who joins with a meeting token — no matter their permissions — bypasses the lobby and enters the call directly. Only tokenless participants are placed in the lobby.

Using Prebuilt

If you’re using Daily Prebuilt, the lobby UI is built in. Once the room is configured above, also set enable_prejoin_ui on the room, domain, or meeting token and you’re done — Daily handles the waiting room experience for you. The rest of this guide covers building a custom lobby UI with the call object API.

Waiting participant flow

1

Join the room

Call join() without a token. The participant lands in the lobby and accessState() returns { access: { level: 'lobby' } } — they are connected but hidden from other participants.
2

Request access

Call requestAccess() with a display name. This notifies admins and adds the participant to the waiting list. The returned Promise blocks until the request is decided — you can use the return value directly:
3

Alternatively, use events

If you need to react to access changes in multiple places (e.g. updating different parts of your UI), the event-based approach may be a better fit. access-state-updated fires when access is granted; a fatal error event with error.type === 'not-allowed' fires when access is denied.

Admin flow

1

Join with admin permissions

Join with a meeting token that grants canAdmin: ['participants'] (or is_owner: true). Either bypasses the lobby and enters the call directly.
See meeting token permissions for how to create a token with canAdmin.
2

Handle participants already waiting

Call waitingParticipants() immediately after joining to catch anyone who arrived before you.
Each waiting participant is a DailyWaitingParticipant:
3

Listen for new arrivals

Subscribe to lobby events to keep your UI in sync:
4

Admit or deny participants

Use updateWaitingParticipant() to act on one participant, or updateWaitingParticipants() to act on many at once.

Complete example

Open https://localhost?t=YOUR_ADMIN_TOKEN for the admin view, or https://localhost (no token) for the waiting participant view.