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

troubleshooting/common-errors.md

Common Errors - HTTP Status Codes and Zoom Error Codes

Complete reference for Zoom REST API error codes, HTTP status codes, and solutions.

HTTP Status Codes

2XX - Success
StatusDescriptionAction
200 OKRequest succeededParse response body
201 CreatedResource createdCheck Location header for new resource URL
204 No ContentRequest succeeded, no bodyCommon for UPDATE/DELETE operations
4XX - Client Errors
StatusDescriptionCommon CausesSolution
400 Bad RequestInvalid requestMissing required fields, invalid JSON, validation errorsCheck request body format and required fields
401 UnauthorizedAuthentication failedInvalid/expired token, missing Authorization headerRefresh access token, check token format
403 ForbiddenPermission deniedMissing scopes, user lacks permission, shared access not grantedAdd required scopes, check user role
404 Not FoundResource doesn't existInvalid userId/meetingId, wrong me keyword usageVerify resource ID, check me keyword rules
409 ConflictResource conflictEmail already exists, duplicate operationUse unique identifiers
429 Too Many RequestsRate limit exceededToo many requests per second/dayImplement exponential backoff, throttle requests
5XX - Server Errors
StatusDescriptionAction
500 Internal Server ErrorZoom server errorRetry with exponential backoff
502 Bad GatewayGateway errorRetry after delay
503 Service UnavailableZoom service downCheck status.zoom.us, retry later

Zoom Error Codes

When an API call fails, Zoom returns an error response:

{
  "code": 300,
  "message": "Request Body should be a valid JSON object."
}
Common Zoom Error Codes
CodeHTTPMessageCauseSolution
300400Invalid requestBad JSON, validation errorCheck request body structure
124400Invalid parameterWrong parameter type/valueValidate parameters against API docs
200401Invalid credentialsIncorrect OAuth tokenRefresh access token
201401Access token expiredToken expiredRequest new token
1001404User does not existInvalid userId or wrong me usageCheck userId, review me keyword rules
300404Meeting not foundInvalid meetingIdVerify meeting exists
3000404Cannot access webinar infoWebinar doesn't exist or no accessCheck webinarId and scopes
200429Rate limit exceededToo many requestsImplement rate limiting
4700401Invalid access tokenToken missing scopesAdd required scopes in app config
3001403Not allowed to accessMissing permissionUpgrade user role or add scope

Detailed Error Scenarios

401 Unauthorized
Scenario 1: Token Expired
{
  "code": 201,
  "message": "Access token is expired."
}

Solution:

async function apiCallWithRetry(url, options) {
  try {
    const response = await fetch(url, options);

    if (response.status === 401) {
      const error = await response.json();

      if (error.code === 201) {
        // Token expired - refresh and retry
        const newToken = await refreshAccessToken();
        options.headers['Authorization'] = `Bearer ${newToken}`;
        return await fetch(url, options);
      }
    }

    return response;
  } catch (error) {
    console.error('API call failed:', error);
    throw error;
  }
}
Scenario 2: Missing/Invalid Token
{
  "code": 200,
  "message": "Invalid credentials."
}

Solution:

  • Check Authorization header is present: Authorization: Bearer ACCESS_TOKEN

  • Verify token format (should be JWT)

  • Ensure token is for the correct account

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

Solution:

  1. Go to your app on Zoom Marketplace

  2. Add required scopes (e.g., meeting:write:admin)

  3. Request new access token with updated scopes

403 Forbidden
Scenario 1: Missing Permission
{
  "code": 3001,
  "message": "This user is not allowed to access this resource."
}

Solution:

  • Verify user has appropriate role (Admin, Owner)

  • Check if endpoint requires admin-level scopes

  • Use account-level scope (e.g., meeting:write:admin instead of meeting:write)

Scenario 2: Shared Access Permissions
{
  "code": 3001,
  "message": "Authenticated user has not permitted access to the targeted resource."
}

Cause: User hasn't authorized shared access permissions for your app.

Solution: Direct user to: Allowing Apps Access to Shared Access Permissions

404 Not Found
Scenario 1: User Not Found (Wrong me Usage)
{
  "code": 1001,
  "message": "User does not exist: [email protected]"
}

Cause: Using userId with User OAuth app (should use me).

Solution:

// WRONG (User OAuth app)
fetch('https://api.zoom.us/v2/users/[email protected]', {
  headers: { 'Authorization': `Bearer ${userToken}` }
});

// CORRECT (User OAuth app)
fetch('https://api.zoom.us/v2/users/me', {
  headers: { 'Authorization': `Bearer ${userToken}` }
});
Scenario 2: Meeting/Resource Not Found
{
  "code": 300,
  "message": "Meeting not found."
}

