Zoom Meeting Bots

Send API-controlled bots into Zoom meetings to record, transcribe, and interact

View as Markdown

MeetStream bots join Zoom meetings through the Zoom Meeting SDK. Zoom is the one platform that needs a one-time setup (Google Meet and Microsoft Teams work with zero configuration) — after that, sending a bot is the same single create_bot call as everywhere else.

curl -X POST "https://api.meetstream.ai/api/v1/bots/create_bot" \
-H "Authorization: Token <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"meeting_link": "https://zoom.us/j/123456789",
"bot_name": "Notetaker"
}'

One-time setup

  1. Create a General App in the Zoom App Marketplace (Develop → Build App → General App). User-managed or admin-managed both work.
  2. Under Features → Embed, enable Meeting SDK.
  3. Save the app’s Client ID and Client Secret in MeetStream Dashboard → Integrations → Zoom. These identify the bot’s Meeting SDK app.
  4. For authenticated joins, configure your own OAuth callback and HTTPS token mint endpoint as described below.

Full walkthrough: Zoom Marketplace App Setup.

Development-mode limitation: with development credentials your bot can only join meetings hosted by your own Zoom account. For external meetings, configure the appropriate ZAK or OBF join and submit the app for production approval — see Zoom App Production Submission. Approval does not replace join-time authorization.

Guest, signed-in, and on-behalf-of joins

zoom payloadJoin mode
Omitted or {}Guest, subject to Zoom’s admission and app authorization rules
{"zak_url": "https://api.yourapp.com/zoom/zak?user_id=alice&auth=YOUR_SECRET"}Signed in as the user whose ZAK you mint
{"obf_url": "https://api.yourapp.com/zoom/obf?user_id=alice&auth=YOUR_SECRET"}Assistant associated with a parent user already in the meeting

Send only one token URL. MeetStream fetches it at join time; your HTTPS server runs OAuth, stores refresh tokens, and mints the token. MeetStream does not store end-user Zoom OAuth refresh tokens for join.

For OBF, the parent must already be in the meeting and the bot is removed when that parent leaves. Do not put meeting_number on obf_url: MeetStream appends it. Mint the short-lived, single-use token when called.

use_zoom_obf and zoom_oauth_connection_user_id are rejected. See Zoom Authenticated Bots for payloads, scopes, the mint endpoint contract, and troubleshooting.

The recording permission flow

Zoom is the only platform where recording is gated on host consent. After bot.inmeeting, the bot requests recording permission and waits — so there can be a visible gap before bot.recording (on Meet and Teams it fires within about a second).

  • Host grants → bot.recording_permission_allowedbot.recording
  • Host denies, or doesn’t respond within recording_permission_denied_timeoutbot.recording_permission_deniedbot.leavingbot.stopped (a clean stop, not bot.denied)

recording_permission_denied_timeout accepts 60–300 seconds (default 60) and is ignored on the other platforms.

Zoom-specific behavior at a glance

BehaviorOn Zoom
SetupOne-time Marketplace app + dashboard credentials
Recording startGated on host permission (see above)
waiting_room_timeout60–1200s, default 600 → bot.notallowed if never admitted
Per-participant audioFull isolation — the Zoom SDK provides a dedicated raw PCM stream per participant, so each file contains only that speaker’s microphone. The cleanest per-participant files of any platform.
Per-participant videoWebcam 640×360 fixed @ 300 kbps; screen share at native resolution @ 1.5 Mbps; 1 concurrent screen share
Screenshots endpointNot supported on Zoom bots
Native captions (meeting_captions)Not available on Zoom — use any other transcription provider
Chat + imagessend_message and send_image inject chat and visuals into the live meeting

Troubleshooting joins

The usual causes when a Zoom bot fails to join:

  • Invalid or expired meeting link
  • App still in development mode and the meeting isn’t hosted by your account
  • Bot stuck in the waiting room until waiting_room_timeout fired (bot.notallowed)
  • Password-protected meeting link missing its ?pwd= component
  • ZAK/OBF: your mint URL failed; check HTTPS reachability, endpoint authentication, and your server’s Zoom OAuth grant
  • OBF: the parent is absent, or meeting_number was duplicated on the mint URL

Watch it live with meetstream listen or the Debugging guide.

Next steps

Zoom FAQ

Recording on Zoom is gated on host consent. If the host doesn’t grant permission within recording_permission_denied_timeout (60s default, max 300), the bot leaves cleanly with bot.stopped. Watch for bot.recording_permission_allowed / denied webhook events.

Your Zoom Marketplace app is still in development mode. Submit it for production approval and configure ZAK or OBF for external meetings.

Run OAuth on your server and pass zoom.zak_url or zoom.obf_url at create_bot. See Zoom Authenticated Bots.

Zoom is the only platform whose SDK provides a dedicated raw PCM stream per participant — full isolation, each file contains only that speaker’s microphone.