Generated banner for Setup Zoom Webhooks
Generated logo for Setup Zoom Webhooks

Setup Zoom Webhooks

AnthropicOfficialCreated by ZoomDistributed by Anthropic

  • Skill
  • Tool integration
  • Automation and integrations
  • MIT
  • No issues found

From the author

Reference skill for Zoom webhooks. Use after routing to an event-driven workflow when implementing subscriptions, signature verification, delivery handling, retries, or event-type selection.
— the description by Zoom

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a technical reference for integrating Zoom webhooks into applications. It covers the essential steps for setting up event subscriptions, verifying incoming webhook signatures using HMAC, and handling event payloads. The documentation includes code examples for signature verification, a list of common event types, and links to community-maintained repositories for various programming languages.

What it does

  • Provides code patterns for verifying Zoom webhook signatures using HMAC-SHA256.
  • Lists common Zoom event types for meetings, recordings, users, and webinars.
  • Outlines prerequisites for receiving webhooks, including HTTPS endpoints and secret tokens.
  • Offers guidance on environment variable management for webhook secrets.
  • Links to official and community-contributed sample implementations across multiple languages.

When to use it

  • When setting up a new webhook listener for Zoom events.
  • When implementing signature verification to secure your webhook endpoint.
  • When troubleshooting issues with event delivery or payload parsing.
  • When looking for language-specific examples of Zoom webhook handlers.

Advantages

  • Centralizes essential configuration and security patterns for Zoom webhooks.
  • Provides a clear, reusable code pattern for signature verification.
  • Includes a comprehensive reference for event types and payload structures.
  • Connects developers to a variety of community-tested implementation samples.

Usage examples

“How do I verify a Zoom webhook signature in Node.js?”
The skill provides an Express.js code snippet demonstrating how to capture the raw request body and use crypto.createHmac to validate the x-zm-signature header.
“What events are available for Zoom recordings?”
The skill lists recording-related events such as recording.started, recording.completed, and recording.trashed.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/anthropics/setup-zoom-webhooks/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip setup-zoom-webhooks.zip -d .agents/skills

Documentation by Zoom

/setup-zoom-webhooks

Background reference for Zoom event delivery over HTTP. Prefer workflow skills first, then use this file for verification, subscription, and delivery details.

Prerequisites

  • Zoom app with Event Subscriptions enabled

  • HTTPS endpoint to receive webhooks

  • Webhook secret token for verification

Need help with authentication? See the zoom-oauth skill for OAuth setup.

Quick Start

// Express.js webhook handler
const crypto = require('crypto');

// Capture raw body for signature verification (avoid re-serializing JSON).
app.use(require('express').json({
  verify: (req, _res, buf) => { req.rawBody = buf; }
}));

app.post('/webhook', (req, res) => {
  // Verify webhook signature
  const signature = req.headers['x-zm-signature'];
  const timestamp = req.headers['x-zm-request-timestamp'];
  const body = req.rawBody ? req.rawBody.toString('utf8') : JSON.stringify(req.body);
  const payload = `v0:${timestamp}:${body}`;
  const hash = crypto.createHmac('sha256', WEBHOOK_SECRET)
    .update(payload).digest('hex');
  
  if (signature !== `v0=${hash}`) {
    return res.status(401).send('Invalid signature');
  }

  // Handle event
  const { event, payload } = req.body;
  console.log(`Received: ${event}`);
  
  res.status(200).send();
});

Common Events

EventDescription
meeting.startedMeeting has started
meeting.endedMeeting has ended
meeting.participant_joinedParticipant joined meeting
recording.completedCloud recording ready
user.createdNew user added

Detailed References

Troubleshooting

Sample Repositories

Official (by Zoom)
TypeRepositoryStars
Node.jswebhook-sample34
PostgreSQLwebhook-to-postgres5
Go/FiberGo-Webhooks-
Header Authzoom-webhook-verification-headers-
Community
LanguageRepositoryDescription
Laravelbinary-cats/laravel-webhooksLaravel webhook handler
AWS Lambdasplunk/zoom-webhook-to-hecServerless to Splunk HEC
Node.jsWill4950/zoom-webhook-listenerWebhook forwarder
Express+Redisojusave/eventSubscriptionPlaygroundSocket.io + Redis
Multi-Language Samples (by tanchunsiong)

Full list: See general/references/community-repos.md

Resources

Environment Variables

Files

references/subscriptions.md

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 Feature → Event 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
SettingDescriptionRequired
notification_endpoint_urlYour HTTPS endpoint (must be publicly accessible)Yes
eventsArray of event types to subscribe toYes

Event Categories

Meeting Events
EventTrigger
meeting.createdMeeting scheduled
meeting.updatedMeeting settings changed
meeting.deletedMeeting deleted
meeting.startedMeeting begins
meeting.endedMeeting ends
meeting.participant_joinedParticipant joins
meeting.participant_leftParticipant leaves
meeting.sharing_startedScreen share begins
meeting.sharing_endedScreen share ends
Recording Events
EventTrigger
recording.startedCloud recording begins
recording.stoppedCloud recording paused/stopped
recording.pausedCloud recording paused
recording.resumedCloud recording resumed
recording.completedRecording processed and available
recording.trashedRecording moved to trash
recording.deletedRecording permanently deleted
recording.recoveredRecording restored from trash
User Events
EventTrigger
user.createdNew user added
user.updatedUser details changed
user.deletedUser removed
user.deactivatedUser deactivated
user.activatedUser activated
Webinar Events
EventTrigger
webinar.createdWebinar scheduled
webinar.startedWebinar begins
webinar.endedWebinar ends
webinar.registration_createdNew 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:

ChainPatternUse Case
REST API → WebhooksCreate meeting, subscribe to eventsTrack meeting lifecycle
Webhooks → REST APIReceive event, fetch detailsRecording download on completion
Users API → WebhooksCreate user, subscribe to user eventsUser 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

ScopeOperations
webhook:read:adminView webhook settings
webhook:write:adminModify webhook settings

Resources

Requirements and compatibility

Written for: Claude Code, Claude apps

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Zoom
Publisher
Anthropic (Official)
Distributed by
Anthropic
Source
anthropics/knowledge-work-plugins · partner-built/zoom-plugin/skills/webhooks · commit e050c2e
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from partner-built/zoom-plugin/LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Zoom or Anthropic.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download setup-zoom-webhooks.zip