How to Set Up a Zoom Meeting Bot with Unified

Updated:


November 7, 2026

Overview

Zoom (meeting bot) (zoommeetingbot) is the integration that gives you a calendar_bot and live calendar_botevents for Zoom meetings. It is separate from the Zoom integration: your existing Zoom connections don't change, and your end users connect Zoom (meeting bot) on its own.

A Zoom meeting bot follows the meeting through Zoom's Realtime Media Streams (RTMS). It does not join as a participant. When Zoom starts the meeting's realtime stream, Unified opens it and sends you, while the meeting runs:

  • Zoom's own meeting captions (TRANSCRIPT_RECEIVED)
  • in-meeting chat to everyone (CHAT_MESSAGE_RECEIVED, when you set record_chat)
  • participant joined, left, speaking, webcam and screen-share events
  • status changes (BOT_STATUS_CHANGE)

After the meeting, when Zoom finishes the cloud recording, the bot gets a recording_id, sends RECORDING_READY, and moves to DONE.

It does not record audio, video or screen shares itself.

The same connection also gives you Zoom's own objects: calendar_calendar, calendar_event, calendar_recording, calendar_webinar, calendar_link, calendar_location, calendar_room and uc_contact. They work as on the Zoom integration, and their scopes are requested only when you select their permissions.

For how to create bots and receive events, see How to Build a Meeting Bot with Unified.


⚠️ Important: you need your own Zoom app

Meeting bots need your own Zoom Marketplace app, with RTMS scopes, and that app's Secret Token saved on the integration in Unified. Unified has no shared Zoom credentials for meeting bots, and creating a bot returns 400 while the Secret Token is missing.

RTMS is available to all developers. It needs a user-managed General app and an active Zoom Developer Pack with credits, which RTMS usage draws on. Zoom's default limit is 2,000 concurrent streams (higher on request; the free trial allows 5). See Zoom's RTMS overview.


What you'll need

  • A Zoom account with access to the Zoom App Marketplace developer tools
  • An active Zoom Developer Pack with credits for RTMS
  • For recordings: cloud recording on the meeting host's Zoom account (Pro or higher)
  • Your Unified workspace ID (shown in the Unified app under Settings)
  • Your Unified region: US (api.unified.to), EU (api-eu.unified.to) or AU (api-au.unified.to)

Step 1: Create the Zoom app

  1. In the Zoom App Marketplace, create a user-managed General app.
  2. Add the Unified redirect URL for your region:
    • US: https://api.unified.to/oauth/code
    • EU: https://api-eu.unified.to/oauth/code
    • AU: https://api-au.unified.to/oauth/code
  3. Copy the app's Client ID and Client Secret. Unified uses them for OAuth and to sign the RTMS connection.

Step 2: Add scopes

Add these scopes to the app:

ScopeUnified permissionWhy
user:read:usercalendar_bot_writeFind the connected user's Zoom account when a bot is created
meeting:read:meetingcalendar_bot_writeRead the meeting when a bot is created
meeting:read:meeting_transcriptcalendar_botevent_readReceive Zoom's meeting captions over RTMS.
cloud_recording:read:list_user_recordingscalendar_recording_readList recordings
cloud_recording:read:list_recording_filescalendar_recording_readRead the recording a bot points to, by id
meeting:read:list_meetingscalendar_event_readList meetings (calendar_event). Creating a bot from an event_id needs only calendar_bot_write.
Among the RTMS scopes, select only meeting:read:meeting_transcript: Zoom's guidance is that an app that only needs meeting transcripts should select only that scope, and RTMS scopes can't be marked optional.

If you select other permissions (calendars, webinars, rooms, contacts), add the same scopes the Zoom integration uses for them. The sign-in scopes the Zoom integration requests (user_profile, user_info:read, user:read) also apply.

Chat: Zoom documents no separate scope name for RTMS chat, so Unified doesn't request one. CHAT_MESSAGE_RECEIVED events arrive only if your app has chat access in RTMS. Zoom only sends the media and session events your app's scopes allow.


Step 3: Subscribe to events

