MeetStream — Zoom Authenticated Bots (ZAK and OBF)
MeetStream — Zoom Authenticated Bots (ZAK and OBF)
How to send a MeetStream Zoom bot as a signed-in user (ZAK) or on behalf of a user already in the meeting (OBF).
MeetStream does not store your end-users’ Zoom OAuth refresh tokens for join. You run Zoom OAuth, keep the refresh token, and expose an HTTPS URL. At join, the bot fetches that URL and uses the token you return.
Endpoint: POST /api/v1/bots/create_bot
Auth: Authorization: Token <your MeetStream user API key>
1) Pick a join mode
Do not send use_zoom_obf or zoom_oauth_connection_user_id. Those fields are rejected.
You still save your Zoom Marketplace app client_id / client_secret on the MeetStream user (integrations auth / zoom). That is the Meeting SDK app the bot process runs as. It is not the end-user OAuth grant.
URLs must be https with a host (max 4096 characters). Bots run in AWS and cannot reach localhost.
2) ZAK vs OBF (Zoom behavior)
Enable Meeting SDK on the Zoom General App when using OBF.
OBF tokens are short-lived and single-use. Mint them when MeetStream calls you, not at create-bot time.
3) What you host
Two jobs, both on your HTTPS server:
-
OAuth (once per Zoom user or service account)
Redirect to Zoom authorize → callback withcode→POST https://zoom.us/oauth/token(grant_type=authorization_code) → storerefresh_token. Never send refresh tokens to MeetStream. -
Mint endpoint (every join)
When the bot calls your URL, refresh the access token if needed (grant_type=refresh_token; persist a new refresh token if Zoom returns one), call Zoom’s user-token API, return the ZAK or OBF as plain text.
Encode which user in the URL (user_id, signed token, etc.). Treat the URL as a credential (shared auth query, HMAC, or short-lived signed URL).
4) create_bot examples
Guest (no authenticated Zoom join)
Omit zoom, or send "zoom": {}.
Signed-in (ZAK)
On-behalf-of (OBF)
Join the Zoom meeting yourself first, then create the bot. Do not add meeting_number to obf_url.
The parent must already be in the meeting before the OBF join attempt. A longer waiting-room timeout does not replace that requirement.
5) What MeetStream sends to your URL
The Zoom bot tries GET first. If the server returns 405, or the body cannot be parsed as a token, it POSTs JSON. A 400 on GET is not retried as POST — fix the handler.
Common to both:
ZAK: POST body { "bot_id", "webhook_secret"? }. No meeting_number.
OBF: GET query meeting_number (MeetStream adds this). POST body { "bot_id", "meeting_number", "webhook_secret"? }. Mint with that meeting id.
If you already put meeting_number on obf_url, MeetStream appends it again. Many frameworks then see an array and your handler returns 400 (OBF token is required but could not be fetched). Leave meeting id off the create-bot URL.
6) Test without a bot
After OAuth, curl your own host (replace host, secret, meeting id):
Expect 200 and a long token. 401 without auth is expected if you use a shared secret.
Then create_bot with zak_url or obf_url pointing at the same URL without duplicating meeting_number on OBF.