Causes:

  • Meeting deleted

  • Meeting expired (30 days after last use)

  • Invalid meetingId

  • Wrong UUID encoding

Solution for UUID:

// UUID starts with / or contains // → double-encode
const uuid = '/xyzAbC123==';
const encoded = encodeURIComponent(encodeURIComponent(uuid));
fetch(`https://api.zoom.us/v2/meetings/${encoded}`, { headers });
429 Too Many Requests
{
  "code": 200,
  "message": "You have reached the maximum per-second rate limit for this API."
}

Solution: Implement exponential backoff

async function apiCallWithBackoff(url, options, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After') || Math.pow(2, attempt);
      console.log(`Rate limited. Retrying after ${retryAfter}s`);
      await sleep(retryAfter * 1000);
      continue;
    }

    return response;
  }

  throw new Error('Max retries exceeded');
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Check rate limit headers:

const remaining = response.headers.get('X-RateLimit-Remaining');
const type = response.headers.get('X-RateLimit-Type');

console.log(`Rate limit remaining: ${remaining} (${type})`);

Validation Error Responses

Field Validation Errors
{
  "code": 300,
  "message": "Validation Failed.",
  "errors": [
    {
      "field": "start_time",
      "message": "Invalid field."
    },
    {
      "field": "type",
      "message": "Invalid field."
    }
  ]
}

Solution:

  • Check each field's format in API documentation

  • Verify required fields are present

  • Ensure data types match (number vs string)

Common Field Errors
FieldErrorCauseFix
start_timeInvalid fieldWrong formatUse yyyy-MM-ddTHH:mm:ssZ
typeInvalid fieldInvalid meeting typeUse 1, 2, 3, or 8
emailInvalid fieldInvalid email formatCheck email format
durationInvalid fieldDuration too longMax duration varies by plan

Error Response Structure

Standard Error
{
  "code": 300,
  "message": "Descriptive error message"
}
Validation Error
{
  "code": 300,
  "message": "Validation Failed.",
  "errors": [
    {
      "field": "field_name",
      "message": "Error description"
    }
  ]
}

Error Handling Best Practices

1. Parse Error Response
async function handleApiResponse(response) {
  if (!response.ok) {
    const error = await response.json();

    console.error(`API Error ${response.status}:`, error);

    // Check for validation errors
    if (error.errors && Array.isArray(error.errors)) {
      error.errors.forEach(err => {
        console.error(`- Field "${err.field}": ${err.message}`);
      });
    }

    throw new Error(`${error.code}: ${error.message}`);
  }

  return await response.json();
}
2. Retry with Exponential Backoff
async function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      const isRetryable = error.status >= 500 || error.status === 429;

      if (!isRetryable || attempt === maxRetries) {
        throw error;
      }

      const delay = baseDelay * Math.pow(2, attempt - 1);
      const jitter = Math.random() * 1000;  // Add randomness

      console.log(`Retry attempt ${attempt} after ${delay + jitter}ms`);
      await sleep(delay + jitter);
    }
  }
}
3. Log Errors with Context
function logApiError(error, context) {
  const logEntry = {
    timestamp: new Date().toISOString(),
    status: error.status,
    code: error.code,
    message: error.message,
    context: {
      endpoint: context.endpoint,
      method: context.method,
      userId: context.userId
    }
  };

  console.error('API Error:', JSON.stringify(logEntry, null, 2));

  // Send to monitoring service
  // monitoring.track(logEntry);
}
4. User-Friendly Error Messages
function getUserFriendlyError(error) {
  const errorMap = {
    1001: 'User not found. Please check the email address.',
    300: 'Invalid request. Please check your input.',
    201: 'Your session has expired. Please sign in again.',
    4700: 'Permission denied. Please contact your administrator.',
    200: 'Too many requests. Please try again in a few moments.'
  };

  return errorMap[error.code] || 'An unexpected error occurred. Please try again.';
}

Troubleshooting Checklist

Quick Diagnostic Steps
  1. Check HTTP status code - Indicates error category (auth, validation, server)

  2. Read error message - Provides specific details

  3. Check Zoom error code - Maps to specific issue

  4. Verify authentication - Token valid, scopes present

  5. Check rate limits - Monitor X-RateLimit-Remaining header

  6. Test with Postman - Isolate code vs API issue

  7. Check Zoom Status - Visit status.zoom.us

Common Fixes
SymptomCheckFix
401 UnauthorizedToken expiryRefresh access token
404 User not foundme keyword usageUse me for User OAuth
404 Meeting not foundUUID encodingDouble-encode UUIDs starting with /
403 ForbiddenScopesAdd required scopes in app config
429 Rate limitRequest rateImplement throttling
400 Validation errorRequest bodyCheck field formats in docs

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