Zoom has no API to register this subscription, so you set it up in the app.

  1. In the app, turn on Event Subscription.
  2. Add these events:
    • under RTMS, RTMS started in Meeting (meeting.rtms_started): starts the live stream
    • under Recording, All Recordings have completed (recording.completed): sets the bot's recording_id, sends RECORDING_READY and moves the bot to DONE
    • under Recording, Recording transcript files have completed (recording.transcript_completed): sends RECORDING_READY again once the transcript is ready. Zoom offers this on Business, Education and Enterprise plans.
  3. Set the endpoint URL to this integration's webhook URL, with your workspace ID:
https://api.unified.to/webhook/workspace/zoommeetingbot?workspace_id=<YOUR_WORKSPACE_ID>

Use api-eu.unified.to or api-au.unified.to if your workspace is in the EU or AU region.

This is the Zoom (meeting bot) URL. Don't use the URL of the Zoom integration.

Zoom validates the endpoint when you save it (endpoint.url_validation). Unified answers that challenge with your Secret Token, so complete Step 4 before you validate the endpoint. Zoom re-validates the endpoint every 72 hours, so keep the Secret Token in Unified current.


Step 4: Enter your credentials in Unified

  1. In the Unified app, open Integrations and activate Zoom (meeting bot).
  2. Enter your Zoom app's Client ID and Client Secret.
  3. Enter the app's Secret Token in the Secret Token field. Unified asks for it when you activate the integration, and the instructions under the field show where to find it: in the Zoom App Marketplace, open Manage, select your app, go to Features and open the Access tab. The Secret Token is not the app's OAuth Client Secret.

The Secret Token verifies every delivery from Zoom: Zoom signs each one with an x-zm-signature header, v0= followed by the hex HMAC-SHA256 of v0:{timestamp}:{body}, and Unified also rejects deliveries older than 5 minutes. That replay window is Unified's own check; Zoom documents none. Unified never sends the Secret Token to Zoom. If you rotate the Secret Token in Zoom, update it in Unified; the change applies within about a minute, including to existing connections.

Without the Secret Token, Unified can't validate the endpoint and refuses every RTMS start.


Step 5: Make sure RTMS starts in meetings

The bot waits in READY until Zoom starts the meeting's realtime stream. That happens when your app is started in the meeting, or when the host has chosen it to start automatically:

  1. Account level: an account admin allows Account Settings → Zoom Apps → Share realtime meeting content with apps. Admins can also add your app under Apps that access content in meetings → + Add app.
  2. User level: the host opens Settings → Zoom Apps in the Zoom web portal, goes to Auto-start apps that access shared realtime meeting content, selects + Choose an app to auto-start, picks your app and saves.

If neither happens, the bot stays READY and no live events are sent.


How end users connect

End users authorize Zoom (meeting bot) through Unified's authorization flow (embedded authorization or the authorization link), the same way they connect any other integration. They grant the scopes above. Connecting Zoom (meeting bot) doesn't change their Zoom connection, and the Zoom connection can't run meeting bots.

A bot can only follow a meeting the connected user's Zoom account can read.


Test the setup

  1. Create a calendar_bot on the connection with the meeting's join link (meeting_url), or with the id of a calendar_event listed on the same connection (event_id, the Zoom meeting ID). The bot is READY.
  2. Create a native webhook for calendar_botevent / created on the same connection.
  3. Start the meeting and start RTMS. You should receive a BOT_STATUS_CHANGE to IN_CALL_RECORDING, then captions and participant events.
  4. End the meeting. You should receive a BOT_STATUS_CHANGE to CALL_ENDED.
  5. If the meeting was recorded to the cloud, you should receive RECORDING_READY and a BOT_STATUS_CHANGE to DONE (sub_code recording_ready) once Zoom finishes the recording.

Limits

  • Unsupported features return 501 (Not supported by this integration: …): join_at (scheduled joins), record_audio, record_video and record_screenshare.
  • Other errors on create: 400 for malformed input, such as a link that isn't a Zoom meeting link or a transcription provider other than MEETING_CAPTIONS; 404 when the meeting doesn't exist; 422 when the connection's Zoom account can't be resolved.
  • Captions only. Live transcription is Zoom's meeting captions (MEETING_CAPTIONS).
  • Recordings need cloud recording on the host's account. A meeting without one stays CALL_ENDED.
  • Reading the recording: get it with GET /calendar/{connection_id}/recording/{recording_id} on the same connection.
  • Recurring meetings: every occurrence has the same meeting ID, and a recording goes to the oldest bot that isn't finished. A CALL_ENDED bot is still waiting for its recording, so create the next occurrence's bot only after the previous bot reaches DONE. If the previous meeting has no cloud recording, delete its bot first.
  • One active bot per meeting link per connection: creating another while an earlier bot for exactly the same link is still active (not CALL_ENDED, DONE or FATAL) returns 409.
  • meeting_url can't change after creation: an update that changes it returns 400. You can update name, event_id and recording_config; a running stream keeps the media it opened with.
  • Reconnects. If the stream drops, Unified reconnects inside Zoom's reconnect windows: about 60 seconds for the signaling connection and about 30 seconds for media. If reconnecting fails, the bot moves to FATAL with sub-code rtms_connection_lost.
  • Chat: only new messages sent to everyone; private messages aren't reported.
  • Speaking: you get PARTICIPANT_SPEECH_ON when the active speaker changes; there is no PARTICIPANT_SPEECH_OFF.
  • Deleting a bot stops the stream. You receive a BOT_STATUS_CHANGE to FATAL (sub-code user_cancelled), then the bot is deleted.

Troubleshooting

❌ Creating a bot returns 400 about the Secret Token

The Secret Token is missing from the Zoom (meeting bot) integration in Unified. Add it (Step 4).

❌ Zoom can't validate the endpoint URL

  • The Secret Token in Unified doesn't match the app's Secret Token, or is missing (it is not the Client Secret)
  • The URL uses the Zoom integration's path instead of zoommeetingbot
  • workspace_id is missing or wrong, or the host is for another region

❌ The bot stays READY

  • RTMS didn't start in the meeting (Step 5)
  • The host hasn't chosen your app to auto-start, or the account admin hasn't allowed sharing realtime meeting content with apps (Step 5)
  • Your Zoom app doesn't have the RTMS scope, or your Zoom Developer Pack has no credits left
  • The RTMS started in Meeting event subscription isn't saved, or points at another URL
  • The Secret Token in Unified doesn't match the app's: Unified rejects Zoom's RTMS start (401) and the bot stays READY

❌ The bot moves to FATAL with session_failed

The RTMS session failed to start or stalled. Check that your app has RTMS access and the scopes in Step 2, and that the Client ID and Client Secret in Unified are correct: Unified signs the RTMS connection with them. The Secret Token isn't involved.

❌ The bot stays CALL_ENDED

  • The meeting wasn't recorded to the cloud, or the host's account has no cloud recording
  • The All Recordings have completed event isn't in the app's event subscription

❌ No chat events

  • record_chat isn't set on the bot's recording_config
  • Your app doesn't have chat access in RTMS
