From zoom-skills
Guides server-side Zoom REST API integrations with 600+ endpoints for meetings, users, webinars, recordings, reports, and OAuth 2.0 authentication.
npx claudepluginhub zoom/skills --plugin zoom-skillsThis skill uses the workspace's default tool permissions.
Expert guidance for building server-side integrations with the Zoom REST API. This API provides 600+ endpoints for managing meetings, users, webinars, recordings, reports, and all Zoom platform resources programmatically.
RUNBOOK.mdconcepts/api-architecture.mdconcepts/authentication-flows.mdconcepts/meeting-urls-and-sdk-joining.mdconcepts/rate-limiting-strategy.mdexamples/graphql-queries.mdexamples/meeting-lifecycle.mdexamples/recording-pipeline.mdexamples/user-management.mdexamples/webhook-server.mdreferences/accounts.mdreferences/ai-companion.mdreferences/ai-services.mdreferences/authentication.mdreferences/auto-dialer.mdreferences/calendar.mdreferences/chatbot.mdreferences/clips.mdreferences/cobrowse-sdk-api.mdreferences/commerce.mdSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Expert guidance for building server-side integrations with the Zoom REST API. This API provides 600+ endpoints for managing meetings, users, webinars, recordings, reports, and all Zoom platform resources programmatically.
Official Documentation: https://developers.zoom.us/api-hub/
API Hub Reference: https://developers.zoom.us/api-hub/meetings/
OpenAPI Inventories: https://developers.zoom.us/api-hub/<domain>/methods/endpoints.json
New to Zoom REST API? Follow this path:
me keyword, ID vs UUID, time formatsjoin_url with Meeting SDKReference:
Most domain files under references/ are aligned to the official API Hub endpoints.json inventories. Treat those files as the local source of truth for method/path discovery.
Having issues?
Building event-driven integrations?
curl -X POST "https://zoom.us/oauth/token" \
-H "Authorization: Basic $(echo -n 'CLIENT_ID:CLIENT_SECRET' | base64)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=account_credentials&account_id=ACCOUNT_ID"
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"expires_in": 3600,
"scope": "meeting:read meeting:write user:read"
}
curl -X POST "https://api.zoom.us/v2/users/HOST_USER_ID/meetings" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"topic": "Team Standup",
"type": 2,
"start_time": "2025-03-15T10:00:00Z",
"duration": 30,
"settings": {
"join_before_host": false,
"waiting_room": true
}
}'
For S2S OAuth, use an explicit host user ID or email in the path. Do not use me.
curl "https://api.zoom.us/v2/users?page_size=300&status=active" \
-H "Authorization: Bearer ACCESS_TOKEN"
https://api.zoom.us/v2
The api_url field in OAuth token responses indicates the user's region. Use regional URLs for data residency compliance:
| Region | URL |
|---|---|
| Global (default) | https://api.zoom.us/v2 |
| Australia | https://api-au.zoom.us/v2 |
| Canada | https://api-ca.zoom.us/v2 |
| European Union | https://api-eu.zoom.us/v2 |
| India | https://api-in.zoom.us/v2 |
| Saudi Arabia | https://api-sa.zoom.us/v2 |
| Singapore | https://api-sg.zoom.us/v2 |
| United Kingdom | https://api-uk.zoom.us/v2 |
| United States | https://api-us.zoom.us/v2 |
Note: You can always use the global URL https://api.zoom.us regardless of the api_url value.
| Feature | Description |
|---|---|
| Meeting Management | Create, read, update, delete meetings with full scheduling control |
| User Provisioning | Automated user lifecycle (create, update, deactivate, delete) |
| Webinar Operations | Webinar CRUD, registrant management, panelist control |
| Cloud Recordings | List, download, delete recordings with file-type filtering |
| Reports & Analytics | Usage reports, participant data, daily statistics |
| Team Chat | Channel management, messaging, chatbot integration |
| Zoom Phone | Call management, voicemail, call routing |
| Zoom Rooms | Room management, device control, scheduling |
| Webhooks | Real-time event notifications for 100+ event types |
| WebSockets | Persistent event streaming without public endpoints |
| GraphQL (Beta) | Single-endpoint flexible queries at v3/graphql |
| AI Companion | Meeting summaries, transcripts, AI-generated content |
| AI Services / Scribe | File and archive transcription via Build-platform JWT-authenticated endpoints |
Need help with authentication? See the zoom-oauth skill for complete OAuth flow implementation.
The JWT app type is deprecated. Migrate to Server-to-Server OAuth. This does NOT affect JWT token signatures used in Video SDK — only the Marketplace "JWT" app type for REST API access.
// OLD (JWT app type - DEPRECATED)
const token = jwt.sign({ iss: apiKey, exp: expiry }, apiSecret);
// NEW (Server-to-Server OAuth)
const token = await getServerToServerToken(accountId, clientId, clientSecret);
me Keyword Rulesme instead of userId (otherwise: invalid token error)me — provide the actual userId or emailme or userIdUUIDs that begin with / or contain // must be double URL-encoded:
// UUID: /abc==
// Single encode: %2Fabc%3D%3D
// Double encode: %252Fabc%253D%253D ← USE THIS
const uuid = '/abc==';
const encoded = encodeURIComponent(encodeURIComponent(uuid));
const url = `https://api.zoom.us/v2/meetings/${encoded}`;
yyyy-MM-ddTHH:mm:ssZ — UTC time (note the Z suffix)yyyy-MM-ddTHH:mm:ss — Local time (no Z, uses timezone field)All apps on the same Zoom account share rate limits. One heavy app can impact others. Monitor X-RateLimit-Remaining headers proactively.
Meeting/Webinar create/update operations are limited to 100 per day per user (resets at 00:00 UTC). Distribute operations across different host users when doing bulk operations.
Recording download_url values require Bearer token authentication and may redirect. Always follow redirects:
curl -L -H "Authorization: Bearer ACCESS_TOKEN" "https://zoom.us/rec/download/..."
// DON'T: Poll every minute (wastes API quota)
setInterval(() => getMeetings(), 60000);
// DO: Receive webhook events in real-time
app.post('/webhook', (req, res) => {
if (req.body.event === 'meeting.started') {
handleMeetingStarted(req.body.payload);
}
res.status(200).send();
});
Webhook setup details: See the zoom-webhooks skill for comprehensive webhook implementation.
This skill includes comprehensive guides organized by category:
me keyword, ID vs UUID, time formats| Type | Repository |
|---|---|
| OAuth Sample | oauth-sample-app |
| S2S OAuth Starter | server-to-server-oauth-starter-api |
| User OAuth | user-level-oauth-starter |
| S2S Token | server-to-server-oauth-token |
| Rivet Library | rivet-javascript |
| WebSocket Sample | websocket-js-sample |
| Webhook Sample | webhook-sample-node.js |
| Python S2S | server-to-server-python-sample |
Need help? Start with Integrated Index section below for complete navigation.
This section was migrated from SKILL.md.
If you're new to the Zoom REST API, follow this order:
Run preflight checks first → RUNBOOK.md
Understand the API design → concepts/api-architecture.md
me keyword rulesSet up authentication → concepts/authentication-flows.md
Create your first meeting → examples/meeting-lifecycle.md
Handle rate limits → concepts/rate-limiting-strategy.md
Set up webhooks → examples/webhook-server.md
Troubleshoot issues → troubleshooting/common-issues.md
rest-api/
├── SKILL.md # Main skill overview + quick start
├── SKILL.md # This file - navigation guide
│
├── concepts/ # Core architectural concepts
│ ├── api-architecture.md # REST design, URLs, IDs, time formats
│ ├── authentication-flows.md # OAuth flows (S2S, User, PKCE, Device)
│ └── rate-limiting-strategy.md # Limits by plan, retry, queuing
│
├── examples/ # Complete working code
│ ├── meeting-lifecycle.md # Create→Update→Start→End→Delete
│ ├── user-management.md # CRUD users, pagination, bulk ops
│ ├── recording-pipeline.md # Download recordings via webhooks
│ ├── webhook-server.md # Express.js CRC + signature verification
│ └── graphql-queries.md # GraphQL queries, mutations, pagination
│
├── troubleshooting/ # Problem solving
│ ├── common-errors.md # HTTP codes, Zoom error codes table
│ └── common-issues.md # Rate limits, tokens, pagination pitfalls
│
└── references/ # 39 domain-specific reference files
├── authentication.md # Auth methods reference
├── meetings.md # Meeting endpoints
├── users.md # User management endpoints
├── webinars.md # Webinar endpoints
├── recordings.md # Cloud recording endpoints
├── reports.md # Reports & analytics
├── accounts.md # Account management
├── rate-limits.md # Rate limit details
├── graphql.md # GraphQL API (beta)
├── zoom-team-chat.md # Team Chat messaging
├── chatbot.md # Chatbot integration
├── phone.md # Zoom Phone
├── rooms.md # Zoom Rooms
├── calendar.md # Zoom Calendar
├── mail.md # Zoom Mail
├── ai-companion.md # AI features
├── openapi.md # OpenAPI specs
├── qss.md # Quality of Service
├── contact-center.md # Contact Center
├── events.md # Zoom Events
├── whiteboard.md # Whiteboard
├── clips.md # Zoom Clips
├── scheduler.md # Scheduler
├── scim2.md # SCIM 2.0
├── marketplace-apps.md # App management
├── zoom-video-sdk-api.md # Video SDK REST
└── ... (39 total files)
Essential knowledge before making any API call:
me keyword rules (different per app type!)concepts/rate-limiting-strategy.md
Rate limits are per-account, shared across all apps:
Complete CRUD with webhook integration — the pattern most developers need first.
JWT app type is deprecated — use Server-to-Server OAuth
me keyword behaves differently by app type
memeRate limiting is nuanced (don’t assume a single global rule)
X-RateLimit-Remaining)100 meeting creates per user per day
UUID double-encoding is required for certain UUIDs
/ or containing // must be double-encodedPagination: use next_page_token, not page_number
page_number is legacy and being phased outnext_page_token is the recommended approachGraphQL is at /v3/graphql, not /v2/
→ Authentication Flows - Token expired or wrong scopes
→ Rate Limiting Strategy - Check headers for reset time
→ API Architecture - User OAuth apps must use me
→ Common Issues - Use next_page_token
→ Webhook Server - CRC validation required
→ Recording Pipeline - Bearer auth + follow redirects
→ Meeting Lifecycle - Full working examples
| Skill | Use When |
|---|---|
| zoom-oauth | Implementing OAuth flows, token management |
| zoom-webhooks | Deep webhook implementation, event catalog |
| zoom-websockets | WebSocket event streaming |
| zoom-general | Cross-product patterns, community repos |
Based on Zoom REST API v2 (current) and GraphQL v3 (beta)
.env keys and where to find each value.