Access the Zoom API with managed OAuth authentication and admin-level scopes. Manage users, meetings, webinars, recordings, and account settings.
# 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
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.
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"
Manage your Zoom Admin OAuth connections at https://api.maton.ai.
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
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
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.
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
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.
GET /zoom-admin/v2/users?status=active&page_size=30
Query Parameters:
| Param | Type | Default | Description |
|---|---|---|---|
| ------- | ------ | --------- | ------------- |
status | string | active | active, inactive, or pending |
page_size | integer | 30 | Max: 2000 |
next_page_token | string | Pagination token (15-min expiry) | |
role_id | string | Filter 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 /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 /zoom-admin/v2/users/{userId}/settings
Query Parameters:
| Param | Type | Description |
|---|---|---|
| ------- | ------ | ------------- |
option | string | meeting_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.
GET /zoom-admin/v2/users/{userId}/meetings?type=scheduled&page_size=30
Query Parameters:
| Param | Type | Default | Description |
|---|---|---|---|
| ------- | ------ | --------- | ------------- |
type | string | live | scheduled, live, upcoming, upcoming_meetings, previous_meetings |
page_size | integer | 30 | Max: 300 |
next_page_token | string | Pagination 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 /zoom-admin/v2/meetings/{meetingId}
Query Parameters:
| Param | Type | Description |
|---|---|---|
| ------- | ------ | ------------- |
occurrence_id | string | For recurring meetings |
show_previous_occurrences | boolean | Show previous occurrences |
Returns full meeting details including settings, recurrence, occurrences, join_url, start_url, password, etc.
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:
| Field | Type | Description |
|---|---|---|
| ------- | ------ | ------------- |
topic | string | Meeting topic |
type | integer | 1 = Instant, 2 = Scheduled, 3 = Recurring (no fixed), 8 = Recurring (fixed) |
start_time | string | ISO 8601 datetime (required for type 2 and 8) |
duration | integer | Duration in minutes |
timezone | string | e.g., America/New_York |
password | string | Up to 10 characters |
agenda | string | Max 2000 characters |
recurrence | object | Required for type 8 |
settings | object | Meeting settings |
Returns the created meeting object (same as Get 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 /zoom-admin/v2/meetings/{meetingId}
Query Parameters:
| Param | Type | Description |
|---|---|---|
| ------- | ------ | ------------- |
occurrence_id | string | Delete specific occurrence of recurring meeting |
schedule_for_reminder | boolean | Notify host about cancellation |
cancel_meeting_reminder | string | Notify registrants (true/false) |
Returns 204 No Content on success.
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"
}
GET /zoom-admin/v2/past_meetings/{meetingId}/instances
Response:
{
"meetings": [
{
"uuid": "/LAYgqiEQ8CW4NlhkyOvVA==",
"start_time": "2026-03-30T18:02:25Z"
}
]
}
Webinar endpoints require a Webinar plan on the Zoom account.
GET /zoom-admin/v2/users/{userId}/webinars?page_size=30
Query Parameters:
| Param | Type | Default | Description |
|---|---|---|---|
| ------- | ------ | --------- | ------------- |
type | string | scheduled | scheduled or upcoming |
page_size | integer | 30 | Max: 300 |
next_page_token | string | Pagination 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 /zoom-admin/v2/webinars/{webinarId}
Returns full webinar details including settings, recurrence, and registration info.
GET /zoom-admin/v2/users/{userId}/recordings?from=2026-04-01&to=2026-04-30&page_size=30
Query Parameters:
| Param | Type | Description |
|---|---|---|
| ------- | ------ | ------------- |
from | string | Start date (yyyy-mm-dd). Max range: 1 month. Max past: 6 months |
to | string | End date (yyyy-mm-dd) |
page_size | integer | Max: 300 |
next_page_token | string | Pagination token |
trash | boolean | List 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 /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:
| Param | Type | Description |
|---|---|---|
| ------- | ------ | ------------- |
include_fields | string | download_access_token for JWT download token |
ttl | integer | Token TTL in seconds (0–604800, default: 172800) |
Returns the meeting's recording files with download URLs.
GET /zoom-admin/v2/accounts/{accountId}/settings
Use me for the connected account. Requires a paid Zoom plan.
Query Parameters:
| Param | Type | Description |
|---|---|---|
| ------- | ------ | ------------- |
option | string | meeting_authentication, recording_authentication, security, meeting_security |
Returns account-level settings grouped into sections: security, schedule_meeting, in_meeting, recording, telephony, feature, chat, etc.
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.
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();
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()
zoom-admin app uses admin-level OAuth scopes that grant access to all users in the Zoom account/ or containing // must be double-URL-encoded when used in path parameters/v2/accounts/me/settings) requires a paid Zoom plancurl -g when URLs contain brackets to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| -------- | --------- |
| 400 | Missing Zoom Admin connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 404 | Resource not found (meeting, user, recording) |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Zoom API |
| Category | Pro Plan | Business+ |
|---|---|---|
| ---------- | ---------- | ----------- |
| LIGHT | 4/sec, 6,000/day | 30/sec |
| MEDIUM | 2/sec, 2,000/day | 20/sec |
| HEAVY | 1/sec, 1,000/day | 10/sec |
Rate-limited responses include a Retry-After header.
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
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
zoom-admin. For example:https://api.maton.ai/zoom-admin/v2/usershttps://api.maton.ai/v2/users共 1 个版本