Generated banner for Setup Zoom Websockets
Generated logo for Setup Zoom Websockets

Setup Zoom Websockets

OpenAIOfficialCreated by ZoomDistributed by OpenAI

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

From the author

Use when building Zoom WebSockets.
— the description by Zoom

AutoGineer summary

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

This skill provides a structured approach to integrating Zoom WebSockets for real-time event streaming. It covers the full connection lifecycle, including Server-to-Server OAuth authentication, token management, heartbeat implementation, and reconnection strategies. It is intended for developers who require persistent event delivery rather than standard HTTP webhook callbacks.

What it does

  • Provides steps for configuring Zoom event subscriptions for WebSockets.
  • Details the authentication flow using Server-to-Server OAuth tokens.
  • Outlines implementation patterns for connection heartbeats and keep-alive pings.
  • Defines strategies for handling disconnections and implementing exponential backoff.
  • Lists required environment variables for managing Zoom app credentials and subscription IDs.
  • Offers guidance on observability and debugging common connection issues.

When to use it

  • When your application requires persistent event delivery from Zoom.
  • When you need to manage real-time event streams outside of standard HTTP webhook patterns.
  • When building custom integration logic that requires manual connection state management.

Advantages

  • Provides a clear lifecycle model for managing persistent WebSocket connections.
  • Includes code patterns for token refresh and heartbeat maintenance.
  • Centralizes configuration requirements for Zoom OAuth and subscription IDs.
  • Offers a structured approach to troubleshooting connection and authentication failures.

Usage examples

“How do I authenticate a Zoom WebSocket connection?”
The skill explains how to generate a Server-to-Server OAuth access token using your account ID, client ID, and client secret to authorize the WebSocket connection.
“How can I keep my Zoom WebSocket connection alive?”
The skill provides a heartbeat implementation pattern using periodic ping/pong messages to maintain the connection state.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/openai/setup-zoom-websockets/download
  2. Unzip it into the cross-client skills folder of your project:

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

Documentation by Zoom

Setup Zoom WebSockets

Use this skill when the integration needs persistent Zoom event delivery instead of HTTP webhook callbacks. If normal webhook retries and delivery are enough, prefer setup-zoom-webhooks.

Workflow

  1. Confirm WebSockets are justified by latency, firewall, connection model, or deployment constraints.

  2. Configure the app and event subscriptions for the required event stream.

  3. Implement connection setup, authentication, heartbeat, reconnect, backoff, and shutdown handling.

  4. Normalize events into the same internal contract used by webhook handlers when both are supported.

  5. Add observability for connection state, reconnect count, event lag, and dropped messages.

  6. Debug by isolating token/auth problems, app subscription settings, network proxies, TLS interception, and reconnect loops.

References

Files

references/full-guide.md

/setup-zoom-websockets

Background reference for persistent Zoom event streams. Prefer workflow routing first, then use this file when WebSockets are plausibly better than webhooks.

WebSockets vs Webhooks

AspectWebSocketsWebhooks
ConnectionPersistent, bidirectionalOne-time HTTP POST
LatencyLower (no HTTP overhead)Higher (new connection per event)
SecurityDirect connection, no exposed endpointRequires endpoint validation, IP whitelisting
ModelPull (you connect to Zoom)Push (Zoom connects to you)
StateStateful (maintains connection)Stateless (each event independent)
SetupMore complex (access token, connection)Simpler (just endpoint URL)

Choose WebSockets when:

  • Real-time, low-latency updates are critical

  • Security is paramount (banking, healthcare, finance)

  • You don't want to expose a public endpoint

  • You need bidirectional communication

Choose Webhooks when:

  • Simpler setup is preferred

  • Small number of event notifications

  • Existing HTTP infrastructure

Prerequisites

  • Server-to-Server OAuth app in Zoom Marketplace

  • Account ID, Client ID, and Client Secret

  • WebSocket subscription with events enabled

Need help with S2S OAuth? See the zoom-oauth skill for complete authentication flows.

Start troubleshooting fast: Use the 5-Minute Runbook before deep debugging.

Quick Start

1. Create Server-to-Server OAuth App
  1. Go to Zoom Marketplace

  2. Create a Server-to-Server OAuth app

  3. Copy Account ID, Client ID, Client Secret

2. Enable WebSocket Subscription
  1. In your app, go to Feature → Event Subscriptions

  2. Add an Event Subscription

  3. Select WebSockets as the method type

  4. Select events to subscribe to (e.g., meeting.created, meeting.started)

  5. Save - an endpoint URL will be generated

3. Connect via WebSocket
const WebSocket = require('ws');
const axios = require('axios');

// Step 1: Get access token
async function getAccessToken() {
  const credentials = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64');

  const response = await axios.post(
    'https://zoom.us/oauth/token',
    new URLSearchParams({
      grant_type: 'account_credentials',
      account_id: ACCOUNT_ID
    }),
    {
      headers: {
        'Authorization': `Basic ${credentials}`,
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    }
  );

  return response.data.access_token;
}

// Step 2: Connect to WebSocket
async function connectWebSocket() {
  const accessToken = await getAccessToken();

  // WebSocket URL from your subscription settings
  const wsUrl = `wss://ws.zoom.us/ws?subscriptionId=${SUBSCRIPTION_ID}&access_token=${accessToken}`;

  const ws = new WebSocket(wsUrl);

  ws.on('open', () => {
    console.log('WebSocket connection established');
  });

  ws.on('message', (data) => {
    const event = JSON.parse(data);
    console.log('Event received:', event.event);

    // Handle different event types
    switch (event.event) {
      case 'meeting.started':
        console.log(`Meeting started: ${event.payload.object.topic}`);
        break;
      case 'meeting.ended':
        console.log(`Meeting ended: ${event.payload.object.uuid}`);
        break;
      case 'meeting.participant_joined':
        console.log(`Participant joined: ${event.payload.object.participant.user_name}`);
        break;
    }
  });

  ws.on('close', (code, reason) => {
    console.log(`Connection closed: ${code} - ${reason}`);
    // Implement reconnection logic
  });

  ws.on('error', (error) => {
    console.error('WebSocket error:', error);
  });

  return ws;
}

connectWebSocket();

Event Format

Events received via WebSocket have the same format as webhook events:

{
  "event": "meeting.started",
  "event_ts": 1706123456789,
  "payload": {
    "account_id": "abcD3ojkdbjfg",
    "object": {
      "id": 1234567890,
      "uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
      "host_id": "xyz789",
      "topic": "Team Standup",
      "type": 2,
      "start_time": "2024-01-25T10:00:00Z",
      "timezone": "America/Los_Angeles"
    }
  }
}

Common Events

EventDescription
meeting.createdMeeting scheduled
meeting.updatedMeeting settings changed
meeting.deletedMeeting deleted
meeting.startedMeeting begins
meeting.endedMeeting ends
meeting.participant_joinedParticipant joins meeting
meeting.participant_leftParticipant leaves meeting
recording.completedCloud recording ready
user.createdNew user added
user.updatedUser details changed

Connection Management

Keep-Alive

WebSocket connections require periodic heartbeats. Zoom will close idle connections.

// Send ping every 30 seconds
setInterval(() => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.ping();
  }
}, 30000);
Reconnection

Implement automatic reconnection for reliability:

function connectWithReconnect() {
  const ws = connectWebSocket();

  ws.on('close', () => {
    console.log('Connection lost. Reconnecting in 5 seconds...');
    setTimeout(connectWithReconnect, 5000);
  });

  return ws;
}
Single Connection Limit

Important: Only ONE WebSocket connection can be open per subscription at a time. Opening a new connection will close the existing one.

Detailed References

Troubleshooting

Sample Repositories

Official / Community
TypeRepositoryDescription
Node.jsjust-zoomit/zoom-websocketsWebSocket sample with S2S OAuth

WebSockets vs RTMS

Don't confuse WebSockets with RTMS (Realtime Media Streams):

FeatureWebSocketsRTMS
PurposeEvent notificationsMedia streams
DataMeeting events, user eventsAudio, video, transcripts
Use caseReact to Zoom eventsAI/ML, live transcription
SkillThis skillrtms

For real-time audio/video/transcript data, use the rtms skill instead.

Resources

Environment Variables

Requirements and compatibility

Written for: OpenAI Codex

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
OpenAI (Official)
Distributed by
OpenAI
Source
openai/plugins · plugins/zoom/skills/websockets · commit d420d13
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from plugins/zoom/LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

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

Download ZIP

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