Top of pageSkip to main content

Using webhooks

Zoom utilizes webhooks as a medium to notify third-party applications (consumer applications) about events that occur in a Zoom account. Instead of making repeated calls to pull data frequently from the Zoom API, you can use webhooks to get information on events that happen in a Zoom account.

Event notifications are sent as HTTP POST requests in JSON to the endpoint you specify in your Marketplace app.

On This Page

Set endpoint URL

Set your Event notification endpoint URL for each event subscription in your Marketplace app. Be sure that it satisfies the Webhook endpoint requirements.

Webhook App on Marketplace Endpoint URL

Webhook endpoint requirements

To receive Webhooks in development and production environments, the Event notification endpoint URL that you specify for each event subscription must:

  • Employ the https:// scheme.
  • Support TLSv1.2+ with a valid certificate chain. The certificate of your webhook endpoint must be issued by a Certificate Authority (CA). Zoom validates the certificate on the configured URL provided by the server. Zoom will not deliver the event request if the certificate isn't valid.
  • Be a fully qualified domain name (FQDN).
  • Be able to accept HTTP POST requests containing JSON payloads.
  • Must be able to respond with an HTTP Status Code.

Objects, actions, and events

Objects are pieces of data that form the resources provided by Zoom, such as Zoom APIs and webhooks. An event occurs when a user performs an action that causes a change in the value of an object. Events are grouped into the following types:

  • Meeting
  • Webinar
  • Recording
  • Zoom Rooms
  • User
  • User Activity
  • Account
  • Zoom Phone
  • TSP
  • Billing
  • Chat Channel
  • Chat Message

Each Zoom event type is comprised of multiple webhook events. These webhook events are defined by a common $object.$action naming rule.

For example, the user webhook object consists action values such as:

  • activated
  • created
  • deactivated
  • deleted
  • disassociated
  • updated

One of the User webhook events is the user.created event. This webhook triggers when a user is created on a Zoom account that is subscribed to the User has been created event in the User event type.

To enable webhooks for these events, you must add Event Subscriptions to your Marketplace app. Refer to the Enable webhooks section for information on enabling webhooks with event subscriptions for each app type.

Chatbot events

You can also receive events for Chatbot actions. For example, when users:

Enable webhooks

You can enable webhooks in any of the following Zoom App Marketplace app types:

Set Endpoint URL

Set your Event notification endpoint URL for each event subscription in your Marketplace app. Be sure that it satisfies the webhook endpoint requirements.

Zoom webhook endpoint URL

Webhook Endpoint URL Requirements

To receive webhooks in development and production environments, the Event notification endpoint URL that you specify for each event subscription must:

  • Be a publicly accessible https endpoint url that supports TLSv1.2+ with a valid certificate chain issued by a Certificate Authority (CA).
  • Be able to accept HTTP POST requests.
  • Be able to respond with a 200 or 204 HTTP Status Code.

Webhook structure

Webhooks requests contain request headers and a request body.

Request headers

Webhooks sent by Zoom contain the following headers:

KeyValue Description
hostThe server where the request is being sent.
user-agentThe identifier of the application that is sending the request. For example, Zoom Marketplace/1.0a
content-typeThe resource's media type. For example, application/json; charset=utf-8
content-lengthThe content length of the HTTP request body, in bytes.
clientidThe client ID of your Marketplace application.
authorizationThis header is unique to your app and confirms the request was sent from Zoom using the webhook verification token on the Add feature page for your Marketplace app. The Verification Token will be deprecated in October 2023. We recommend that you replace your webhook verification token logic with the logic using the x-zm-signature header and the webhook secret token.
x-zm-signatureThe encrypted authorization header used to verify that webhook requests come from Zoom.
x-zm-request-timestampThe time the request was sent, in epoch format.
x-zm-trackingidA unique ID that Zoom uses to identify the request.

Request body

The webhook request body includes the event type (event), the event details (payload), and the timestamp (event_ts) of when the event occurred.

