Generated banner for Build Zoom Rest API App
Generated logo for Build Zoom Rest API App

Build Zoom Rest API App

OpenAIOfficialCreated by ZoomDistributed by OpenAI

  • Skill
  • Tool integration
  • Software development
  • MIT
  • Medium risk

From the author

Use when calling REST APIs.
— 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 interacting with the Zoom REST API. It offers guidance on selecting appropriate authentication flows, managing resources such as meetings and users, and implementing robust API interaction patterns like pagination and rate-limit handling. It includes reference documentation for various Zoom product areas, including account management and AI Companion services, to assist developers in building API-integrated applications.

What it does

  • Provides endpoint inventories for Zoom API product areas.
  • Outlines authentication requirements for user-level, account-level, and server-to-server workflows.
  • Defines patterns for implementing API wrappers with pagination and retry logic.
  • Offers guidance on webhook processing, including signature verification.
  • Assists in troubleshooting common API issues like scope mismatches and rate limits.

When to use it

  • When developing applications that need to programmatically manage Zoom meetings, users, or recordings.
  • When integrating Zoom account settings or dashboard metrics into custom software.
  • When setting up event-driven workflows using Zoom webhooks.
  • When debugging authentication or scope-related errors during Zoom API integration.

Advantages

  • Centralizes access to official Zoom API endpoint documentation.
  • Standardizes the implementation of API interaction patterns.
  • Clarifies the selection of correct authentication scopes for different API operations.
  • Provides a clear methodology for handling API rate limits and resource management.

Usage examples

“How do I list meeting participants using the Zoom API?”
The agent provides the correct endpoint path from the dashboard references and explains the necessary OAuth scopes and pagination requirements.
“What authentication should I use for an account-level Zoom integration?”
The agent guides you through the account-level OAuth flow requirements as defined in the authentication documentation.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/openai/build-zoom-rest-api-app/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip build-zoom-rest-api-app.zip -d .agents/skills

Documentation by Zoom

Build Zoom REST API App

Use this skill when the task needs deterministic Zoom API calls or resource management from application code.

Workflow

  1. Define the resource and actor: user, meeting, webinar, recording, docs, chat, phone, account, or admin-level workflow.

  2. Select the endpoint and required scopes from the reference files before coding.

  3. Confirm auth fit: user-level OAuth for user-owned resources, account-level OAuth for admin workflows, and only use server-to-server OAuth where the target API documents support for it.

  4. Implement narrow API wrappers with explicit pagination, retry, idempotency, and rate-limit handling.

  5. Treat webhook processing as a separate event-ingestion path with signature verification and replay protection.

  6. Debug by checking token audience, missing scopes, resource ownership, account settings, API enablement, and rate-limit headers.

References

Files

concepts/api-architecture.md

API Architecture

Core design patterns for the Zoom REST API — base URLs, regional routing, identifiers, time formats, and request conventions.

Base URL

All requests use HTTPS with API version /v2 in the path:

https://api.zoom.us/v2/

GraphQL uses a separate versioned endpoint:

https://api.zoom.us/v3/graphql

Regional Base URLs

The OAuth token response includes an api_url field indicating the user's data region. Use this for data residency compliance:

{
  "access_token": "eyJ...",
  "api_url": "https://api-eu.zoom.us"
}

Construct your regional base URL by appending /v2/:

RegionAPI URLBase URL
Global (default)https://api.zoom.ushttps://api.zoom.us/v2
Australiahttps://api-au.zoom.ushttps://api-au.zoom.us/v2
Canadahttps://api-ca.zoom.ushttps://api-ca.zoom.us/v2
European Unionhttps://api-eu.zoom.ushttps://api-eu.zoom.us/v2
Indiahttps://api-in.zoom.ushttps://api-in.zoom.us/v2
Saudi Arabiahttps://api-sa.zoom.ushttps://api-sa.zoom.us/v2
Singaporehttps://api-sg.zoom.ushttps://api-sg.zoom.us/v2
United Kingdomhttps://api-uk.zoom.ushttps://api-uk.zoom.us/v2
United Stateshttps://api-us.zoom.ushttps://api-us.zoom.us/v2
Vanity accounthttps://{vanity}.zoom.ushttps://{vanity}.zoom.us/v2

Important: The global URL https://api.zoom.us always works regardless of user region. Regional URLs are for compliance, not required.

