Zoom Admin

Zoom Admin API integration with managed OAuth. Manage users, meetings, webinars, recordings, and account settings with admin-level access. Use this skill when users want to list users, create or manage meetings, view recordings, check user/account settings, or administer a Zoom workspace. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Security: The MATON_API_KEY authenticates with Maton.ai but grants NO access to Zoom by itself. Zoom access requires explicit OAuth authorization by the user through Maton's connect flow. Access is strictly scoped to the Zoom account the user has authorized. All API requests are proxied through Maton's gateway, which handles OAuth token management. Only connect the intended Zoom account and revoke the connection when no longer needed. Requires network access and valid Maton API key.

Audits

Pass

Install

openclaw skills install zoom-admin-api

Zoom Admin

Access the Zoom API with managed OAuth authentication and admin-level scopes. Manage users, meetings, webinars, recordings, and account settings.

Quick Start

# List users in your Zoom account
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/zoom-admin/v2/users?status=active&page_size=30')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Base URL

https://api.maton.ai/zoom-admin/{native-api-path}

Replace {native-api-path} with the actual Zoom API endpoint path (e.g., v2/users, v2/meetings/123). The gateway proxies requests to api.zoom.us and automatically injects your OAuth token.

Authentication

All requests require the Maton API key in the Authorization header:

Authorization: Bearer $MATON_API_KEY

Environment Variable: Set your API key as MATON_API_KEY:

export MATON_API_KEY="YOUR_API_KEY"

Getting Your API Key

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key

Connection Management

Manage your Zoom Admin OAuth connections at https://api.maton.ai.

List Connections

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=zoom-admin&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Create Connection

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'zoom-admin'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Get Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Response:

{
  "connection": {
    "connection_id": "{connection_id}",
    "status": "ACTIVE",
    "creation_time": "2025-12-08T07:20:53.488460Z",
    "last_updated_time": "2026-01-31T20:03:32.593153Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "zoom-admin",
    "metadata": {}
  }
}

Open the returned url in a browser to complete OAuth authorization.

Delete Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Specifying Connection

If you have multiple Zoom Admin connections, specify which one to use with the Maton-Connection header:

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/zoom-admin/v2/users?status=active')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If you have multiple connections, always include this header to ensure requests go to the intended account.

Security & Permissions

  • No implicit access: The MATON_API_KEY alone cannot access Zoom. The user must explicitly authorize a Zoom account via OAuth through Maton's connect flow.
  • Scoped access: Access is limited to the specific Zoom account the user authorized. Admin scopes grant read/write access to users, meetings, webinars, and recordings within that account only.
  • Write safeguards: All write operations (POST, PATCH, PUT, DELETE) require explicit user approval. Before executing any create, update, or delete call, confirm the exact target resource, account, and intended effect with the user.
  • Least privilege: Connect only the intended Zoom account. Revoke or delete the connection when it is no longer needed.
  • Data handling: API requests and responses flow through Maton's gateway, which handles OAuth token injection. No credentials are stored in this skill or exposed to the agent.

API Reference

User Operations

List Users

GET /zoom-admin/v2/users?status=active&page_size=30

Query Parameters:

ParamTypeDefaultDescription
statusstringactiveactive, inactive, or pending
page_sizeinteger30Max: 2000
next_page_tokenstringPagination token (15-min expiry)
role_idstringFilter by role ID

Response:

{
  "page_size": 30,
  "total_records": 1,
  "next_page_token": "",
  "users": [
    {
      "id": "a-IOECePRV265Gy_wotUdQ",
      "first_name": "Richard",
      "last_name": "Song",
      "display_name": "Richard Song",
      "email": "user@example.com",
      "type": 1,
      "pmi": 6862513852,
      "timezone": "America/Los_Angeles",
      "verified": 1,
      "status": "active",
      "created_at": "2025-03-21T21:52:50Z",
      "last_login_time": "2026-05-01T01:01:08Z",
      "role_id": "0"
    }
  ]
}

User type values: 1 = Basic, 2 = Licensed, 4 = Unassigned, 99 = None.

Get User

GET /zoom-admin/v2/users/{userId}

Use me for the authenticated user, or a user ID / email address.

Response:

{
  "id": "a-IOECePRV265Gy_wotUdQ",
  "first_name": "Richard",
  "last_name": "Song",
  "display_name": "Richard Song",
  "email": "user@example.com",
  "type": 1,
  "role_name": "Owner",
  "pmi": 6862513852,
  "use_pmi": false,
  "personal_meeting_url": "https://us05web.zoom.us/j/6862513852?pwd=...",
  "timezone": "America/Los_Angeles",
  "status": "active",
  "account_id": "ciah2jjMRgedBSqxO8bOjA",
  "role_id": "0",
  "login_types": [100, 1],
  "created_at": "2025-03-21T21:52:50Z",
  "last_login_time": "2026-05-01T01:01:08Z"
}

Get User Settings

GET /zoom-admin/v2/users/{userId}/settings

Query Parameters:

ParamTypeDescription
optionstringmeeting_authentication, recording_authentication, or meeting_security

Returns detailed settings grouped into sections: schedule_meeting, in_meeting, email_notification, recording, telephony, feature, whiteboard, audio_conferencing, etc.

Meeting Operations

List Meetings

GET /zoom-admin/v2/users/{userId}/meetings?type=scheduled&page_size=30

Query Parameters:

ParamTypeDefaultDescription
typestringlivescheduled, live, upcoming, upcoming_meetings, previous_meetings
page_sizeinteger30Max: 300
next_page_tokenstringPagination token (15-min expiry)

Response:

{
  "page_size": 30,
  "total_records": 11,
  "next_page_token": "B4Tr0tLbJKQMnChspbYH7UUvt7g0UeDQNh2",
  "meetings": [
    {
      "uuid": "SukzvlkXQO2rNcNPKUGCpw==",
      "id": 89560318205,
      "host_id": "a-IOECePRV265Gy_wotUdQ",
      "topic": "Team Standup",
      "type": 2,
      "start_time": "2026-03-30T18:00:00Z",
      "duration": 30,
      "timezone": "America/Los_Angeles",
      "created_at": "2026-03-29T18:01:40Z",
      "join_url": "https://us05web.zoom.us/j/89560318205?pwd=..."
    }
  ]
}

Meeting type values: 1 = Instant, 2 = Scheduled, 3 = Recurring (no fixed time), 4 = PMI, 8 = Recurring (fixed time).

Get Meeting

GET /zoom-admin/v2/meetings/{meetingId}

Query Parameters:

ParamTypeDescription
occurrence_idstringFor recurring meetings
show_previous_occurrencesbooleanShow previous occurrences

Returns full meeting details including settings, recurrence, occurrences, join_url, start_url, password, etc.

Create Meeting

POST /zoom-admin/v2/users/{userId}/meetings
Content-Type: application/json

{
  "topic": "Weekly Team Sync",
  "type": 2,
  "start_time": "2026-05-02T10:00:00Z",
  "duration": 30,
  "timezone": "America/Los_Angeles",
  "agenda": "Discuss project updates",
  "settings": {
    "host_video": true,
    "participant_video": true,
    "join_before_host": false,
    "mute_upon_entry": true,
    "waiting_room": false,
    "auto_recording": "none",
    "audio": "voip"
  }
}

Key Request Fields:

FieldTypeDescription
topicstringMeeting topic
typeinteger1 = Instant, 2 = Scheduled, 3 = Recurring (no fixed), 8 = Recurring (fixed)
start_timestringISO 8601 datetime (required for type 2 and 8)
durationintegerDuration in minutes
timezonestringe.g., America/New_York
passwordstringUp to 10 characters
agendastringMax 2000 characters
recurrenceobjectRequired for type 8
settingsobjectMeeting settings

Returns the created meeting object (same as Get Meeting).

Update Meeting

PATCH /zoom-admin/v2/meetings/{meetingId}
Content-Type: application/json

{
  "topic": "Updated Meeting Topic",
  "duration": 45
}

All fields are optional. Returns 204 No Content on success.

Delete Meeting

DELETE /zoom-admin/v2/meetings/{meetingId}

Query Parameters:

ParamTypeDescription
occurrence_idstringDelete specific occurrence of recurring meeting
schedule_for_reminderbooleanNotify host about cancellation
cancel_meeting_reminderstringNotify registrants (true/false)

Returns 204 No Content on success.

Get Past Meeting Details

GET /zoom-admin/v2/past_meetings/{meetingId}

Use the meeting ID or UUID. If the UUID starts with / or contains //, it must be double-URL-encoded.

Response:

{
  "uuid": "/LAYgqiEQ8CW4NlhkyOvVA==",
  "id": 89560318205,
  "host_id": "a-IOECePRV265Gy_wotUdQ",
  "type": 2,
  "topic": "Team Standup",
  "user_name": "Richard Song",
  "user_email": "user@example.com",
  "start_time": "2026-03-30T18:02:25Z",
  "end_time": "2026-03-30T18:09:50Z",
  "duration": 8,
  "total_minutes": 22,
  "participants_count": 3,
  "source": "Calendly for Zoom"
}

List Past Meeting Instances

GET /zoom-admin/v2/past_meetings/{meetingId}/instances

Response:

{
  "meetings": [
    {
      "uuid": "/LAYgqiEQ8CW4NlhkyOvVA==",
      "start_time": "2026-03-30T18:02:25Z"
    }
  ]
}

Webinar Operations

Webinar endpoints require a Webinar plan on the Zoom account.

List Webinars

GET /zoom-admin/v2/users/{userId}/webinars?page_size=30

Query Parameters:

ParamTypeDefaultDescription
typestringscheduledscheduled or upcoming
page_sizeinteger30Max: 300
next_page_tokenstringPagination token

Response:

{
  "page_size": 30,
  "total_records": 0,
  "next_page_token": "",
  "webinars": [
    {
      "uuid": "...",
      "id": 12345678901,
      "host_id": "...",
      "topic": "Product Launch Webinar",
      "type": 5,
      "start_time": "2026-05-15T14:00:00Z",
      "duration": 60,
      "timezone": "America/Los_Angeles",
      "join_url": "https://us05web.zoom.us/j/..."
    }
  ]
}

Webinar type values: 5 = Webinar, 6 = Recurring (no fixed time), 9 = Recurring (fixed time).

Get Webinar

GET /zoom-admin/v2/webinars/{webinarId}

Returns full webinar details including settings, recurrence, and registration info.

Recording Operations

List User Recordings

GET /zoom-admin/v2/users/{userId}/recordings?from=2026-04-01&to=2026-04-30&page_size=30

Query Parameters:

ParamTypeDescription
fromstringStart date (yyyy-mm-dd). Max range: 1 month. Max past: 6 months
tostringEnd date (yyyy-mm-dd)
page_sizeintegerMax: 300
next_page_tokenstringPagination token
trashbooleanList trashed recordings

Response:

{
  "from": "2026-04-01",
  "to": "2026-04-30",
  "total_records": 0,
  "next_page_token": "",
  "meetings": [
    {
      "uuid": "...",
      "id": 12345678901,
      "host_id": "...",
      "topic": "Meeting Topic",
      "start_time": "2026-04-15T10:00:00Z",
      "duration": 45,
      "total_size": 52428800,
      "recording_count": 2,
      "recording_files": [
        {
          "id": "...",
          "file_type": "MP4",
          "file_extension": "MP4",
          "file_size": 41943040,
          "play_url": "https://...",
          "download_url": "https://...",
          "recording_type": "shared_screen_with_speaker_view",
          "status": "completed"
        }
      ]
    }
  ]
}

Get Meeting Recordings

GET /zoom-admin/v2/meetings/{meetingId}/recordings

Use the meeting ID or UUID. If the UUID starts with / or contains //, it must be double-URL-encoded.

Query Parameters:

ParamTypeDescription
include_fieldsstringdownload_access_token for JWT download token
ttlintegerToken TTL in seconds (0–604800, default: 172800)

Returns the meeting's recording files with download URLs.

Account Operations

Get Account Settings

GET /zoom-admin/v2/accounts/{accountId}/settings

Use me for the connected account. Requires a paid Zoom plan.

Query Parameters:

ParamTypeDescription
optionstringmeeting_authentication, recording_authentication, security, meeting_security

Returns account-level settings grouped into sections: security, schedule_meeting, in_meeting, recording, telephony, feature, chat, etc.

Pagination

Zoom uses token-based pagination via next_page_token. Tokens expire after 15 minutes.

# First page
GET /zoom-admin/v2/users?page_size=30

# Next page
GET /zoom-admin/v2/users?page_size=30&next_page_token={next_page_token}

Response includes pagination fields:

{
  "page_size": 30,
  "total_records": 100,
  "next_page_token": "B4Tr0tLbJKQMnChspbYH7UUvt7g0UeDQNh2"
}

When next_page_token is empty, there are no more pages. Do not reuse expired tokens — start from the first page if a token expires.

Code Examples

JavaScript

const response = await fetch(
  'https://api.maton.ai/zoom-admin/v2/users?status=active&page_size=10',
  {
    headers: {
      'Authorization': `Bearer ${process.env.MATON_API_KEY}`
    }
  }
);
const data = await response.json();

Python

import os
import requests

response = requests.get(
    'https://api.maton.ai/zoom-admin/v2/users',
    headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
    params={'status': 'active', 'page_size': 10}
)
data = response.json()

Notes

  • The zoom-admin app uses admin-level OAuth scopes that grant access to all users in the Zoom account
  • Meeting IDs are integers; UUIDs are base64-encoded strings. Both can be used in most endpoints
  • UUIDs starting with / or containing // must be double-URL-encoded when used in path parameters
  • Webinar endpoints require a Webinar add-on plan on the Zoom account
  • Account Settings endpoint (/v2/accounts/me/settings) requires a paid Zoom plan
  • Zoom enforces a limit of 100 meeting create/update operations per day per user
  • IMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing
  • IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments

Error Handling

StatusMeaning
400Missing Zoom Admin connection or invalid request
401Invalid or missing Maton API key
404Resource not found (meeting, user, recording)
429Rate limited
4xx/5xxPassthrough error from Zoom API

Zoom Rate Limits

CategoryPro PlanBusiness+
LIGHT4/sec, 6,000/day30/sec
MEDIUM2/sec, 2,000/day20/sec
HEAVY1/sec, 1,000/day10/sec

Rate-limited responses include a Retry-After header.

Troubleshooting: API Key Issues

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Troubleshooting: Invalid App Name

  1. Ensure your URL path starts with zoom-admin. For example:
  • Correct: https://api.maton.ai/zoom-admin/v2/users
  • Incorrect: https://api.maton.ai/v2/users

Resources