# Zoom Server-to-Server OAuth apps (/integrations/zoom-service-account)





Connect Zoom with a **Server-to-Server OAuth app**. Activate the app, grant the scopes your workflows need, and add its Account ID, Client ID, and client secret to Sim.

## Prerequisites [#prerequisites]

You need a Zoom **admin** whose role has permission to view and edit Server-to-Server OAuth apps, plus permission for the scopes the app will use. The **Develop** option in the Zoom Marketplace only appears for accounts with this permission.

<Callout type="warn">
  Scope selection is capped by the creating admin's own role permissions, and Zoom automatically removes admin-level scopes from the app if that admin's role is later downgraded — workflows then start failing with scope errors even though nothing changed in Sim. Create the app from an admin account you expect to keep.
</Callout>

## Set up the Server-to-Server OAuth app [#setting-up-the-server-to-server-oauth-app]

### 1. Create the app [#1-create-the-app]

<Steps>
  <Step>
    Sign in at [marketplace.zoom.us](https://marketplace.zoom.us) as a Zoom admin, click **Develop** → **Build an app**, select **Server-to-Server OAuth app**, and click **Create**. Give it a name (e.g. `Sim`)
  </Step>

  <Step>
    On the **App Credentials** page, copy the **Account ID**, **Client ID**, and **Client secret** — these are the three values you'll paste into Sim

    <Callout type="warn">
      Use the Account ID from this **App Credentials** page — it's an opaque string, not a number. The numeric account number shown in your Zoom web-portal profile is a different value, and pasting it is a documented common mistake that produces "bad request" errors when minting tokens.
    </Callout>
  </Step>

  <Step>
    In the **Information** section, fill in the required short description, company name, and developer name and email — the app can't be activated without them
  </Step>

  <Step>
    In **Scopes**, click **Add Scopes** and add the admin-level granular scopes your workflows need (see the list below)
  </Step>

  <Step>
    In **Activation**, resolve any remaining blockers and activate the app

    <Callout type="warn">
      Tokens cannot be minted until the app is activated — and deactivating it later immediately kills every token it has issued, stopping all workflows that use the credential.
    </Callout>
  </Step>
</Steps>

### 2. Choose scopes [#2-choose-scopes]

Server-to-Server OAuth apps use Zoom's granular scopes with account-level (`:admin`) variants. Grant only what your workflows use. The set Sim's Zoom tools can draw on is:

**Users:**

```
user:read:user:admin
```

**Meetings:**

```
meeting:read:meeting:admin
meeting:read:list_meetings:admin
meeting:write:meeting:admin
meeting:update:meeting:admin
meeting:delete:meeting:admin
meeting:read:invitation:admin
meeting:read:list_past_participants:admin
```

**Cloud recordings:**

```
cloud_recording:read:list_user_recordings:admin
cloud_recording:read:list_recording_files:admin
cloud_recording:delete:recording_file:admin
cloud_recording:delete:meeting_recording:admin
```

Deleting a specific recording file uses `cloud_recording:delete:recording_file:admin`. Omitting `recordingId` deletes the meeting's recordings and requires `cloud_recording:delete:meeting_recording:admin`. See Zoom's [granular scope reference](https://developers.zoom.us/docs/integrations/oauth-scopes-granular/).

Match these against what the Marketplace **Scopes** picker actually offers — Zoom's granular-scope catalog shows the `:admin` variants for account-level apps, but names occasionally differ from the user-level scopes Sim's OAuth flow requests. If a picker entry differs slightly from this list, prefer the picker's name for the matching action.

A missing scope surfaces at run time as a `4xx` error from the Zoom API naming a scope problem. Add the scope in the app's **Scopes** section and re-run the workflow — no changes are needed in Sim.

### 3. Copy the credentials [#3-copy-the-credentials]

The Client secret is bearer material for your entire Zoom account, limited only by the app's scopes. Treat it like a password — do not commit it to source control or share it publicly. Sim encrypts it at rest.

Regenerating the Client secret in the Zoom Marketplace invalidates the stored pair. If you rotate it, update the credential in Sim right away.

## Add the Server-to-Server app to Sim [#adding-the-server-to-server-app-to-sim]

<Steps>
  <Step>
    Open **Integrations** from your workspace sidebar
  </Step>

  <Step>
    Search for "Zoom" and open it, then click **Add to Sim** and choose **Add server-to-server app**
  </Step>

  <Step>
    In the **Add Zoom server-to-server app** dialog, paste the **Client ID**, **Client secret**, and **Account ID**, and optionally set a display name and description
  </Step>

  <Step>
    Click **Add server-to-server app**. Sim verifies the credentials by minting a real access token from Zoom — if it fails, the error tells you whether Zoom rejected the credentials or couldn't be reached. A rejection usually means bad credentials, an app that isn't a Server-to-Server OAuth app, or an app that hasn't been activated.
  </Step>
</Steps>

## Use the credential in workflows [#using-the-credential-in-workflows]

Add a Zoom block to your workflow. In the credential dropdown, select the saved Zoom server-to-server app. Configure the selected operation.

The block calls `api.zoom.us` using a minted access token. Operations use the same API request paths as the OAuth flow, subject to app scopes and account access.

<Callout type="warn">
  **The `me` keyword does not work with service accounts.** With a personal OAuth connection, user-scoped operations (create meeting, list meetings, list recordings) accept `me` for the connected user. A Server-to-Server app has no user context — Zoom rejects `me` with an error like "This API does not support client credentials for authorization." Always pass an explicit user ID or email address in the block's user field when using a service account.
</Callout>

Sim's Zoom tools call the standard `api.zoom.us` host. Standard commercial Zoom accounts work as-is; Zoom for Government and other regionally partitioned accounts may not be reachable at that host and aren't currently supported with service accounts.

## Token behavior [#token-behavior]

Access tokens minted from the app live for one hour and there is no refresh token — Sim simply mints a new token when one is needed. Zoom explicitly allows multiple concurrently valid tokens, so minting never invalidates workflows already in flight. Account changes can interrupt access:

* **Deactivating the app** — all minted tokens die immediately and no new ones can be issued until it's reactivated
* **Regenerating the Client secret** — the stored credentials cannot mint new tokens; reconnect the credential in Sim with the new secret

## Troubleshooting and rotation [#troubleshooting-and-rotation]

| Problem | What to check |
| - | - |
| Token request is rejected | Copy all three values from the app's **App Credentials** page. Use its opaque Account ID, rather than the numeric account number from your Zoom profile. |
| Unsupported grant or inactive app | Confirm that the credentials belong to a **Server-to-Server OAuth app** and that it is activated. A regular OAuth app cannot use this grant. |
| A user-scoped action rejects client credentials | Replace `me` with the target Zoom user's ID or email address. |
| Scope errors after a role change | Inspect the app's scopes and the creating admin's permissions, restore the required scopes, and retry. |

To rotate, regenerate the client secret in **App Credentials**, then select **Reconnect** on the saved Zoom credential in Sim and paste the new credentials. Coordinate the change: the old stored secret stops working when it is replaced.

See Zoom's [Server-to-Server OAuth guide](https://developers.zoom.us/docs/internal-apps/s2s-oauth/) for activation, role permissions, and token behavior.
