Zoom Integration

Purpose and Scope

The Zoom integration lets a self-hosted Cal.diy instance create Zoom video meetings through a Zoom Marketplace OAuth application. This page is for administrators who are wiring Zoom into their own deployment and need to know which credentials to create, where the OAuth callback must point, and how the repository exposes the integration package. The setup is intentionally centered on a user-managed OAuth app, not a marketplace-published public app, because the official guide instructs self-hosters to create a private Zoom app, store the resulting client credentials, and enable only the meeting scope needed by Cal.diy.

Sources: apps/docs/content/apps/zoom.mdx

The important distinction for operators is that Zoom is configured in two places. First, Zoom Marketplace must know the exact redirect URL for the Cal.diy instance, including the deployment origin and integration callback path. Second, Cal.diy must receive the client ID and client secret through environment variables so the app-store integration can start and complete OAuth. If either side is inconsistent, users may see OAuth failures when they try to add Zoom from Cal.diy settings, even if the Zoom app itself was created successfully.

Sources: apps/docs/content/apps/zoom.mdx, packages/app-store/zoomvideo/api/index.ts

Relevant Source Files

  • apps/docs/content/apps/zoom.mdx — First-party setup guide for creating the Zoom OAuth app, saving credentials, registering the callback URL, enabling the allow list, and adding the required Meeting scope.
  • packages/app-store/zoomvideo/api/index.ts — Public API surface for the Zoom app package; it exports the add and callback handlers used by the integration route layer.
  • packages/app-store/zoomvideo/index.ts — Package-level entrypoint for the Zoom video integration; it re-exports api, lib, and metadata namespaces for the app-store system.

Setup Flow

Start in Zoom Marketplace and sign in with the Zoom account that should own the integration. The guide tells administrators to choose Develop, build a new OAuth app, provide a name, and select the user-managed app type. It also says to deselect publishing on the Zoom App Marketplace. That matters because the Cal.diy self-hosting flow is for a private OAuth app tied to your instance, not for distributing an app to unrelated Zoom tenants. After creating the app, copy the issued client ID and client secret before moving to redirect and scope configuration.

Sources: apps/docs/content/apps/zoom.mdx

Add the credentials to the Cal.diy environment under the exact names expected by the integration guide:

ZOOM_CLIENT_ID=your_zoom_client_id
ZOOM_CLIENT_SECRET=your_zoom_client_secret

These values are deployment secrets and should be treated like any other OAuth client secret. They belong in the environment used by the running Cal.diy web service, not in browser-visible configuration or committed source files. After changing them, restart or redeploy the application so the process that serves integration routes can read the new values. If you run multiple environments, create separate Zoom OAuth apps or at least separate redirect settings for each externally visible origin to avoid mixing local, staging, and production callbacks.

Sources: apps/docs/content/apps/zoom.mdx

OAuth Callback and Zoom Marketplace Settings

The redirect URL registered in Zoom must be the public Cal.diy URL followed by the Zoom video callback route. The guide gives the shape as the application URL plus the integration callback path. In practice, replace the placeholder host with the exact origin users reach in their browser, including the scheme. A deployment served at an HTTPS domain should register the HTTPS URL, while a local test instance should use whatever reachable URL Zoom can redirect to. The callback path is specific to the Zoom video app and should not be replaced with a generic OAuth endpoint.

<Cal.diy URL>/api/integrations/zoomvideo/callback

Sources: apps/docs/content/apps/zoom.mdx

After entering the redirect URL, the Zoom app settings also need the same URL in the allow list, and the guide calls out enabling the subdomain check. The instruction to confirm that the form displays saved is operationally useful: an unsaved allow-list value can produce a failure that looks like an application bug but is actually a Zoom-side validation problem. The setup then skips basic information and proceeds to Scopes, where the Meeting category is selected and the meeting write permission is checked before saving.

Sources: apps/docs/content/apps/zoom.mdx

System-to-Code Mapping

The repository maps the reader-facing callback path into the app-store package through a compact public API namespace. The Zoom API entrypoint exports two default handlers named add and callback. The add handler is the package surface used when a user starts connecting Zoom, while the callback handler is the package surface used after Zoom redirects back to Cal.diy. The source evidence does not expose the handler bodies here, but the export names match the setup flow: one action begins OAuth, and the other receives the authorization result at the configured callback route.

Sources: packages/app-store/zoomvideo/api/index.ts, apps/docs/content/apps/zoom.mdx

At the package boundary, the Zoom video integration re-exports three namespaces: api, lib, and metadata. That shape is consistent with an app-store integration where route handlers, supporting library code, and app metadata are consumed by the broader app-store registry. For administrators, the practical takeaway is that the OAuth settings documented in the guide correspond to a named package under the Zoom video app, not to a one-off route unrelated to the app store. For contributors, the package entrypoint is the starting place for understanding how the integration is surfaced to the rest of the monorepo.

Sources: packages/app-store/zoomvideo/index.ts, packages/app-store/zoomvideo/api/index.ts

Compact Reference

ItemValueNotes
Environment variableZOOM_CLIENT_IDStores the Zoom OAuth client ID copied from Zoom Marketplace.
Environment variableZOOM_CLIENT_SECRETStores the Zoom OAuth client secret copied from Zoom Marketplace.
OAuth app typeUser-managed appThe setup guide directs self-hosters to use this app type.
Marketplace visibilityNot publishedThe guide says to deselect publication on the Zoom App Marketplace.
Redirect path/api/integrations/zoomvideo/callbackAppend this path to the public Cal.diy URL.
Zoom scopemeeting:writeAdd this from the Meeting scope category.
API exportsadd, callbackExported by the Zoom video API package entrypoint.
Package exportsapi, lib, metadataExported by the Zoom video package entrypoint.

Sources: apps/docs/content/apps/zoom.mdx, packages/app-store/zoomvideo/api/index.ts, packages/app-store/zoomvideo/index.ts

Validation and Troubleshooting

When validating the integration, check the configuration in the same order as the OAuth flow. Confirm the Cal.diy process has both Zoom environment variables, then confirm the Zoom app has the exact redirect URL and that the allow-list entry was saved. Next, verify the Meeting scope includes the write permission named by the guide. Only after those pieces are correct should you debug application routing. A common class of errors comes from mismatched origins, such as registering one domain in Zoom while users access Cal.diy through another host, protocol, or reverse-proxy URL.

Sources: apps/docs/content/apps/zoom.mdx

For local or self-hosted deployments, remember that Zoom redirects through the browser to the URL configured in Marketplace. If that URL is not reachable from the user’s browser, the callback cannot complete even though the server has valid credentials. Likewise, if the deployment is moved to a new domain, the redirect URL and allow list must be updated in Zoom before users reconnect the app. Once the credentials, callback, allow list, and scope are all aligned, the official guide concludes that the integration can be added from Cal.diy settings.

Sources: apps/docs/content/apps/zoom.mdx

Next Steps

After Zoom is connected, test it by adding the Zoom app in Cal.diy settings and creating a booking flow that uses Zoom video conferencing. If the OAuth start page works but the return step fails, inspect the callback URL and environment first because those are the parts directly described by the setup guide and package exports. Contributors who need to change behavior should begin at the Zoom video package entrypoint, then follow the exported api namespace into add and callback implementation files in the same package area.

Sources: packages/app-store/zoomvideo/index.ts, packages/app-store/zoomvideo/api/index.ts