Skip to content

Repository files navigation

Zoom API Client

A fully auto-generated, dependency-free, and 100% typed Zoom API client for Node.js. Generated from Zoom's official OpenAPI specification.

Maintained by Nektar AI and used in production.

Installation

npm install @nektarai/zoom-api-client

Features

  • Zero Dependencies: No runtime dependencies
  • Fully Typed: Complete TypeScript type definitions generated from OpenAPI spec
  • Comprehensive Coverage: 180+ endpoints across meetings, webinars, users, reports, recordings, and more
  • Auto-Generated: Regenerate anytime from the latest Zoom OpenAPI spec
  • Tested: Full test coverage with Jest

Usage

ZoomClient

This is the core provider of all authentication and requests for Zoom. It is recommended to create only one ZoomClient instance for all Oauth (non-S2SO) purposes.

import {ZoomClient} from '@nektarai/zoom-api-client';

const zoomClient = new ZoomClient({
    clientId: process.env.ZOOM_CLIENT_ID,
    clientSecret: process.env.ZOOM_CLIENT_SECRET,
    redirectUri: process.env.ZOOM_REDIRECT_URI,
    verificationKey: process.env.ZOOM_VERIFICATION_KEY, // optional
});

ZoomOauth

To use the Zoom's Oauth functionality

import {ZoomS2SO} from '@nektarai/zoom-api-client';

const zoomOauth = new ZoomOauth(zoomClient);

expressRouter.get('/zoom/oauth', (req, res) => {
  const state = {userId: req.params.userId};
  res.redirect(zoomOauth.getAuthorizationUrl(state));
});

ZoomS2SO

To use Zoom's Server-to-server oauth functionality

import {ZoomClient, ZoomS2SO} from '@nektarai/zoom-api-client';

const zoomClient = new ZoomClient({
  // S2SO credentials
})
const zoomS2so = new ZoomS2SO(zoomClient);

ZoomApi

The API client provides access to all Zoom API endpoints through an intuitive, fluent interface.

User Operations

import {ZoomApi} from '@nektarai/zoom-api-client';

const zoomApi = new ZoomApi({
  client: zoomClient,
  tokens: await zoomS2so.requestTokens(),
});

// List meetings for a user
const meetings = await zoomApi.user('me').listMeetings({ type: 'scheduled' });

// Create a meeting
const newMeeting = await zoomApi.user('me').createMeeting({
  topic: 'Team Standup',
  type: 2, // Scheduled meeting
  start_time: '2026-02-15T10:00:00Z',
});

Meeting Operations

// Get meeting recordings
const recordings = await zoomApi.meeting('meeting-id').listRecordings();

// Get past meeting details and participants
const details = await zoomApi.pastMeeting('meeting-uuid').getPastMeeting();
const participants = await zoomApi.pastMeeting('meeting-uuid').listParticipants();

Reports & Analytics

// Get daily usage report
const report = await zoomApi.report().getDaily({ year: 2024, month: 1 });

Devices & Hardware

// List Zoom Rooms devices
const devices = await zoomApi.devices().list();

Webinars

// Webinar operations
const webinar = await zoomApi.webinar('webinar-id').getWebinar();
const registrants = await zoomApi.webinar('webinar-id').listRegistrants();

Error handling

Any non-ok response throws a ZoomError carrying the HTTP status, Zoom's application error code from the response body, and rate-limit state parsed from the response headers.

import { ZoomError } from '@nektarai/zoom-api-client';

try {
    await zoomApi.report().listMeetings(userId, { from, to });
} catch (err) {
    if (!(err instanceof ZoomError)) throw err;

    err.code; // Zoom's body error code, e.g. 124 (invalid access token)
    err.statusCode; // HTTP status, e.g. 429
    err.retryAfter; // `Retry-After` in whole seconds, or undefined
    err.rateLimit; // { type, category, limit, remaining, reset }, or undefined
}

OAuth failures return { error, reason } rather than message, so those arrive joined as err.message === 'invalid_grant: Invalid Token!' — the code stays matchable by substring while the readable half remains visible.

rateLimit.type is what distinguishes a per-second trip from a spent daily quota, which need very different retry strategies:

const DEFAULT_BACKOFF_SECONDS = 60;

if (err.statusCode === 429) {
    if (err.rateLimit?.type === 'Daily-limit') {
        // Quota is gone for the day. Reschedule past err.rateLimit.reset
        // instead of retrying — every retry before then also fails.
        reschedule(err.rateLimit.reset);
    } else {
        // QPS. `retryAfter` is optional, so always supply a fallback.
        const wait = err.retryAfter ?? DEFAULT_BACKOFF_SECONDS;
        setTimeout(retry, wait * 1000);
    }
}

Note the ??retryAfter is number | undefined and Zoom does not always send Retry-After, even on a 429. Using it unguarded gives undefined * 1000NaN, which setTimeout treats as 0 and retries instantly against an endpoint that just rejected you.

rateLimit is undefined when Zoom sent no X-RateLimit-* headers, so an absent value means "no data", not "not rate limited". Fall back to statusCode and the message in that case.

Known limitation: rate-limit headers are read on the error path only. X-RateLimit-Remaining on a successful response is discarded, because request() resolves with the parsed body and has nowhere to surface it. So you can react to a 429 but cannot yet throttle to avoid one — track your own call counts if you need that. Exposing the headers on success is additive and would not be a breaking change.

Code Generation

This library is auto-generated from Zoom's OpenAPI specifications. Zoom publishes one spec per product area; each is committed verbatim under specs/ and registered in SPEC_PATHS in scripts/generate-api.ts. To regenerate:

npm run generate

This will:

  1. Parse each OpenAPI spec in specs/
  2. Generate TypeScript types in src/types.generated.ts
  3. Generate API client methods in src/zoomApi.generated.ts
  4. Format and lint the generated code

Migration

Upgrading from 0.x? Version 1.0.0 replaced the hand-written convenience methods with a pure OpenAPI-generated API. See the migration guide for the old-to-new method mapping.

Contribution

We welcome contributions!

  1. Clone the repo
  2. Install dependencies: npm install
  3. Make your changes:
    • For API updates: refresh or add a spec in specs/ and run npm run generate
    • For core functionality: Edit files in src/
    • Add tests in test/
  4. Ensure tests pass: npm test
  5. Build: npm run build
  6. Submit a PR

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages