Skip to main content
Zoom delivers webhooks through Event Subscriptions, configured once on your Marketplace app.
This guide covers the Zoom integration (authorization code, one end user per connection). For Zoom (Server-to-Server OAuth), see its own webhooks guide instead — the setup differs enough between the two that they’re documented separately.

How it works

  1. Zoom sends a POST request to your Nango webhook URL when a subscribed event occurs on any account that authorized your app.
  2. Nango verifies the delivery’s signature against the Webhook secret on the integration, then matches the event’s payload.account_id against connection_config.accountId on your connections — see step 4.
  3. Nango forwards the event to your app, or triggers a sync.
Zoom’s dashboard can’t scope a multi-tenant app’s Event Subscriptions to one account — the only scope that covers accounts other than your own, “Only for users who have added this app,” applies to every authorizing account collectively and delivers them all to the same single destination URL. There’s no way to register a separate URL per account. This is why account_id-based matching exists: with one shared URL for every tenant, Zoom’s payload itself is the only place a specific account is identified.
Zoom doesn’t expose Event Subscriptions setup through any API — there’s no endpoint to create a subscription, enable an event type, or retrieve the Secret Token. Everything in Setup is a one-time dashboard task, done once per app.

Setup

1. Get your Nango webhook URL

In the Nango dashboard, open your Zoom integration and copy the Webhook URL. Use it as-is, with no query param — every account that authorizes your app sends events here, and Nango matches each one to a connection via account_id.

2. Set the webhook secret in Nango

  1. Go to the Zoom App Marketplace, open your app under Develop → Build App, then go to Features → Access.
  2. Turn on Event Subscriptions. Zoom immediately generates a Secret Token on this page — copy it.
  3. In the Nango dashboard, open your Zoom integration, go to the Settings tab, and paste it into the Webhook Secret field.
Do this before creating any Event Subscription. Zoom validates the destination URL synchronously as part of both creating a subscription and saving the app, and Nango can only answer that validation request once the secret is set — see step 3.

3. Add Event Subscriptions in Zoom

  1. On the same Features → Access page, click Add Event Subscription.
  2. Under Event notification endpoint URL, paste your Nango webhook URL from step 1. Zoom immediately sends a validation request to that URL to confirm you control it — Nango answers this automatically since the Webhook secret is already set. If validation fails, double-check the secret matches the Secret Token from step 2 before retrying.
  3. Under the event subscription’s scope, choose “Only for users who have added this app” — this is the scope that covers every account that connects through your app, not just your own.
  4. Click Add events and select the events you want to receive.
  5. Save the app.
This is a one-time setup — you don’t need to repeat it as new accounts authorize your app.

4. Nango captures your Zoom account id

An authorization-code connection has no Zoom account id stored anywhere by default, so Nango can’t match payload.account_id to one until it’s saved. Nango does this for you automatically: right after a connection is created, a built-in step calls GET /v2/users/me and stores the result as connection_config.accountId on the connection. There’s nothing to set up.
Connections created before this became the default have no connection_config.accountId and won’t receive webhooks. Reconnect them (have the end user go through OAuth again) to trigger this step and start routing correctly — there’s no API to backfill connection_config on an existing connection the way there is for metadata.
This step needs the user:read:user scope (or the legacy user:read scope on older apps) on your Zoom app. Without it, GET /v2/users/me fails silently, connection_config.accountId never gets set, and the connection won’t receive webhooks — with no error surfaced anywhere. Add the scope when registering your app.

Handle the webhook

Once routed, you have two options:
  • Forward it to your app — Nango forwards the event to your webhook URL with connection attribution. See External webhook forwarding.
  • Process it in a sync — run a sync when the webhook arrives using webhookSubscriptions and onWebhook in a sync script. See Real-time syncs.

Payload

Every delivery has the same shape: an event name, an event_ts timestamp, and a payload object carrying account_id plus the affected object (its fields vary by event):

Supported events

event (used as the webhook type for webhookSubscriptions/onWebhook) is one of Zoom’s namespaced event names. Common ones: For the full list across meetings, webinars, recordings, phone, chat, and more, see Zoom’s webhook events reference.

Connection matching

Nango matches payload.account_id against connection_config.accountId on your connections (populated in step 4). If nothing matches payload.account_id, the delivery is still accepted (so Zoom doesn’t see an error and retry), but isn’t routed to any connection.
With no Webhook secret configured, every delivery is rejected outright — it never reaches routing.

Retries and duplicate deliveries

Zoom retries a failed delivery (any non-2xx response) up to 3 times, at +5min, +25min, and +85min. Each attempt, including retries, carries a freshly signed timestamp — not a replay of the original request. Nango also dedupes by the delivery’s x-zm-request-id, which stays the same across retries. If the same delivery arrives again after already being processed, Nango accepts it (so Zoom stops retrying) but doesn’t forward it or re-trigger a sync a second time.

Rollback strategy

To stop deliveries, remove the event notification endpoint (or disable Event Subscriptions entirely) from Features → Access on your app in the Zoom App Marketplace. Re-enable notifications by creating a new subscription with the steps above.
Need help getting started? Join us in the community.