Stitchflow
Zoom logo

Zoom User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 5, 2026

Summary and recommendation

Zoom's REST API is versioned at https://api.zoom.us/v2 and covers the full user lifecycle: create, read, update, deactivate, and delete. JWT authentication was deprecated in June 2023 and is no longer supported; all integrations must use OAuth 2.0, specifically a Server-to-Server OAuth app for backend automation.

The token exchange is a POST to https://zoom.us/oauth/token with grant_type=account_credentials and a Basic auth header carrying base64-encoded clientId:clientSecret - the returned Bearer token is used on all subsequent calls.

Core user management scopes are user:read:admin (list and read) and user:write:admin (create, update, delete, status changes). Email updates and status changes are separate PUT endpoints - PATCH /users/{userId} cannot modify email or status, a common source of silent failures in provisioning pipelines.

User IDs are UUIDs or email strings in most endpoints; UUIDs are preferred to avoid breakage after email changes, which is relevant when building an identity graph that maps Zoom identities to canonical user records across systems.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 – Server-to-Server OAuth app (for backend/automated use) or Account-level OAuth app. JWT authentication was deprecated June 2023 and is no longer supported.
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredBusiness or Enterprise (SSO must be configured)

Authentication

Auth method: OAuth 2.0 – Server-to-Server OAuth app (for backend/automated use) or Account-level OAuth app. JWT authentication was deprecated June 2023 and is no longer supported.

Setup steps

  1. Log in to the Zoom App Marketplace (marketplace.zoom.us).
  2. Create a 'Server-to-Server OAuth' app for automated/backend use.
  3. Add required user-management scopes (e.g., user:read:admin, user:write:admin).
  4. Activate the app and note the Account ID, Client ID, and Client Secret.
  5. Exchange credentials for an access token: POST https://zoom.us/oauth/token?grant_type=account_credentials&account_id={accountId} with Basic auth header (base64-encoded clientId:clientSecret).
  6. Use the returned access_token as a Bearer token in the Authorization header for all API calls.

Required scopes

Scope Description Required for
user:read:admin Read user details and list users across the account. List Users, Get User, Get User Settings
user:write:admin Create, update, and delete users on the account. Create User, Update User, Delete User, Update User Status, Update User Email
user:master Manage users on sub-accounts (Master Account only). Cross-account user management
user_zak:read Retrieve a user's ZAK (Zoom Access Key) token. Get User ZAK

User object / data model

Field Type Description On create On update Notes
id string Unique Zoom user ID (UUID). auto-generated immutable Use 'me' as alias for the authenticated user.
email string User's email address. required via PUT /users/{userId}/email only Must match a verified domain on paid plans. Cannot be changed via PATCH /users/{userId}.
first_name string User's first name. optional supported Max 64 chars.
last_name string User's last name. optional supported Max 64 chars.
display_name string Display name shown in meetings. optional supported Defaults to first_name + last_name if not set.
type integer License type: 1=Basic, 2=Licensed, 3=On-prem. required supported Changing type consumes or releases a license seat.
role_id string Role assigned to the user. optional supported Use GET /roles to list available role IDs.
status string Account status: active, inactive, pending. auto (pending until invite accepted, or active for autoCreate) via PUT /users/{userId}/status only Cannot be set directly in the create or update body.
pmi integer Personal Meeting ID (10-digit). auto-generated supported Must be unique across the account.
timezone string User's timezone in IANA format. optional supported e.g., 'America/New_York'.
dept string Department the user belongs to. optional supported Free-form string.
job_title string User's job title. optional supported Max 128 chars.
location string User's location. optional supported Free-form string.
phone_number string User's phone number. optional supported Full functionality requires Zoom Phone add-on.
group_ids array Groups the user belongs to. not directly settable via POST /groups/{groupId}/members Must be managed through the Groups API, not the user create/update body.
vanity_name string Personal meeting room name. optional supported Must be unique across the account.
host_key string 6-digit host key for claiming host in meetings. auto-generated supported Only returned with user:read:admin scope.
use_pmi boolean Whether to use PMI for instant meetings. optional supported Default false.
created_at string (ISO 8601) Timestamp when the user was created. auto-generated immutable Read-only.
last_login_time string (ISO 8601) Timestamp of the user's last login. N/A immutable Read-only.

Core endpoints

List Users

  • Method: GET
  • URL: https://api.zoom.us/v2/users
  • Watch out for: next_page_token expires after 15 minutes. Max page_size is 300. Rate limit category is 'Medium' (20 req/s), not 'Light'.

Request example

GET /v2/users?status=active&page_size=300&next_page_token=abc123
Authorization: Bearer {token}

Response example

{
  "total_records": 450,
  "next_page_token": "xyz789",
  "users": [
    {"id":"abc","email":"user@example.com","type":2,"status":"active"}
  ]
}

Get User

  • Method: GET
  • URL: https://api.zoom.us/v2/users/{userId}
  • Watch out for: Use 'me' as userId to get the token owner's profile. Fields like host_key only appear with admin scope.

Request example

GET /v2/users/abc123
Authorization: Bearer {token}

Response example

{
  "id": "abc123",
  "email": "user@example.com",
  "first_name": "Jane",
  "last_name": "Doe",
  "type": 2,
  "status": "active"
}

Create User

  • Method: POST
  • URL: https://api.zoom.us/v2/users
  • Watch out for: action controls flow: 'create' sends invite email (user stays pending); 'autoCreate' skips email but requires SSO; 'custCreate' is API-managed with no email; 'ssoCreate' requires SSO. Wrong action is a common integration error.

Request example

POST /v2/users
{
  "action": "autoCreate",
  "user_info": {
    "email": "new@example.com",
    "type": 2,
    "first_name": "Jane",
    "last_name": "Doe"
  }
}

Response example

{
  "id": "newUserId",
  "email": "new@example.com",
  "type": 2
}

Update User

  • Method: PATCH
  • URL: https://api.zoom.us/v2/users/{userId}
  • Watch out for: Returns 204 with no body on success. Email cannot be changed here; use PUT /users/{userId}/email. Status cannot be changed here; use PUT /users/{userId}/status.

Request example

PATCH /v2/users/abc123
{
  "first_name": "Janet",
  "dept": "Engineering",
  "timezone": "America/Chicago"
}

Response example

HTTP 204 No Content

Delete User

  • Method: DELETE
  • URL: https://api.zoom.us/v2/users/{userId}
  • Watch out for: Default action is 'disassociate' (removes from account, Zoom account persists). Use action=delete for permanent removal. transfer_email reassigns meetings/webinars before deletion.

Request example

DELETE /v2/users/abc123?action=delete&transfer_email=manager@example.com
Authorization: Bearer {token}

Response example

HTTP 204 No Content

Update User Status (Activate/Deactivate)

  • Method: PUT
  • URL: https://api.zoom.us/v2/users/{userId}/status
  • Watch out for: action must be 'activate' or 'deactivate'. Deactivated users cannot sign in but retain data and still consume a license seat.

Request example

PUT /v2/users/abc123/status
{
  "action": "deactivate"
}

Response example

HTTP 204 No Content

Update User Email

  • Method: PUT
  • URL: https://api.zoom.us/v2/users/{userId}/email
  • Watch out for: New email must not already exist in Zoom. User receives a confirmation email. SSO users may need a separate IdP update.

Request example

PUT /v2/users/abc123/email
{
  "email": "newemail@example.com"
}

Response example

HTTP 204 No Content

Get/Update User Settings

  • Method: GET
  • URL: https://api.zoom.us/v2/users/{userId}/settings
  • Watch out for: Settings are nested by category. Use PATCH /users/{userId}/settings to update. Some settings require specific add-ons or plan levels to take effect.

Request example

GET /v2/users/abc123/settings
Authorization: Bearer {token}

Response example

{
  "schedule_meeting": {"host_video": true},
  "recording": {"local_recording": false},
  "feature": {"meeting_capacity": 100}
}

Rate limits, pagination, and events

  • Rate limits: Zoom enforces per-second rate limits per API category. User endpoints fall under 'Light' or 'Medium' categories. Daily caps also apply and vary by plan.
  • Rate-limit headers: Yes
  • Retry-After header: Yes
  • Rate-limit notes: Response headers include X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Category, and Retry-After (on HTTP 429). List Users is categorized as 'Medium' (20 req/s). Exceeding limits returns HTTP 429.
  • Pagination method: token
  • Default page size: 30
  • Max page size: 300
  • Pagination pointer: next_page_token
Plan Limit Concurrent
Free / Pro Light endpoints: 30 req/s per account; Medium endpoints (e.g., List Users): 20 req/s per account 0
Business / Enterprise Light endpoints: 30 req/s per account; Medium endpoints: 20 req/s per account; higher daily caps 0
  • Webhooks available: Yes
  • Webhook notes: Zoom supports webhooks via a Webhook-only app or OAuth app configured in the Marketplace. Subscribe to user-related events to receive real-time HTTP POST notifications to a configured endpoint URL. Endpoint must respond with HTTP 200 within a timeout window.
  • Alternative event strategy: Poll GET /v2/users with status filters if webhooks are not feasible. Zoom Dashboard API provides activity data for audit purposes.
  • Webhook events: user.created, user.updated, user.deleted, user.deactivated, user.activated, user.invitation_accepted, user.signed_in, user.signed_out, user.presence_status_updated

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Business or Enterprise (SSO must be configured)

  • Endpoint: https://api.zoom.us/scim2

  • Supported operations: GET /Users (list users), GET /Users/{id} (get user), POST /Users (create user), PUT /Users/{id} (replace user), PATCH /Users/{id} (update user), DELETE /Users/{id} (delete/deprovision user), GET /Groups (list groups), POST /Groups (create group), PATCH /Groups/{id} (update group members), DELETE /Groups/{id} (delete group)

