La interfaz está localizada; el contenido de las Skills de los autores se mantiene en su idioma original, y algunas páginas explicativas se ofrecen en inglés.
Explorar Skills
Desarrollo · SKILL.md

zoom-api

zoom-api

Integrates Zoom API v2 (Meetings, Webinars, Recordings, Phone, Users) using the zoom-python-client SDK v0.2+ with Server-to-Server OAuth, proper pagination, and rate-limit handling.

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentación de la Skill

GitHub

name: zoom-api description: Integrates Zoom API v2 (Meetings, Webinars, Recordings, Phone, Users) using the zoom-python-client SDK v0.2+ with Server-to-Server OAuth, proper pagination, and rate-limit handling. license: MIT compatibility: opencode metadata: version: "1.0.0" domain: coding triggers: zoom, zoom api, zoom meetings, create zoom meeting, zoom sdk, zoom webinars, zoom recording, zoom-python archetypes:

  • tactical
  • generation anti_triggers:
  • brainstorming
  • vague ideation
  • code golf
  • over-engineering response_profile: verbosity: low directive_strength: high abstraction_level: operational role: implementation scope: implementation output-format: code content-types:
  • code
  • guidance
  • do-dont
  • examples related-skills: coding-twilio-api, coding-slack-api, coding-sendgrid-api

Zoom API Integration (Meetings, Webinars, Recordings, Users)

Integrates the Zoom API v2 — Meetings, Webinars, Recordings, Phone, and Users management — using the zoom-python-client SDK v0.2+ with Server-to-Server OAuth authentication. When loaded, this skill makes the model implement Zoom API operations with proper token management, pagination for list endpoints, rate-limit handling, and webhook event processing.

TL;DR for Code Generation

  • Initialize ZoomApiClient from environment variables using ZoomApiClient.init_from_env() — never hardcode credentials
  • Use Server-to-Server OAuth (account_id, client_id, client_secret) — JWT tokens are deprecated by Zoom
  • Handle pagination explicitly: use next_page_token in list endpoint responses to iterate all pages
  • Wrap API calls in try/except for requests.exceptions.HTTPError with status code inspection
  • Respect rate limits — Zoom returns X-RateLimit-Limit and X-RateLimit-Remaining headers
  • Validate required parameters: topic, start_time, duration for meetings; topic for webinars
  • Use ISO 8601 format (2026-05-23T15:00:00Z) for all datetime parameters

Zoom meetings and webinars programmatically

  • Listing meeting recordings and managing cloud recording retention policies
  • Managing Zoom users (create, suspend, update, list) in a Zoom account
  • Integrating Zoom Phone for call log retrieval, extension management, and call routing
  • Processing Zoom webhook events (meeting started/ended, participant joined/left, recording completed)
  • Building apps with the Zoom Apps SDK for embedded experiences within Zoom meetings

Zoom RTMS SDK (Real-Time Media Streams) instead

  • Managing Zoom Rooms hardware or calendar integration — those require separate Zoom Room management APIs

Core Workflow

Authenticate with Server-to-Server OAuth: Initialize ZoomApiClient from environment variables (ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, ZOOM_CLIENT_SECRET). The SDK handles token caching and refresh automatically. Checkpoint: Verify authentication by calling zoom_client.users.get_user("me") — this returns the authenticated accounts owner details.; Identify the Target Resource: Determine user ID or email address (for user-scoped endpoints), or use the API root for account-scoped operations. User IDs can be me (the authenticated user), an email address, or the numeric user ID. Checkpoint: Confirm the user exists with get_user() before creating meetings for them.; Execute the API Operation: Call the appropriate method: create_meeting(), get_meeting(), list_recordings(), etc. Pass required parameters as keyword arguments. For list endpoints, implement pagination using next_page_token from the response. Checkpoint: Validate the response contains expected fields — for meetings, check join_url and id are present.; Handle Errors and Rate Limits: Catch requests.exceptions.HTTPError and inspect the status code: 400 (bad request / validation), 401 (bad auth / token expired), 404 (resource not found), 429 (rate limited). For 429, implement exponential backoff using the Retry-After header. Checkpoint: Log the response payload for 400s to capture validation error details.; Process Webhooks: Zoom sends event notifications to your webhook endpoint as JSON POST bodies. Validate the webhook using the Authorization header (Bearer token comparison). Acknowledge by returning HTTP 200 immediately. Checkpoint: Return 200 within 3 seconds — Zoom retries for 24 hours if you do not acknowledge.

Implementation Patterns

Pattern 1: Creating a Scheduled Meeting

import os
from datetime import datetime, timedelta
from zoom_python_client.zoom_api_client import ZoomApiClient
import requests

# ❌ BAD — JWT token (deprecated), hardcoded credentials, no error handling
import jwt
token = jwt.encode({"iss": "API_KEY", "exp": datetime.now() + timedelta(hours=1)}, "API_SECRET")
headers = {"Authorization": f"Bearer {token}"}
resp = requests.post(
    "https://api.zoom.us/v2/users/me/meetings",
    headers=headers,
    json={"topic": "My Meeting", "type": 2, "start_time": "2026-05-23T15:00:00Z", "duration": 60},
)
print(resp.json())

# ✅ GOOD — Server-to-Server OAuth, env-based config, typed parameters, error handling
import logging

logger = logging.getLogger(__name__)

# Initialize from environment variables
# Requires: ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, ZOOM_CLIENT_SECRET
zoom_client = ZoomApiClient.init_from_env()

def create_scheduled_meeting(
    topic: str,
    start_time: str,
    duration_minutes: int,
    settings: dict | None = None,
    password: str | None = None,
) -> dict:
    """Create a scheduled Zoom meeting and return meeting details."""
    meeting_data: dict = {
        "topic": topic,
        "type": 2,  # 1=instant, 2=scheduled, 3=recurring, 8=webinar
        "start_time": start_time,  # ISO 8601: "2026-05-23T15:00:00Z"
        "duration": duration_minutes,
        "timezone": "UTC",
        "settings": settings or {
            "host_video": True,
            "participant_video": True,
            "join_before_host": False,
            "mute_upon_entry": True,
            "approval_type": 0,  # 0=auto approve, 1=manual, 2=no registration
            "audio": "voip",
            "auto_recording": "none",
        },
    }
    if password:
        meeting_data["password"] = password

    try:
        result = zoom_client.meetings.create_meeting(meeting_data)
        meeting = result.json() if hasattr(result, "json") else result

        logger.info("Meeting created", extra={"id": meeting.get("id"), "topic": topic, "join_url": meeting.get("join_url")})
        return {
            "id": meeting.get("id"),
            "join_url": meeting.get("join_url"),
            "start_url": meeting.get("start_url"),
            "password": meeting.get("password"),
            "start_time": meeting.get("start_time"),
        }
    except requests.exceptions.HTTPError as exc:
        status = exc.response.status_code if exc.response else 0
        body = exc.response.json() if exc.response and exc.response.content else {}
        logger.error("Zoom meeting creation failed", extra={"status": status, "response": body})

        if status == 429:
            retry_after = exc.response.headers.get("Retry-After", "60")
            raise RuntimeError(f"Rate limited. Retry after {retry_after}s") from exc
        elif status == 401:
            raise RuntimeError("Zoom authentication failed — check credentials") from exc
        elif status == 404:
            raise RuntimeError("User not found") from exc
        raise

Pattern 2: Listing Meeting Recordings with Pagination

import os
import requests

# ❌ BAD — no pagination, only fetches first page (max 30 records)
result = zoom_client.meetings.list_meetings("me")
print(result.json())

# ✅ GOOD — full pagination, typed response, resource cleanup
def list_all_recordings(
    user_id: str = "me",
    page_size: int = 300,
    from_date: str | None = None,
    to_date: str | None = None,
) -> list[dict]:
    """List all cloud recordings for a user, handling pagination."""
    all_recordings: list[dict] = []
    next_page_token: str | None = None

    while True:
        params: dict = {
            "user_id": user_id,
            "page_size": min(page_size, 300),
        }
        if next_page_token:
            params["next_page_token"] = next_page_token
        if from_date:
            params["from"] = from_date
        if to_date:
            params["to"] = to_date

        try:
            response = zoom_client.meetings.list_recordings(params)
            data = response.json() if hasattr(response, "json") else response

            meetings = data.get("meetings", [])
            all_recordings.extend(meetings)

            next_page_token = data.get("next_page_token")
            logger.info("Fetched recordings page", extra={"count": len(meetings), "total_so_far": len(all_recordings)})

            if not next_page_token:
                break
        except requests.exceptions.HTTPError as exc:
            logger.error("Failed to list recordings", extra={"status": exc.response.status_code if exc.response else 0})
            raise

    return all_recordings

Pattern 3: Managing Zoom Users

import os
import requests

# ❌ BAD — no input validation, no user action filtering, no pagination
result = zoom_client.users.get_user("someone@example.com")
print(result.json())

# ✅ GOOD — user lookup with validation, action options, error handling
from typing import Literal

UserAction = Literal["activate", "deactivate", "suspend", "unsuspend"]

def get_or_create_user(email: str, first_name: str, last_name: str) -> dict:
    """Look up a Zoom user or create them if they do not exist."""
    try:
        result = zoom_client.users.get_user(email)
        user = result.json() if hasattr(result, "json") else result
        logger.info("User found", extra={"email": email, "id": user.get("id")})
        return {
            "id": user.get("id"),
            "email": user.get("email"),
            "first_name": user.get("first_name"),
            "last_name": user.get("last_name"),
            "status": user.get("status"),
            "created": user.get("created_at"),
        }
    except requests.exceptions.HTTPError as exc:
        if exc.response and exc.response.status_code == 404:
            # User does not exist — create them
            return create_user(email, first_name, last_name)
        raise

def create_user(email: str, first_name: str, last_name: str) -> dict:
    """Create a new Zoom user."""
    user_data = {
        "action": "create",  # "create", "autoCreate", "custCreate", "ssoCreate"
        "user_info": {
            "email": email,
            "first_name": first_name,
            "last_name": last_name,
            "type": 1,  # 1=basic (free), 2=pro, 3=corporate
        },
    }
    try:
        result = zoom_client.users.create_user(user_data)
        user = result.json() if hasattr(result, "json") else result
        logger.info("User created", extra={"email": email, "id": user.get("id")})
        return user
    except requests.exceptions.HTTPError as exc:
        body = exc.response.json() if exc.response and exc.response.content else {}
        logger.error("User creation failed", extra={"email": email, "response": body})
        raise

def update_user_status(email: str, action: UserAction) -> bool:
    """Update a Zoom users status (suspend/unsuspend)."""
    try:
        zoom_client.users.update_user(email, {"action": action})
        logger.info("User status updated", extra={"email": email, "action": action})
        return True
    except requests.exceptions.HTTPError as exc:
        logger.error("Status update failed", extra={"email": email, "action": action, "status": exc.response.status_code if exc.response else 0})
        return False

Constraints

MUST DO

  • Use Server-to-Server OAuth (account_id + client_id + client_secret) for authentication — Zoom deprecated JWT tokens in September 2023
  • Store credentials in environment variables: ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, ZOOM_CLIENT_SECRET — never hardcode them
  • Use ISO 8601 datetime format (2026-05-23T15:00:00Z) for all start_time parameters
  • Handle pagination on every list endpoint — Zoom returns next_page_token for responses exceeding page_size (default 30, max 300)
  • Implement exponential backoff for 429 rate-limit responses — Zoom allows 1 request/second for most endpoints, 10/s for batch operations
  • Validate meeting/webinar parameters before sending: topic max 200 chars, start_time must be in the future, duration minimum 10 minutes

MUST NOT DO

  • Use Static JWT tokens or hardcoded API Key/Secret — they are deprecated and will generate 401 responses
  • Assume list endpoints return all records in one call — always paginate with next_page_token
  • Hardcode Zoom user IDs — resolve them by email or use me for the authenticated user
  • Return raw Zoom API responses to end users — extract specific fields and structure the output
  • Ignore webhook event validation — verify the Authorization header on incoming webhooks to prevent unauthorized event injection

Output Template

When implementing Zoom API code, the output must follow this structure:

  1. Client Initialization — ZoomApiClient.init_from_env() reading ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, ZOOM_CLIENT_SECRET
  2. Resource Identification — User resolved by email or me; meeting/webinar ID validated before operations
  3. Parameter Construction — Dict with topic, start_time (ISO 8601), duration (minutes), type, and settings
  4. API Call — Method call wrapped in try/except for requests.exceptions.HTTPError
  5. Pagination — while next_page_token: loop for all list endpoints
  6. Error Handling — Status-specific logic: 400 (validation), 401 (auth), 404 (not found), 429 (rate limit)
  7. Response Structuring — Extracts id, join_url, start_url, password from responses

Zoom for meeting notification via SMS | | coding-slack-api | Team messaging — send Zoom meeting links and recording notifications to Slack channels | | coding-sendgrid-api | Transactional email — use for meeting confirmation and recording delivery emails |


Live References

Authoritative documentation links for this skill's domain. The model follows markdown links at load time to resolve external references and inline content.

Skills guardadas