KeyValue TypeValue Description
eventstringThe type of the webhook event.
payloadobjectThe event details. See the reference guides for details, for example, Zoom Meeting, Phone, or Video SDK.
event_tsnumberThe timestamp of the webhook event.

IP addresses

We strongly recommend that you Verify webhook events instead of creating an allow list of IP addresses because Zoom may update the IP ranges used at any time.

If you must create an allow list by IP Address, Zoom uses the following to send event notifications:

3.80.20.128/25
3.235.82.0/23
18.205.93.128/25
52.61.100.253
52.61.100.254
134.224.0.0/16
144.195.0.0/16
170.114.0.0/16

Verify webhook events

Zoom includes a webhook secret token on the Add Feature page for your app. Zoom uses the value of the secret token to hash the webhook data, which it sends in the x-zm-signature webhook request header.

To verify that Zoom sent a webhook request, use the webhook secret token and the webhook request body to create a signature to compare with the x-zm-signature header value sent by Zoom.

Zoom webhook secret token

See the following steps to create your signature string to compare with the Zoom webhook x-zm-signature header value.

1. Receive the webhook request

The webhook request body includes the following properties:

KeyValue TypeValue Description
eventstringThe type of the webhook event
payloadobjectContains the event webhook details
event_tsnumberThe timestamp of the webhook event.

Here's an example:

{
  "event": "session.started",
  "payload": {
    "account_id": "{ACCOUNT_ID}",
    "object": {
      "start_time": "2022-07-27T16:56:34Z",
      "id":"{SESSION_ID}"
    }
  },
  "event_ts": 1658940994914
}

2. Construct the message

After receiving a webhook request, construct the message string with "v0", the webhook request header x-zm-request-timestamp value, and the webhook request body. Separate each section with a colon :. For example:

v0:{WEBHOOK_REQUEST_HEADER_X-ZM-REQUEST-TIMESTAMP_VALUE}:{WEBHOOK_REQUEST_BODY}

Example string with printed values:

v0:1658940994:{"event":"session.started","payload":{"account_id":"{ACCOUNT_ID}","object":{"start_time":"2022-07-27T16:56:34Z","id":"{SESSION_ID}"}},"event_ts":1658940994914}

3. Hash the message

Once you have constructed the message string, create a HMAC SHA-256 hash. Set your webhook's secret token as the secret/salt, and the message you constructed as the string to hash. Output in hex format.

4. Create the signature

Then, create the signature by prepending v0= to the hashed message. For example:

v0={HASHED_MESSAGE}

Example string with printed values:

v0=a05d830fa017433bc47887f835a00b9ff33d3882f22f63a2986a8es270341

5. Compare the signature

Now compare the signature you created with the Zoom webhook request header x-zm-signature value. If it matches, the webhook request came from Zoom.

Here is an example in Node.js:

const crypto = require('crypto')

const message = `v0:${request.headers['x-zm-request-timestamp']}:${JSON.stringify(request.body)}`

const hashForVerify = crypto.createHmac('sha256', ZOOM_WEBHOOK_SECRET_TOKEN).update(message).digest('hex')

const signature = `v0=${hashForVerify}`

if (request.headers['x-zm-signature'] === signature) {
  // Webhook request came from Zoom
} else {
  // Webhook request did not come from Zoom
}

See the Webhook sample app for an example implementation.

Validate your webhook endpoint

Zoom requires that you manually trigger webhook validation when you add a new webhook or make changes to an existing one. Subsequently, Zoom will automatically revalidate webhooks every 72 hours.

Zoom uses a challenge-response check (CRC) for webhook validation. When a CRC occurs, Zoom will make a POST request to your endpoint with a challenge request body. After your endpoint receives the request, your app needs to respond with the challenge response within 3 seconds.

To trigger the initial CRC validation, click Validate under the Event Notification Endpoint URL on the Feature page for your app. See Revalidation for revalidation details.

Zoom webhook validate

See the following steps to handle the challenge-response check flow.

1. Receive the challenge (webhook request body)