Limitations:

  • Bearer token authentication no longer supported; OAuth 2.0 Authorization Code Grant is required.
  • Requires Business plan or higher with SSO enabled.
  • Email domain must be associated with the Zoom account.
  • Users must have SSO login type configured for SSO-based provisioning.
  • Officially supported IdPs: Okta, Azure AD (Entra ID), OneLogin. Google Workspace is not natively supported.
  • AD Sync Tool available for on-premises Active Directory scenarios.
  • SCIM endpoint path is /scim2 (not /scim); older documentation may reference the deprecated /scim path.

Common scenarios

Three scenarios cover the majority of production integration patterns.

For SSO-based provisioning with no invite email, POST /v2/users with action='autoCreate' and type=2. This requires SSO to be configured and the email domain verified on the account; without those prerequisites, the call fails silently or falls back to pending status. Use action='create' if SSO is not in place - it sends an invite email and leaves the user in pending status until accepted.

For offboarding, the correct sequence is: deactivate immediately via PUT /v2/users/{userId}/status with action='deactivate', then downgrade the license type to 1 (Basic) via PATCH /v2/users/{userId} to free the seat, then permanently delete via DELETE /v2/users/{userId}?action=delete&transfer_email={manager} to reassign meetings and recordings before removal. Skipping the type downgrade before deletion still frees the seat, but the transfer_email param on DELETE is the only mechanism to preserve scheduled meetings and cloud recordings - omitting it results in unrecoverable data loss.

For bulk directory sync, GET /v2/users?status=active&page_size=300 with next_page_token pagination. The token expires after 15 minutes; for large accounts, complete pagination in a single run or implement retry-from-page-one logic. Pair the initial full load with webhooks (user.created, user.updated, user.deleted) to keep the identity graph current incrementally without repeated full scans.

Provision a new licensed user via SSO (no invite email)

  1. Obtain an OAuth 2.0 access token: POST https://zoom.us/oauth/token?grant_type=account_credentials&account_id={accountId} with Basic auth (base64 clientId:clientSecret).
  2. POST /v2/users with action='autoCreate', user_info.type=2, and the user's SSO-linked email.
  3. Verify the user is active: GET /v2/users/{userId} and confirm status='active'.
  4. Optionally assign to a group: POST /v2/groups/{groupId}/members with the new user's ID.
  5. Optionally configure user settings: PATCH /v2/users/{userId}/settings.

Watch out for: autoCreate requires SSO to be configured on the account and the email domain to be verified. Without SSO, use action='create', which sends an invite email and leaves the user in 'pending' status until accepted.

Offboard a user when they leave the organization

  1. Look up the user by email: GET /v2/users/{email} (email can be used as userId).
  2. Deactivate the user immediately: PUT /v2/users/{userId}/status with body {"action": "deactivate"}.
  3. Downgrade license to Basic to free the seat: PATCH /v2/users/{userId} with {"type": 1}.
  4. Transfer meetings and recordings: DELETE /v2/users/{userId}?action=delete&transfer_email=manager@example.com for permanent removal with data transfer.

Watch out for: Deactivation alone does not free a license seat. The transfer_email query param on DELETE reassigns meetings and webinars to another user before permanent deletion. Deleted users cannot be recovered.

Bulk-list all active users and sync to an external directory

  1. GET /v2/users?status=active&page_size=300 to fetch the first page.
  2. Check response for next_page_token; if present, repeat GET with &next_page_token={token}.
  3. Continue until next_page_token is absent or empty; use total_records for progress tracking.
  4. Map Zoom user fields (id, email, first_name, last_name, type, dept, role_id) to the external directory schema.
  5. Subscribe to user.created, user.updated, and user.deleted webhooks to keep the sync incremental after the initial load.

Watch out for: next_page_token expires in 15 minutes. For large accounts, complete pagination quickly or implement retry-from-start logic. List Users is rate-limited at 20 req/s (Medium category).

Why building this yourself is a trap

The most consequential API trap is the action parameter on POST /v2/users. Four values exist - create, autoCreate, custCreate, ssoCreate - each with different email, SSO, and activation behaviors.

Choosing the wrong action produces a user in an unexpected state (pending instead of active, or active without SSO linkage) that is not immediately visible in the API response, only in a subsequent GET. This is the leading cause of provisioning pipeline failures in Zoom integrations.

The DELETE endpoint defaults to disassociate, not permanent deletion. Without action=delete, the user is removed from the account but their Zoom identity persists, which creates orphaned records in any identity graph that relies on Zoom user IDs as a join key.

Pass action=delete explicitly for permanent removal, and always supply transfer_email to avoid silent recording loss.

Rate limits require attention at scale: List Users is categorized as Medium (20 req/s), not Light (30 req/s). The response headers X-RateLimit-Remaining and Retry-After are present on 429 responses and should drive backoff logic.

SCIM is available at https://api.zoom.us/scim2 (note: scim2, not scim) on Business plan or higher with SSO enabled; Bearer token auth to the SCIM endpoint is no longer supported and must be replaced with OAuth 2.0 Authorization Code Grant.

Automate Zoom workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 5, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen