Setup Zoom Websockets
OpenAIOfficialCreated by ZoomDistributed by OpenAI
- Skill
- Tool integration
- Automation and integrations
- MIT
- No issues found
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
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/openai/setup-zoom-websockets/downloadUnzip 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
Confirm WebSockets are justified by latency, firewall, connection model, or deployment constraints.
Configure the app and event subscriptions for the required event stream.
Implement connection setup, authentication, heartbeat, reconnect, backoff, and shutdown handling.
Normalize events into the same internal contract used by webhook handlers when both are supported.
Add observability for connection state, reconnect count, event lag, and dropped messages.
Debug by isolating token/auth problems, app subscription settings, network proxies, TLS interception, and reconnect loops.
References
Full preserved guide: references/full-guide.md
Connection: references/connection.md
Events: references/events.md
Common issues: troubleshooting/common-issues.md
Files
- ATTRIBUTION.mdAdded by AutoGineer878 B
- LICENSELicence file added by AutoGineer1.1 KiB
- RUNBOOK.md2.9 KiB
- SKILL.md1.2 KiB
- agents/openai.yaml148 B
- references/connection.md10.2 KiB
- references/environment-variables.md827 B
- references/events.md10.5 KiB
- references/full-guide.md7.0 KiB
- troubleshooting/common-issues.md1.1 KiB
references/events.md
WebSockets - Event Types
Complete reference for events available via Zoom WebSockets.
Event Structure
All WebSocket events follow this structure:
{
"event": "event.type",
"event_ts": 1706123456789,
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
// Event-specific data
}
}
}| Field | Type | Description |
|---|---|---|
event | string | Event type identifier |
event_ts | number | Unix timestamp (milliseconds) |
payload.account_id | string | Zoom account ID |
payload.object | object | Event-specific payload |
Meeting Events
meeting.created
Triggered when a meeting is scheduled.
{
"event": "meeting.created",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"host_id": "xyz789",
"topic": "Weekly Team Sync",
"type": 2,
"start_time": "2024-01-25T10:00:00Z",
"duration": 60,
"timezone": "America/Los_Angeles"
}
}
}meeting.updated
Triggered when meeting settings are changed.
{
"event": "meeting.updated",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"topic": "Updated: Weekly Team Sync"
},
"old_object": {
"topic": "Weekly Team Sync"
}
}
}meeting.deleted
Triggered when a meeting is deleted.
{
"event": "meeting.deleted",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"host_id": "xyz789"
}
}
}meeting.started
Triggered when a meeting begins.
{
"event": "meeting.started",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"host_id": "xyz789",
"topic": "Weekly Team Sync",
"type": 2,
"start_time": "2024-01-25T10:00:00Z",
"timezone": "America/Los_Angeles"
}
}
}meeting.ended
Triggered when a meeting ends.
{
"event": "meeting.ended",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"host_id": "xyz789",
"topic": "Weekly Team Sync",
"start_time": "2024-01-25T10:00:00Z",
"end_time": "2024-01-25T11:05:00Z",
"duration": 65
}
}
}meeting.participant_joined
Triggered when a participant joins the meeting.
{
"event": "meeting.participant_joined",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"host_id": "xyz789",
"participant": {
"id": "participant123",
"user_id": "user456",
"user_name": "John Doe",
"email": "[email protected]",
"join_time": "2024-01-25T10:02:00Z"
}
}
}
}meeting.participant_left
Triggered when a participant leaves the meeting.
{
"event": "meeting.participant_left",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"participant": {
"id": "participant123",
"user_name": "John Doe",
"leave_time": "2024-01-25T10:45:00Z",
"leave_reason": "left the meeting"
}
}
}
}meeting.sharing_started
Triggered when screen sharing begins.
{
"event": "meeting.sharing_started",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"participant": {
"id": "participant123",
"user_name": "John Doe"
},
"sharing_details": {
"content": "screen",
"date_time": "2024-01-25T10:15:00Z"
}
}
}
}meeting.sharing_ended
Triggered when screen sharing ends.
{
"event": "meeting.sharing_ended",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"participant": {
"id": "participant123",
"user_name": "John Doe"
}
}
}
}Recording Events
recording.started
Triggered when cloud recording starts.
{
"event": "recording.started",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"host_id": "xyz789",
"topic": "Weekly Team Sync",
"start_time": "2024-01-25T10:00:00Z",
"recording_start": "2024-01-25T10:01:00Z"
}
}
}recording.stopped
Triggered when cloud recording stops (paused or ended).
{
"event": "recording.stopped",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"recording_start": "2024-01-25T10:01:00Z",
"recording_end": "2024-01-25T11:00:00Z"
}
}
}recording.completed
Triggered when cloud recording is processed and ready for download.
{
"event": "recording.completed",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 1234567890,
"uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
"host_id": "xyz789",
"topic": "Weekly Team Sync",
"start_time": "2024-01-25T10:00:00Z",
"duration": 60,
"total_size": 157286400,
"recording_count": 2,
"recording_files": [
{
"id": "file123",
"meeting_id": "abcdefgh-1234-5678-abcd-1234567890ab",
"recording_start": "2024-01-25T10:01:00Z",
"recording_end": "2024-01-25T11:00:00Z",
"file_type": "MP4",
"file_size": 104857600,
"download_url": "https://zoom.us/rec/download/...",
"status": "completed"
},
{
"id": "file124",
"file_type": "TRANSCRIPT",
"file_size": 52428800,
"download_url": "https://zoom.us/rec/download/..."
}
]
}
}
}recording.trashed
Triggered when recording is moved to trash.
recording.deleted
Triggered when recording is permanently deleted.
recording.recovered
Triggered when recording is restored from trash.
User Events
user.created
Triggered when a new user is added to the account.
{
"event": "user.created",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": "user789",
"first_name": "Jane",
"last_name": "Smith",
"email": "[email protected]",
"type": 2,
"created_at": "2024-01-25T09:00:00Z"
}
}
}user.updated
Triggered when user details are changed.
{
"event": "user.updated",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": "user789",
"first_name": "Jane",
"last_name": "Smith-Jones"
},
"old_object": {
"last_name": "Smith"
}
}
}user.deleted
Triggered when a user is removed from the account.
{
"event": "user.deleted",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": "user789",
"email": "[email protected]"
}
}
}user.deactivated
Triggered when a user is deactivated.
user.activated
Triggered when a user is activated.
Webinar Events
webinar.created
webinar.updated
webinar.deleted
webinar.started
webinar.ended
webinar.registration_created
Triggered when someone registers for a webinar.
{
"event": "webinar.registration_created",
"payload": {
"account_id": "abcD3ojkdbjfg",
"object": {
"id": 9876543210,
"uuid": "webinar-uuid-here",
"registrant": {
"id": "registrant123",
"email": "[email protected]",
"first_name": "Attendee",
"last_name": "User",
"join_url": "https://zoom.us/w/..."
}
}
}
}Event Handling Example
const eventHandlers = {
// Meeting events
'meeting.created': (payload) => {
console.log(`New meeting: ${payload.object.topic}`);
notifyCalendarService(payload.object);
},
'meeting.started': (payload) => {
console.log(`Meeting started: ${payload.object.topic}`);
updateMeetingStatus(payload.object.id, 'in_progress');
},
'meeting.ended': (payload) => {
console.log(`Meeting ended: ${payload.object.uuid}`);
updateMeetingStatus(payload.object.id, 'completed');
calculateAttendance(payload.object);
},
'meeting.participant_joined': (payload) => {
const { participant } = payload.object;
console.log(`${participant.user_name} joined`);
trackAttendance(payload.object.id, participant);
},
// Recording events
'recording.completed': (payload) => {
console.log(`Recording ready: ${payload.object.topic}`);
downloadRecordings(payload.object.recording_files);
},
// User events
'user.created': (payload) => {
console.log(`New user: ${payload.object.email}`);
sendWelcomeEmail(payload.object);
}
};
ws.on('message', (data) => {
const event = JSON.parse(data);
const handler = eventHandlers[event.event];
if (handler) {
handler(event.payload);
} else {
console.log(`Unhandled event: ${event.event}`);
}
});Subscribing to Events
Configure which events to receive in your Zoom Marketplace app:
Go to Feature → Event Subscriptions
Select WebSockets as method type
Check the events you want to receive
Save the subscription
Note: You can modify subscriptions at any time. Changes take effect immediately.
Event Filtering
If you're receiving too many events, consider:
Subscribe selectively - Only subscribe to events you need
Filter in handler - Drop events that don't match your criteria
Use multiple subscriptions - Route different events to different handlers
// Filter example: Only process events for specific hosts
ws.on('message', (data) => {
const event = JSON.parse(data);
// Only process meetings from specific hosts
const allowedHosts = ['[email protected]', '[email protected]'];
if (event.event.startsWith('meeting.') &&
event.payload.object.host_id &&
!allowedHosts.includes(getHostEmail(event.payload.object.host_id))) {
return; // Skip this event
}
processEvent(event);
});Resources
Event reference: https://developers.zoom.us/docs/api/rest/reference/zoom-api/events/
WebSockets docs: https://developers.zoom.us/docs/api/websockets/
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