The webhook request body includes the following properties:

KeyValue TypeValue Description
eventstringThe type of the webhook event, which will be "endpoint.url_validation"
payloadobjectContains a property with the plainToken value, the string to hash.
event_tsnumberThe timestamp of the webhook event.

Here's an example:

{
  "payload": {
    "plainToken": "qgg8vlvZRS6UYooatFL8Aw"
  },
  "event_ts": 1654503849680,
  "event": "endpoint.url_validation"
}

2. Hash the plainToken

Once you receive the request body, create a HMAC SHA-256 hash. Set your webhook's secret token as the secret/salt, and the plainToken value as the string to hash. Output in hex format.

3. Create the response JSON object

Create a JSON object with a key of "plainToken" with a value of the plainToken from the request body, and a key of "encryptedToken" with a value of the hashed plainToken. For example:

{
  "plainToken": "qgg8vlvZRS6UYooatFL8Aw",
  "encryptedToken": "23a89b634c017e5364a1c8d9c8ea909b60dd5599e2bb04bb1558d9c3a121faa5"
}

4. Respond with the response JSON object

Respond with the response JSON within 3 seconds with a 200 or 204 HTTP response code.

When Zoom successfully validates the challenge response from your webhook endpoint URL, you'll see a validated message under the Event Notification Endpoint URL. If validation fails, you'll see a failed to validate message. Once you successfully complete validation, click Save.

Zoom webhook validate success

Here is an example in Node.js:

const crypto = require('crypto')

// Webhook request event type is a challenge-response check
if(request.body.event === 'endpoint.url_validation') {
  const hashForValidate = crypto.createHmac('sha256', ZOOM_WEBHOOK_SECRET_TOKEN).update(request.body.payload.plainToken).digest('hex')

  response.status(200)
  response.json({
    "plainToken": request.body.payload.plainToken,
    "encryptedToken": hashForValidate
  })
}

See the Webhook sample app for an example implementation.

Revalidation

Your production and development webhook URLs will be revalidated periodically every 72 hours. Zoom will send notification emails to the account owner associated with your apps if the URL fails the revalidation, following this schedule:

  • First notification email after a total of 2 consecutive failed revalidations.
  • Second notification email after a total of 4 consecutive failed revalidations.

If the revalidation check fails 6 times in a row, Zoom will stop sending event notifications to the webhook URL and disable it. To enable the webhook URL to receive event notifications again, see the following steps:

  1. Fix the issue that caused your webhook URL validation to fail.
  2. If you changed the URL, update the Event Notification Endpoint URL on the Feature page on the Zoom App Marketplace.
  3. Click Validate to manually re-validate the URL. If successful, you should see that it is valid.
  4. Click Save to save changes. If this is a private app not shared on the Marketplace, Zoom will re-enable your webhook after this step.
  5. If your app is a published app on the Zoom Marketplace, resubmit your app for review. After the review is completed, Zoom will re-enable your webhook.

Notification delivery

Your webhook endpoint URL should respond with either a 200 or a 204 HTTP status code within three seconds after receiving a webhook request in order for Zoom to consider the notification was successfully delivered.

Unsuccessful delivery

For any unsuccessful notification deliveries, Zoom attempts to deliver the webhook three times:

  • The first attempt is sent five minutes after the initial delivery attempt.
  • A second attempt is sent 30 minutes after the first attempt.
  • A third attempt is sent 90 minutes after the second attempt.

If a 200 or a 204 response is received after any retry attempt, then Zoom considers the notification was successfully delivered.

However, if Zoom does not receive a 200 or a 204 response after three attempts, then no further webhooks for that event will be sent.

Delivery latency

The event_ts response is included in the payload of all event notifications. This represents the timestamp for when the associated event occurred.

You can determine the latency in webhook delivery by calculating the difference between the delivery timestamp and the value of the event_ts.

Need help?

If you're looking for help, try Developer Support or our Developer Forum. Priority support is also available with Premier Developer Support plans.