Files
2026-07-13 12:20:06 +08:00

7.2 KiB

Webhooks - Subscriptions

Configure webhook event subscriptions for real-time notifications.

Overview

Subscribe to Zoom events to receive real-time notifications at your endpoint. This enables:

  • Real-time meeting tracking (started, ended, participant changes)
  • Automated recording processing pipelines
  • User lifecycle management
  • Skill chaining: Combine REST API calls with event-driven workflows

Configuring Subscriptions

  1. Go to your app in Marketplace
  2. Navigate to FeatureEvent Subscriptions
  3. Add subscription name and endpoint URL
  4. Select events to subscribe to
  5. Save and activate

Method 2: Via API (Programmatic Management)

Use the Webhook Subscriptions API for programmatic subscription management.

Create Subscription

POST /webhooks/options
{
  "notification_endpoint_url": "https://your-server.com/zoom/webhook",
  "events": [
    "meeting.started",
    "meeting.ended",
    "meeting.participant_joined",
    "recording.completed"
  ]
}

Get Subscription

GET /webhooks/options

Response:

{
  "notification_endpoint_url": "https://your-server.com/zoom/webhook",
  "events": [
    "meeting.started",
    "meeting.ended",
    "meeting.participant_joined",
    "recording.completed"
  ]
}

Update Subscription

PATCH /webhooks/options
{
  "events": [
    "meeting.started",
    "meeting.ended",
    "recording.completed",
    "user.created"
  ]
}

Subscription Settings

Setting Description Required
notification_endpoint_url Your HTTPS endpoint (must be publicly accessible) Yes
events Array of event types to subscribe to Yes

Event Categories

Meeting Events

Event Trigger
meeting.created Meeting scheduled
meeting.updated Meeting settings changed
meeting.deleted Meeting deleted
meeting.started Meeting begins
meeting.ended Meeting ends
meeting.participant_joined Participant joins
meeting.participant_left Participant leaves
meeting.sharing_started Screen share begins
meeting.sharing_ended Screen share ends

Recording Events

Event Trigger
recording.started Cloud recording begins
recording.stopped Cloud recording paused/stopped
recording.paused Cloud recording paused
recording.resumed Cloud recording resumed
recording.completed Recording processed and available
recording.trashed Recording moved to trash
recording.deleted Recording permanently deleted
recording.recovered Recording restored from trash

User Events

Event Trigger
user.created New user added
user.updated User details changed
user.deleted User removed
user.deactivated User deactivated
user.activated User activated

Webinar Events

Event Trigger
webinar.created Webinar scheduled
webinar.started Webinar begins
webinar.ended Webinar ends
webinar.registration_created New registration

Subscription Object Schema

{
  "notification_endpoint_url": "string (HTTPS URL)",
  "events": ["array of event type strings"],
  "secret_token": "string (for signature verification)"
}

Code Examples

JavaScript - Express Webhook Handler with Subscription Check

const express = require('express');
const crypto = require('crypto');
const axios = require('axios');

const app = express();
app.use(express.json());

// Verify webhook signature
function verifyWebhookSignature(req, secret) {
  const message = `v0:${req.headers['x-zm-request-timestamp']}:${JSON.stringify(req.body)}`;
  const hashForVerify = crypto
    .createHmac('sha256', secret)
    .update(message)
    .digest('hex');
  
  const signature = `v0=${hashForVerify}`;
  return signature === req.headers['x-zm-signature'];
}

// Handle webhook events
app.post('/zoom/webhook', (req, res) => {
  const WEBHOOK_SECRET = process.env.ZOOM_WEBHOOK_SECRET;
  
  if (!verifyWebhookSignature(req, WEBHOOK_SECRET)) {
    return res.status(401).send('Unauthorized');
  }
  
  const { event, payload } = req.body;
  
  switch (event) {
    case 'meeting.started':
      console.log(`Meeting started: ${payload.object.topic}`);
      break;
    case 'meeting.ended':
      console.log(`Meeting ended: ${payload.object.uuid}`);
      break;
    case 'recording.completed':
      processRecording(payload.object);
      break;
  }
  
  res.status(200).send('OK');
});

JavaScript - Manage Subscriptions via API

async function updateWebhookSubscription(accessToken, events) {
  const response = await axios.patch(
    'https://api.zoom.us/v2/webhooks/options',
    { events },
    {
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Content-Type': 'application/json'
      }
    }
  );
  return response.data;
}

// Add new events to subscription
await updateWebhookSubscription(token, [
  'meeting.started',
  'meeting.ended',
  'recording.completed',
  'user.created',  // New event
  'user.deleted'   // New event
]);

Multiple Subscriptions

You can create multiple subscriptions to:

  • Send different events to different endpoints
  • Separate production and development endpoints
  • Organize by event type
  • Route events to different microservices

Skill Chaining

Webhooks are commonly combined with REST API in skill chains:

Chain Pattern Use Case
REST API → Webhooks Create meeting, subscribe to events Track meeting lifecycle
Webhooks → REST API Receive event, fetch details Recording download on completion
Users API → Webhooks Create user, subscribe to user events User lifecycle tracking

Example: Meeting creation with event tracking

// Step 1: Subscribe to meeting events (one-time setup)
await updateWebhookSubscription(token, ['meeting.started', 'meeting.ended']);

// Step 2: Create meeting via REST API
const meeting = await createMeeting(token, { topic: 'Team Standup', type: 2 });

// Step 3: When meeting.started webhook arrives, track it
// Step 4: When meeting.ended webhook arrives, process attendance

See meeting-details-with-events.md for complete skill chaining patterns.

Testing Webhooks

  1. Local development: Use ngrok to expose local endpoint
    ngrok http 3000
    
  2. Webhook logs: Check Marketplace portal → App → Webhooks → Logs
  3. Test endpoint: Validate signature handling before going live
  4. Retry behavior: Zoom retries failed webhooks (5xx responses) up to 3 times

Required Scopes

Scope Operations
webhook:read:admin View webhook settings
webhook:write:admin Modify webhook settings

Resources