Node.js — Dynamic Base URL from Token
async function getZoomClient(accountId, clientId, clientSecret) {
  const credentials = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');

  const tokenRes = await fetch('https://zoom.us/oauth/token', {
    method: 'POST',
    headers: {
      'Authorization': `Basic ${credentials}`,
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: `grant_type=account_credentials&account_id=${accountId}`
  });

  const tokenData = await tokenRes.json();
  const baseUrl = tokenData.api_url
    ? `${tokenData.api_url}/v2`
    : 'https://api.zoom.us/v2';

  return {
    accessToken: tokenData.access_token,
    baseUrl,
    async request(method, path, body = null) {
      const res = await fetch(`${this.baseUrl}${path}`, {
        method,
        headers: {
          'Authorization': `Bearer ${this.accessToken}`,
          'Content-Type': 'application/json'
        },
        body: body ? JSON.stringify(body) : undefined
      });
      if (!res.ok) {
        const err = await res.json();
        throw new Error(`Zoom API ${res.status}: ${err.message}`);
      }
      return res.json();
    }
  };
}

The me Keyword

The me keyword substitutes for userId or accountId in API paths. Its behavior varies by app type:

App Typeme BehaviorWhen to Use
User-level OAuthResolves to the authenticated userMUST use — providing userId causes invalid token error
Server-to-Server OAuthNot supportedMUST NOT use — provide actual userId or email
Account-level OAuthResolves to the user who installed the appCan use either me or userId
Examples
# User OAuth app — MUST use me
GET /v2/users/me
GET /v2/users/me/meetings

# S2S OAuth app — MUST use actual userId or email
GET /v2/users/abc123def
GET /v2/users/[email protected]
GET /v2/users/[email protected]/meetings
Common Error

Using userId with a User-level OAuth token:

{
  "code": 4700,
  "message": "Invalid access token, does not contain scopes."
}

Fix: Replace the userId with me.

Meeting ID vs UUID

  • Meeting ID: Numeric identifier for the meeting. Reusable for recurring meetings. Expires 30 days after last use.

  • UUID: Unique identifier for a specific meeting instance. Never expires. Generated per occurrence of recurring meetings.

When to Use Which
Use CaseUse
Get a scheduled meetingMeeting ID
Get a past meeting instanceUUID
Get recordings for a specific sessionUUID
Report on a specific occurrenceUUID
Double-Encoding UUIDs

UUIDs that begin with / or contain // must be double URL-encoded:

function encodeUUID(uuid) {
  // Check if double-encoding is needed
  if (uuid.startsWith('/') || uuid.includes('//')) {
    return encodeURIComponent(encodeURIComponent(uuid));
  }
  return encodeURIComponent(uuid);
}

// UUID: /abcABC123==
// Single encode: %2FabcABC123%3D%3D
// Double encode: %252FabcABC123%253D%253D  ← Required

const meetingUUID = '/abcABC123==';
const url = `https://api.zoom.us/v2/past_meetings/${encodeUUID(meetingUUID)}`;
Python
from urllib.parse import quote

def encode_uuid(uuid_str):
    if uuid_str.startswith('/') or '//' in uuid_str:
        return quote(quote(uuid_str, safe=''), safe='')
    return quote(uuid_str, safe='')

uuid = '/abcABC123=='
url = f'https://api.zoom.us/v2/past_meetings/{encode_uuid(uuid)}'

Time Formats

Zoom API uses ISO 8601 with two variants:

FormatMeaningExample
yyyy-MM-ddTHH:mm:ssZUTC time (Z suffix)2025-03-15T10:00:00Z
yyyy-MM-ddTHH:mm:ssLocal time (no Z, uses timezone field)2025-03-15T10:00:00
Setting Meeting Time
{
  "topic": "Team Meeting",
  "type": 2,
  "start_time": "2025-03-15T10:00:00",
  "timezone": "America/Los_Angeles",
  "duration": 60
}

Or using UTC directly:

{
  "topic": "Team Meeting",
  "type": 2,
  "start_time": "2025-03-15T17:00:00Z",
  "duration": 60
}

Note: Some Report APIs only accept UTC format. Always check the endpoint reference for the accepted format.

Date-Only Parameters

Some endpoints (e.g., recordings list) use YYYY-MM-DD format:

GET /v2/users/me/recordings?from=2025-01-01&to=2025-01-31

Download URLs

Recording download_url values in API responses and webhook payloads are dynamically generated. They require authentication:

Authentication Methods
  1. Bearer token in Authorization header (recommended):

curl -L -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://zoom.us/rec/archive/download/xyz"
  1. download_access_token from webhook payload (for webhook-triggered downloads):

curl -L -H "Authorization: Bearer DOWNLOAD_ACCESS_TOKEN" \
  "https://zoom.us/rec/archive/download/xyz"
Follow Redirects

Download URLs may return HTTP 301/302 redirects. Always follow redirects:

// Node.js — fetch follows redirects by default
const response = await fetch(downloadUrl, {
  headers: { 'Authorization': `Bearer ${accessToken}` },
  redirect: 'follow'
});

const fileBuffer = await response.arrayBuffer();
# Python — requests follows redirects by default
import requests

response = requests.get(
    download_url,
    headers={'Authorization': f'Bearer {access_token}'},
    allow_redirects=True,
    stream=True
)

with open('recording.mp4', 'wb') as f:
    for chunk in response.iter_content(chunk_size=8192):
        f.write(chunk)

Personal Meeting ID (PMI)

Users can create meetings with their PMI. The API returns a unique meeting ID in the response, but webhook events still reference the PMI. Use the PMI when passing IDs to API endpoints for PMI-based meetings.

Shared Access Permissions

Users with Schedule Privilege or role-based access can act on behalf of other users. If your app accesses resources of a user other than the one who installed the app, that user must have authorized shared access permissions.

Error when shared access is not granted:

{
  "code": 403,
  "message": "authenticated user has not permitted access to the targeted resource"
}

Resolution: Direct the user to enable shared access permissions in their Zoom settings. See Zoom Help Center for the user-facing instructions.

Email Address Display Rules

External participant emails are only shown if:

  • The participant entered their email during registration

  • The host provided the email via calendar integration, authentication exception, or breakout room assignment

  • A CSV was imported for webinar panelists/attendees

High API Failure Rates

If your app has a consistently high error-to-request ratio, Zoom may disable it. Build robust error handling and graceful retry logic.

Request Authentication

All API requests require a Bearer token in the Authorization header:

Authorization: Bearer {access_token}

Full auth implementation: See Authentication Flows or the zoom-oauth skill.

Resources

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

What our scanner noticed· Medium risk

  • Possible data-exfiltration endpoints
  • Instructions that use the network

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/rest-api · 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 build-zoom-rest-api-app.zip