Zoom Skip Waiting Room
Skip the Zoom waiting room by providing the meeting host's ZAK token
Zoom bots join the waiting room by default when a waiting room is enabled. To let the bot skip the waiting room without a host manually admitting it, provide a ZAK token minted for the meeting host via zoom.zak_url.
Prerequisite: Signed-in Zoom bots
Skipping the waiting room builds on signed-in Zoom bots. Implement that flow first: a Zoom OAuth app, a zoom.zak_url callback that returns a plaintext ZAK, and just-in-time token minting.
This guide only changes whose ZAK you mint — it must belong to the meeting host, not a shared service account.
Common mistakeFollowing the Signed-in Bots: Zoom guidance and minting ZAKs from one dedicated service account will not skip the waiting room. That pattern is correct for authenticated-join meetings, but Zoom will still place the bot in the waiting room unless the ZAK belongs to the meeting host.
ZAK tokens are short-lived. Mint them just-in-time when Recall requests your callback — do not pre-generate and cache them for later joins.
Implementation
Step 1: Resolve the host in your zoom.zak_url callback
zoom.zak_url callbackRecall will GET your callback and expects a plaintext ZAK in the response body (not JSON).
The minting mechanics are the same as signed-in Zoom bots. The difference is your callback must resolve the correct host credentials for that bot/meeting (for example via a query parameter you set when creating the bot):
def validate_request(request) -> bool:
"""Validate the authenticity of the request.
https://docs.recall.ai/docs/authenticating-requests-from-recallai
"""
pass
def retrieve_host_zak_token(host_id: str) -> str:
"""Load the host's Zoom OAuth credentials, refresh if needed,
then call Zoom's userZak endpoint and return the token string.
"""
pass
# HTTP handler for https://example.com/recall/callbacks/zak
def http_handler(request):
if not validate_request(request):
return HttpResponse(code=401)
host_id = request.query_parameters["host_id"]
zak_token = retrieve_host_zak_token(host_id)
return HttpResponse(body=zak_token)Step 2: Create the bot with zoom.zak_url
zoom.zak_urlcurl -X POST "https://RECALL_REGION.recall.ai/api/v1/bot/" \
-H "Authorization: Token YOUR_RECALL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"meeting_url": "YOUR_ZOOM_MEETING_URL",
"zoom": {
"zak_url": "https://YOUR_SERVER/recall/callbacks/zak?host_id=HOST_ID"
}
}'When the bot joins, Recall calls your zak_url, receives the host ZAK, and uses it to authenticate the bot so it can skip the waiting room.
FAQ
Can I use a service-account (or any non-host) ZAK to skip the waiting room?
No. For skipping the waiting room, the ZAK must be minted for the meeting host. A foreign-account / shared service-account ZAK will leave the bot in the waiting room.
Does each meeting host need to connect Zoom?
Yes for this guide's host-ZAK flow. Store per-host OAuth credentials and resolve the correct host when your zak_url is called.
At scale (many hosts / white-label tenants), plan for a connect-Zoom step per host (or an account-level Zoom authorization model that can mint that host's ZAK). A single shared Zoom user cannot cover skip-waiting-room for arbitrary external hosts.
Does the host need to already be in the meeting?
No for host ZAK. You can mint and provide the host's ZAK before the host joins.
That differs from OBF tokens, which require the associated user to already be in the meeting and remove the bot if that user leaves.
Why is my bot still in the waiting room?
Check these first:
- Wrong ZAK identity — token was minted for a service account / non-host user
- Host never connected Zoom — no OAuth credentials to mint a host ZAK from
- Stale tokens — expired ZAK or expired underlying OAuth access token
- Bad callback response —
zak_urlreturned JSON, quotes, or an empty body instead of plaintext - Join-token-only config —
join_token_urlwithout a accompanying ZAK/OBF on the Meeting SDK path - Waiting room is expected — if no host ZAK (and no successful join-token+ZAK/OBF path) is configured, the bot behaves like a normal guest
How can I tell that skip-waiting-room worked?
On a successful host-ZAK join, the bot should move from joining into the call without sitting in in_waiting_room waiting for manual admit.
If you see joining_call → in_waiting_room (and especially if you later see recording_permission_allowed only after someone admits the bot), the host ZAK was not applied successfully for that meeting.
Updated about 1 hour ago
