# Authenticating Zoom Meetings accounts with Nylas

Source: https://developer.nylas.com/docs/provider-guides/zoom-meetings/

Authenticate users with Zoom to [automatically add conferencing to events](/docs/v3/calendar/add-conferencing/). You create a Zoom OAuth app, connect it to Nylas as a conferencing connector, then authenticate individual users.

## Create a Zoom OAuth application

1. Sign in to your Zoom account and go to the [Zoom App Marketplace](https://marketplace.zoom.us/).
2. From the **Develop** menu at the top-right, select **Build app**.
3. Select **General app**, then click **Create**.
4. Copy the **client ID** and **client secret** and [store them securely](/docs/dev-guide/best-practices/#store-secrets-securely). You'll need these when you create the Nylas connector.
5. Optionally, click the **pencil** symbol to rename your Zoom app.
6. For the management option, select **User-managed**. This lets your users authenticate without organization-wide admin approval.
7. On the **Basic Information** page, scroll to **OAuth information** and add your redirect URI:
   - If you're using Nylas Hosted OAuth, enter the URI for your region:
     - **U.S.**: `https://api.us.nylas.com/v3/connect/callback`
     - **E.U.**: `https://api.eu.nylas.com/v3/connect/callback`
   - If you have Nylas applications in both regions, add one in the OAuth redirect URI field and the other in the allowlist further down the page.
   - If you're using Bring Your Own Authentication, enter your project's callback URI.
8. Enable both **Use Strict Mode for Redirect URLs** and **Subdomain Check** for security.
9. In the left navigation, select **Scopes**, then click **Add scopes** and select:
   - `meeting:write:meeting` (create a meeting for a user)
   - `meeting:update:meeting` (update a meeting)
   - `meeting:delete:meeting` (delete a meeting)
   - `user:read:user` (view a user)
10. Click **Done**, then **Add app now**.

You don't need to publish your Zoom app on the Marketplace if you're only authenticating users from your own organization. If you need users from multiple domains, you must go through the [Zoom app review process](https://developers.zoom.us/docs/distribute/app-review-process/).

### If Zoom rejects your redirect URIs

Zoom's automatic domain validation doesn't work with third-party OAuth hosts, so Zoom can reject `api.us.nylas.com` or `api.eu.nylas.com` when you save your redirect URI. When this happens, Zoom Support needs to manually allowlist the Nylas domain for your OAuth app.

Post a request on the [Zoom Developer Forum](https://devforum.zoom.us/). The Zoom developer relations team answers there and can help resolve redirect URI and domain validation issues for third-party apps like Nylas.

Here's a template you can adapt for your forum post:

```markdown
Title: Allowlist Nylas redirect URI for General (User-managed) OAuth app

Hi Zoom team,

I'm building a Zoom Meetings integration through Nylas, a third-party
API platform. My OAuth app is rejecting the Nylas hosted callback URL
when I try to save it as a redirect URI. Because Nylas hosts the OAuth
flow on my behalf, Zoom's automatic domain validation doesn't apply,
and I need the Nylas domain allowlisted for my app.

- App type: General (User-managed)
- Client ID: <YOUR_ZOOM_CLIENT_ID>
- Redirect URIs to allow:
  - https://api.us.nylas.com/v3/connect/callback (U.S. region)
  - https://api.eu.nylas.com/v3/connect/callback (E.U. region, if applicable)
- Scopes requested: meeting:write:meeting, meeting:update:meeting,
  meeting:delete:meeting, user:read:user

Nylas documents the required callback URLs here:
https://developer.nylas.com/docs/provider-guides/zoom-meetings/

Could you please allowlist these URIs for my app? Happy to provide
any additional verification you need.

Thanks!
```

## Create a Zoom conferencing connector

1. Create a Zoom connector either:
   - From the Nylas Dashboard: Click **Connectors**, click the plus sign next to Zoom, and enter the client ID and client secret from your Zoom app.
   - By API: Make a [`POST /v3/connectors` request](/docs/reference/api/connectors-integrations/create_connector/) with the `client_id` and `client_secret`. Don't include scopes in the connector request. Scopes are configured directly on your [Zoom OAuth app](https://developers.zoom.us/docs/integrations/oauth-scopes-granular/).
2. (Optional) To redirect users to a specific URL after Zoom authentication, add that URL to your application from the Nylas Dashboard or by making a [`POST /v3/applications/redirect-uris` request](/docs/reference/api/applications/add_callback_uri/).

## Authenticate an existing user with Zoom

The user must already have a valid Nylas grant ID before you connect them to Zoom. You can use [Hosted OAuth](/docs/v3/auth/hosted-oauth-apikey/) or [Bring Your Own Authentication](/docs/v3/auth/bring-your-own-authentication/).

### Connect to Zoom using Hosted OAuth

First, redirect the user to the Zoom authorization URL:

```bash [zoomAuth_1-Start Hosted OAuth with Zoom]
https://api.us.nylas.com/v3/connect/auth?
  client_id=<NYLAS_CLIENT_ID>
  &redirect_uri=https://myapp.com/callback-handler  // Your application's callback_uri.
  &response_type=code
  &access_type=offline
  &provider=zoom
```

After the user authorizes, Zoom redirects to your callback with a `code` parameter. Exchange it for a Zoom grant ID:

```bash [zoomAuth_1-Hosted OAuth Exchange Zoom token]
curl --request POST \
  --url 'https://api.us.nylas.com/v3/connect/token' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: <NYLAS_API_KEY>' \
  --data '{
    "code": "<NYLAS_CODE>",
    "client_id": "<NYLAS_CLIENT_ID>",
    "client_secret": "<NYLAS_API_KEY>",
    "redirect_uri": "https://myapp.example.com/callback",
    "grant_type": "authorization_code",
    "code_verifier": "nylas"
  }'
```

Save the returned grant ID as the user's `conf_grant_id`.

### Connect to Zoom using Bring Your Own authentication

If you already have Zoom credentials, follow the [Zoom OAuth documentation](https://developers.zoom.us/docs/integrations/oauth/) to get a `refresh_token`, then pass it to Nylas:

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/connect/custom' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: <NYLAS_API_KEY>' \
  --data '{
    "provider": "zoom",
    "settings": {
      "refresh_token": "<ZOOM_REFRESH_TOKEN>"
    }
  }'
```

Save the returned grant ID as the user's `conf_grant_id`.

## Use Zoom with the Calendar API

Once a user has a Zoom `conf_grant_id`, pass it in the `autocreate` object when creating an event. Nylas contacts Zoom to create the meeting, then attaches the conferencing details to the event. Note that Nylas uses the provider value `zoom` for authentication and connectors, but `Zoom Meeting` in the event conferencing object.

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/events?calendar_id=<CALENDAR_ID>' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "title": "Philosophy Club Zoom Meeting",
    "status": "confirmed",
    "busy": true,
    "conferencing": {
      "provider": "Zoom Meeting",
      "autocreate": {
        "conf_grant_id": "<USER_ZOOM_GRANT_ID>"
      }
    },
    "participants": [
      {
        "name": "Leyah Miller",
        "email": "leyah@example.com"
      },
      {
        "name": "Nyla",
        "email": "nyla@example.com"
      }
    ],
    "description": "Come ready to talk philosophy!",
    "when": {
      "start_time": 1674604800,
      "end_time": 1722382420,
      "start_timezone": "America/New_York",
      "end_timezone": "America/New_York"
    }
  }'
```

You can also customize Zoom meeting settings like waiting rooms, recording, and muting. For the full details, see [Adding conferencing to events](/docs/v3/calendar/add-conferencing/).

## Use Zoom with Nylas Scheduler

You can also attach Zoom conferencing to bookings created through [Nylas Scheduler](/docs/v3/scheduler/). The setup is the same: create a Zoom OAuth app, connector, and authenticate users as described above. Then pass the `conf_grant_id` in the Scheduler configuration instead of individual event requests.

To configure Zoom on a Scheduler booking page, see [Add conferencing to bookings](/docs/v3/scheduler/add-conferencing/). If you're using the Scheduler Editor component, you can pass the Zoom grant ID through the `conferenceProviders` prop. See the [Scheduler Editor component reference](/docs/reference/ui/scheduler-editor/) for details.

## Zoom behavior and limitations

- **Create/update failures are atomic.** When Nylas creates or updates a Zoom conference for an event, the entire operation fails if the Zoom call fails. The parent event is not modified.
- **Field sync on updates.** If you update an event's time, timezone, duration, title, or description, Nylas updates those fields on the Zoom conference too.
- **Deletes are best-effort.** Nylas deletes the provider event first, then contacts Zoom to delete the conference (requires the `meeting:delete:meeting` scope). If the Zoom delete fails, the event is still removed but the orphaned Zoom meeting persists.
- **Past events.** If you create or modify an event to occur in the past, Nylas can update the provider event, but Zoom schedules the conference for the time of the request instead.