Share
All guidesAccounting Account Type Hierarchy in UnifiedAdvertising Report Metrics by IntegrationAmazon S3: Required IAM PermissionsATS to Vector DB: How to Power Talent Intelligence with Real-Time DataBuilding AI applications with Unified and LangbaseConcur & Concur (Company) — Connection GuideConfigure Greenhouse Native Candidate WebhooksConfigure Salesforce Meetings and Notes for UnifiedConnect Amazon Seller Central to Unified.toConnecting BambooHR via OAuth 2Connecting Google Workspace Integrations with a Service AccountCorrect WelcomeKit Scopes for Jungle IntegrationCreating Ads using the Unified Ads APICreating Walmart Items via UnifiedEnd-Users, Integrations, and ConnectionsEnriching Unified Objects with Custom MetadataEnterprise-managed authorization (EMA) with a static keyEnterprise-managed authorization (EMA) with a workspace secretEnterprise-managed authorization (EMA) with Microsoft Entra IDExtended observability — pushing API logs to ClickHouseExtended observability — pushing API logs to Grafana / LokiExtended Observability - Pushing API Logs to your Datadog InstanceFacebook Messenger Webhook SetupFireflies Integration GuideGetting started with WorkableHandling Delegated vs. Application Scopes in Microsoft IntegrationsHiBob & Unified: connection and time off guideHow long are logs retainedHow to access employees and usersHow to add API support for the Create Activity in CrelateHow to Associate a Connection ID with Your End-UserHow to build a Candidate Assessment product withHow to build a candidate sourcing or job board app with Unified.toHow to build a Discord support bot with Unified.to and LangbaseHow to Build a Fintech Application with Unified's Payments APIHow to Build an E-Commerce Product Integration with UnifiedHow to build an invoicing system with Unified.toHow to build Enterprise Search using RAGHow to configure Bullhorn Redirect URI for creating a connectionHow to configure webhooks in HubSpotHow to configure webhooks in Thrive LearningHow to configure webhooks in Toast for UnifiedHow to Connect Anthropic to Real-Time SaaS Data with Unified.to MCP ServerHow to Connect Cohere to Real-Time SaaS Data with Unified.to MCP ServerHow to Connect Google Gemini to Real-Time SaaS Data with Unified.to MCP ServerHow to connect HiBob (Bob) to Unified with OAuth 2.0How to Connect LLMs to Real-Time SaaS Data with Unified.to MCP ServerHow to Connect OpenAI to Real-Time SaaS Data with Unified.to MCP ServerHow to Connect Zoom and Zoom PhoneHow to create a Connection In Microsoft TeamsHow to create a token-based connection in HighlevelHow to Create a Unified.to Connection to HighLevelHow to Create a Xero Connection in Unified.toHow to create and configure webhooksHow to create Connection with HubspotHow to customize portal URLs for Stripe and GoCardlessHow to filter webhook eventsHow-to Get a Private Support Channel for Your Unified IntegrationHow to get help fromHow to get your 8x8 Connect API Key and Account ID: Step-by-step guideHow to get your ADP Workforce Now Oauth2 client ID, Oauth2 client secret, Oauth2 PEM certificate and Oauth2 private key: Step-by-step guideHow to get your Amazon S3 AWS Region, AWS S3 Key and AWS S3 Secret: Step-by-step guideHow to get your Ashby API Key: Step-by-step guideHow to get your Brex API token: Step-by-step guideHow to get your Bullhorn OAuth2 Client ID, OAuth2 Client Secret, API Username and API Password: Step-by-step guideHow to get your Ceridian Dayforce Username, Password and Client Namespace: Step-by-step guideHow to get your Crelate API key: Step-by-step guideHow to get your Dashlane API Key: Step-by-step guideHow to get your Deel Access Token: Step-by-step guideHow to get your Dialpad API Key: Step-by-step guideHow to get your Discord OAuth 2 credentials and bot tokenHow to get your ELMO client ID and client secret: Step-by-step guideHow to get your Gainsight Client ID, Client Secret and Gainsight API Domain: Step-by-step guideHow to get your Greenhouse API Key and Job board token: Step-by-step guideHow to get your Helpscout API Key: Step-by-step guideHow to get your HiBob Service User ID and Service User Token: Step-by-step guideHow to get your HighLevel API Key and Location ID: Step-by-step guideHow to get your HubSpot developer key and OAuth 2 credentials (Legacy Apps)How to get your Humaans API Key: Step-by-step guideHow to get your iCIMS API Username, API Password and Customer ID: Step-by-step guideHow to get your JobDiva Client ID, Username/email and Password: Step-by-step guideHow to get your Jobvite API Key, API Key Secret and Email: Step-by-step guideHow to get your Lever API Key: Step-by-step guideHow to get your Loxo Agency slug, API Key and Agency ID: Step-by-step guideHow to get your Microsoft Active Directory / Entra ID Client ID, Client Secret and Tenant ID: Step-by-step guideHow to get your Microsoft Azure AD OAuth 2 credentialsHow to get your OAuth 2 credentials for GmailHow to get your OAuth 2 credentials for Microsoft Dynamics 365How to get your OAuth 2 credentials in PipeDriveHow to get your OpenAI API Key: Step-by-step guideHow to get your Paycom SID/Username and Token/Password: Step-by-step guideHow to get your PCRecruiter Username, Password, Database ID, App Key and App ID: Step-by-step guideHow to get your SAP SuccessFactors (OpenID Connect) Username, Password, Client ID, Client Secret, Dependency Name, IAS Host and API URL: Step-by-step guideHow to get your SAP SuccessFactors Username, Company ID, Password and API URL: Step-by-step guideHow to get your Shopify Admin API access token and Store ID: Step-by-step guideHow to get your Wayfair Client ID, Client Secret and Vendor Encrypted Key: Step-by-step guideHow to get your Workable API Token and Subdomain: Step-by-step guideHow to get your yotpo APP Key / Store ID and Secret Key: Step-by-step guideHow to Handle Attachments in Invoice, Bill and Credit MemoHow to migrate or import your integrations into Unified.toHow to obtain your GitHub OAuth2 credentialsHow to Power Claude with Live Customer Data Using Unified MCPHow to receive assessment orders from an ATS with Unified.toHow to register a Google developer app and get OAuth 2 credentialsHow to register a Salesforce developer app and get OAuth 2 credentialsHow to register a Slack developer account and get OAuth 2 credentialsHow to Register a Workday Developer App and Get OAUTH2 CredentialsHow to Register a Workday Developer App and Get OAUTH2/ SOAP CredentialsHow to Register a ZendeskSell Developer App and Get OAUTH2 CredentialsHow to Register a Zoho Developer App and Get OAUTH2 CredentialsHow to Register an ADP Developer App and Get OAUTH2 CredentialsHow to Register an Atlassian Developer App and Get OAUTH2 CredentialsHow to Register your Facebook OAuth2 ApplicationHow to Register your Google Ads OAuth2 ApplicationHow to Register your MetaAds OAuth2 applicationHow To Request & Write Raw Integration DataHow to Retrieve Microsoft Dynamics 365 Business Central CredentialsHow to set up a custom API URL with a CNAMEHow to Set Up a Google Meet Meeting Bot with UnifiedHow to set up a HiBob marketplace installHow to Set Up a Microsoft Teams Bot with UnifiedHow to Set Up a Microsoft Teams Meeting Bot with UnifiedHow to Set Up a Webex Meeting Bot with UnifiedHow to set up and configure NotionHow to set up Google Business Profile API access and get OAuth 2 credentialsHow to Set Up LinkedIn Webhooks with UnifiedHow to set up native webhooks for QuickBooks Online with UnifiedHow to set up Slack webhooks using event subscriptionsHow to set up Telegram (bot) with Unified.toHow to set up your scopes in HubSpotHow to setup a Freshbooks developer appHow to setup a TikTok Shop applicationHow to Setup AWS Assume Role for AWS Secret ManagerHow to setup Oracle JD EdwardsHow to Setup Quickbooks DesktopHow to setup Sage 100 with Unified.toHow to test webhooks in the Synthetic Data (Sandbox) environmentHow to troubleshoot unhealthy connectionsHow to troubleshoot unhealthy webhooksHow to use SCIM with the Unified APIHow to use the Passthrough APIHow to Use Unified.to's Generative AI API with OpenAI and ClaudeHow to use User Provisioning and Verification with UnifiedHow virtual webhook retry and recovery worksIntegration set-up guide for LeverManaging custom validation rules in SalesforceNetSuite Authentication Setup for UnifiedNotice of Deprecation of Fields and Objects (Nov 2025)Oracle HCM / Taleo OAuth Credentials GuideRetrieval-Augmented Generation (RAG)SalesForce (External Client Apps) on Multiple OrganizationsSAML Single-Sign-OnScaling MCP Tools with Anthropic's (& OpenAI's) Defer LoadingSet Environments for your Unified.to WorkspaceSetting up a Slack Bot Connection with Unified.toSetting up OAuth 2 Credentials for Greenhouse's APIsTrello Connection Guide in UnifiedUnderstanding OAuth2 Authorization flowsUnderstanding Response Time Headers in the Unified APIUnified Assessment API: Embed Assessments Inside ATS PlatformsUnified's MCP ServerUnified MCP Server with LangChain and LangGraphUnlock real-time data with virtual webhooksUse Unified to sign in your users into your applicationVincere OAuth Setup Guide for UnifiedWorkable: Creating candidates and attaching them to jobsWorkday vs Workday Legacy — Why Unified.to Supports BothWorking with hierarchical tree data in Storage, Messaging, and KMS APIs
Are we missing anything? Let us know
Was this page helpful?