iiuniversitet.ruЦентр обучения нейросетямОткрыть каталог

Приложения внутри Zoom (Apps SDK)

Справочник для разработчиков: как создать веб-приложение, которое работает внутри встреч, вебинаров и клиента Zoom, с авторизацией и свободной раскладкой видео.

СкиллAnthropic (партнёр: Zoom)ClaudeMITНужен терминалПроверка не требуетсяСлужебный: его вызывают другие скиллы
Что делает
Справочник для разработчиков: как создать веб-приложение, которое работает внутри встреч, вебинаров и клиента Zoom, с авторизацией и свободной раскладкой видео.
Когда брать
Когда нужно встроить своё веб-приложение в окно Zoom: боковую панель встречи, иммерсивную раскладку видео, наложение на камеру или совместную работу участников.
Когда не брать
Если нужно встроить саму встречу Zoom в свой сайт или приложение (для этого Meeting SDK) либо управлять встречами через REST API.
Пример запроса
Сделай приложение для боковой панели встречи Zoom, где участники вместе голосуют за идеи, и настрой авторизацию внутри клиента.
Нужно подключить
терминал, Node.js, приложение в Zoom Marketplace
Работает лучше с
ngrok или другой HTTPS-туннель для локальной разработки

Входит в плагин zoom-plugin. В Cowork и Claude Code можно поставить плагин целиком.

Как включить

  1. Скачайте архив и распакуйте его.
  2. Положите папку zoom-apps-sdk в ~/.claude/skills/.
  3. Откройте Claude Code и опишите задачу своими словами: Claude подхватит скилл по описанию.

Текст

---
name: zoom-apps-sdk
description: Справочный скилл по Zoom Apps SDK. Используй после маршрутизации в рабочий процесс приложений внутри клиента, когда создаёшь веб-приложения, которые работают внутри встреч, вебинаров, основного клиента Zoom или Zoom Phone.
user-invocable: false
triggers:
  - "zoom app"
  - "in-meeting app"
  - "app inside zoom"
  - "zoom client app"
  - "layers api"
  - "immersive mode"
  - "camera mode"
  - "collaborate mode"
  - "appssdk"
  - "in-client oauth"
  - "zoom mail"
  - "domain allowlist"
  - "domain whitelist"
  - "url whitelisting"
  - "blank panel"
  - "runningContext"
  - "zoomSdk"
---

Zoom Apps SDK

Справочный материал о веб-приложениях, которые работают внутри клиента Zoom. Сначала обращайся к choose-zoom-approach, а сюда переходи за сведениями о Layers API, режиме совместной работы (Collaborate Mode), OAuth внутри клиента и ограничениях среды выполнения.

Zoom Apps SDK

Создавай веб-приложения, которые работают внутри клиента Zoom: во встречах, вебинарах, основном клиенте и Zoom Phone.

Официальная документация: https://developers.zoom.us/docs/zoom-apps/ Справочник по SDK: https://appssdk.zoom.us/ Пакет NPM: https://www.npmjs.com/package/@zoom/appssdk

Быстрые ссылки

Впервые работаешь с Zoom Apps? Иди по этому пути:

  1. [Архитектура](concepts/architecture.md) - Схема «фронтенд и бэкенд», встроенный браузер, глубокие ссылки (deep linking)
  2. [Быстрый старт](examples/quick-start.md) - Готовое рабочее приложение на Express и SDK
  3. [Контексты запуска](concepts/running-contexts.md) - Где работает приложение (inMeeting, inMainClient и т. д.)
  4. [Zoom Apps и Meeting SDK](concepts/meeting-sdk-vs-zoom-apps.md) - Не смешивай типы приложений
  5. [OAuth внутри клиента](examples/in-client-oauth.md) - Бесшовная авторизация с PKCE
  6. [Справочник по API](references/apis.md) - Больше 100 методов SDK
  7. Сводный указатель - см. раздел ниже в этом файле
  8. [Пятиминутный RUNBOOK](RUNBOOK.md) - Предварительные проверки перед глубокой отладкой

Справочники:

  • [Справочник по API](references/apis.md) - Все методы SDK по категориям
  • [Справочник по событиям](references/events.md) - Все обработчики событий SDK
  • [Layers API](references/layers-api.md) - Отрисовка в иммерсивном режиме и в режиме камеры
  • [Справочник по OAuth](references/oauth.md) - Потоки OAuth для Zoom Apps
  • [Zoom Mail](references/zmail-sdk.md) - Интеграция с почтовым плагином

Возникли проблемы?

  • Приложение не загружается в Zoom → проверь [список разрешённых доменов](#url-whitelisting-required) ниже
  • Ошибки SDK → [Частые проблемы](troubleshooting/common-issues.md)
  • Настройка локальной разработки → [Руководство по отладке](troubleshooting/debugging.md)
  • Переход на новую версию → [Руководство по миграции](troubleshooting/migration.md)
  • Ответы на вопросы с форума → [Главные вопросы форума](troubleshooting/forum-top-questions.md)

Создаёшь иммерсивные сценарии?

  • [Иммерсивный режим Layers](examples/layers-immersive.md) - Свои раскладки видео
  • [Режим камеры](examples/layers-camera.md) - Наложения на виртуальной камере

Нужна помощь с OAuth? Схемы аутентификации смотри в скилле [zoom-oauth](../oauth/SKILL.md).

Обзор SDK

Zoom Apps SDK (@zoom/appssdk) даёт JavaScript API для веб-приложений, работающих во встроенном браузере Zoom:

  • API контекста - Получение сведений о встрече, пользователе и участниках
  • Действия во встрече - Показ приложения, приглашение участников, открытие ссылок
  • Авторизация - OAuth внутри клиента с PKCE (без перенаправления в браузер)
  • Layers API - Иммерсивные раскладки видео и наложения в режиме камеры
  • Режим совместной работы (Collaborate Mode) - Общее состояние приложения у всех участников
  • Связь между приложениями - Передача сообщений между экземплярами приложения (основной клиент <-> встреча)
  • Управление медиа - Виртуальные фоны, список камер, управление записью
  • Управление интерфейсом - Разворачивание приложения, уведомления, всплывающее окно
  • События - Реакция на состояние встречи, участников, демонстрацию экрана и не только

Предварительные требования

  • Приложение Zoom, настроенное как тип «Zoom App» в Marketplace
  • Учётные данные OAuth (Client ID и Secret) с правами Zoom Apps
  • Веб-приложение (рекомендуется Node.js и Express)
  • Твой домен внесён в список разрешённых доменов в Marketplace
  • ngrok или HTTPS-туннель для локальной разработки
  • Node.js 18+ (для серверной части)

Быстрый старт

Вариант A: NPM (рекомендуется для фреймворков)

npm install @zoom/appssdk
import zoomSdk from '@zoom/appssdk';

async function init() {
  try {
    const configResponse = await zoomSdk.config({
      capabilities: [
        'shareApp',
        'getMeetingContext',
        'getUserContext',
        'openUrl'
      ],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
    // 'inMeeting' | 'inMainClient' | 'inWebinar' | 'inImmersive' | ...

    const context = await zoomSdk.getMeetingContext();
    console.log('Meeting ID:', context.meetingID);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}

Вариант B: CDN (чистый JS)

<script src="https://appssdk.zoom.us/sdk.js"></script>

<script>
// CRITICAL: Do NOT declare "let zoomSdk" - the SDK defines window.zoomSdk globally
// Using "let zoomSdk = ..." causes: SyntaxError: redeclaration of non-configurable global property
let sdk = window.zoomSdk;  // Use a different variable name

async function init() {
  try {
    const configResponse = await sdk.config({
      capabilities: ['shareApp', 'getMeetingContext', 'getUserContext'],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}

function showDemoMode() {
  document.body.innerHTML = '<h1>Preview Mode</h1><p>Open this app inside Zoom to use.</p>';
}

document.addEventListener('DOMContentLoaded', () => {
  init();
  setTimeout(() => { if (!sdk) showDemoMode(); }, 3000);
});
</script>

Критично: конфликт глобальной переменной

Скрипт с CDN объявляет window.zoomSdk глобально. Не объявляй её заново:

// WRONG - causes SyntaxError in Zoom's embedded browser
let zoomSdk = null;
zoomSdk = window.zoomSdk;

// CORRECT - use different variable name
let sdk = window.zoomSdk;

// ALSO CORRECT - NPM import (no conflict)
import zoomSdk from '@zoom/appssdk';

Это касается только подключения через CDN. Импорт из NPM создаёт переменную в области видимости модуля, конфликта нет.

Просмотр в браузере / демонстрационный режим

SDK работает только внутри клиента Zoom. При открытии в обычном браузере:

  • window.zoomSdk существует, но sdk.config() выдаёт ошибку
  • Всегда используй try/catch с запасным интерфейсом
  • Добавь тайм-аут (3 секунды) на случай зависания SDK

URL в списке разрешённых (обязательно)

Приложение НЕ загрузится в Zoom, если домен не внесён в список разрешённых.

  1. Открой Zoom Marketplace
  2. Открой своё приложение -> вкладка Feature
  3. В разделе Zoom App найди Add Allow List
  4. Добавь свой домен (например, yourdomain.com для рабочей версии, xxxxx.ngrok.io для разработки)

Без этого клиент Zoom покажет пустую панель без сообщения об ошибке.

Права OAuth (обязательно)

Для функций нужны соответствующие права OAuth, включённые в Marketplace:

ФункцияНеобходимое право
getMeetingContextzoomapp:inmeeting
getUserContextzoomapp:inmeeting
shareAppzoomapp:inmeeting
openUrlzoomapp:inmeeting
sendAppInvitationzoomapp:inmeeting
runRenderingContextzoomapp:inmeeting
authorizezoomapp:inmeeting
getMeetingParticipantszoomapp:inmeeting

Чтобы добавить права: Marketplace -> твоё приложение -> вкладка Scopes -> добавь нужные права.

Нет нужных прав — функция молча не работает или выдаёт ошибку. Если добавить новые права, пользователям придётся пройти авторизацию заново.

Контексты запуска

Приложение работает в разных частях Zoom. Где именно, сообщает configResponse.runningContext:

КонтекстОбластьОписание
inMeetingБоковая панель встречиСамый частый. Доступны все API встречи
inMainClientПанель основного клиентаВкладка «Главная». API контекста встречи недоступны
inWebinarБоковая панель вебинараВедущий и панелисты. API встреч и вебинаров
inImmersiveLayers APIСвоя отрисовка на весь экран
inCameraРежим камерыНаложение на виртуальной камере
inCollaborateРежим совместной работыКонтекст общего состояния
inPhoneZoom PhoneПриложение для телефонного звонка
inChatTeam ChatБоковая панель чата

Поведение и API для каждого контекста описаны в [Контекстах запуска](concepts/running-contexts.md).

Шаблон инициализации SDK

Любое приложение Zoom начинается с config():

import zoomSdk from '@zoom/appssdk';

const configResponse = await zoomSdk.config({
  capabilities: [
    // List ALL APIs you will use
    'getMeetingContext',
    'getUserContext',
    'shareApp',
    'openUrl',
    'authorize',
    'onAuthorized'
  ],
  version: '0.16'
});

// configResponse contains:
// {
//   runningContext: 'inMeeting',
//   clientVersion: '5.x.x',
//   unsupportedApis: []  // APIs not supported in this client version
// }

Правила:

  1. config() ОБЯЗАТЕЛЬНО вызывать до любого другого метода SDK
  2. Доступны только функции (capabilities), перечисленные в config()
  3. Функции должны соответствовать правам OAuth в Marketplace
  4. Проверяй unsupportedApis, чтобы приложение корректно упрощало работу

OAuth внутри клиента (кратко)

Лучший вариант для пользователя при авторизации: без перенаправления в браузер:

// 1. Get code challenge from your backend
const { codeChallenge, state } = await fetch('/api/auth/challenge').then(r => r.json());

// 2. Trigger in-client authorization
await zoomSdk.authorize({ codeChallenge, state });

// 3. Listen for authorization result
zoomSdk.addEventListener('onAuthorized', async (event) => {
  const { code, state } = event;
  // 4. Send code to backend for token exchange
  await fetch('/api/auth/token', {
    method: 'POST',
    body: JSON.stringify({ code, state })
  });
});

Полная реализация — в [руководстве по OAuth внутри клиента](examples/in-client-oauth.md).

Layers API (кратко)

Создавай иммерсивные раскладки видео и наложения для камеры:

// Start immersive mode - replaces gallery view
await zoomSdk.runRenderingContext({ view: 'immersive' });

// Position participant video feeds
await zoomSdk.drawParticipant({
  participantUUID: 'user-uuid',
  x: 0, y: 0, width: 640, height: 480, zIndex: 1
});

// Add overlay images
await zoomSdk.drawImage({
  imageData: canvas.toDataURL(),
  x: 0, y: 0, width: 1280, height: 720, zIndex: 0
});

// Exit immersive mode
await zoomSdk.closeRenderingContext();

См. [Layers Immersive](examples/layers-immersive.md) и [Режим камеры](examples/layers-camera.md).

Переменные окружения

ПеременнаяОписаниеГде найти
ZOOM_APP_CLIENT_IDClient ID приложенияMarketplace -> App -> App Credentials
ZOOM_APP_CLIENT_SECRETClient Secret приложенияMarketplace -> App -> App Credentials
ZOOM_APP_REDIRECT_URIURL перенаправления OAuthURL твоего сервера + /auth
SESSION_SECRETСекрет для подписи cookieСгенерируй случайную строку
ZOOM_HOSTURL хоста Zoomhttps://zoom.us (или https://zoomgov.com)

Частые API

APIОписание
config()Инициализирует SDK, запрашивает функции
getMeetingContext()Получает ID встречи, тему, статус
getUserContext()Получает имя пользователя, роль, ID участника
getRunningContext()Получает текущий контекст запуска
getMeetingParticipants()Список участников
shareApp()Показывает экран приложения участникам
openUrl({ url })Открывает ссылку во внешнем браузере
sendAppInvitation()Приглашает пользователей открыть твоё приложение
authorize()Запускает OAuth внутри клиента
connect()Подключается к другим экземплярам приложения
postMessage()Отправляет сообщение подключённым экземплярам
runRenderingContext()Запускает Layers API (иммерсивный режим или режим камеры)
expandApp({ action })Разворачивает или сворачивает панель приложения
showNotification()Показывает уведомление в Zoom

Полная библиотека документации

Основные концепции

  • [Архитектура](concepts/architecture.md) - Схема «фронтенд и бэкенд», встроенный браузер, глубокие ссылки, X-Zoom-App-Context
  • [Контексты запуска](concepts/running-contexts.md) - Все контексты, API для каждого контекста, связь между несколькими экземплярами
  • [Безопасность](concepts/security.md) - Заголовки OWASP, CSP, безопасность cookie, PKCE, хранение токенов

Готовые примеры

  • [Быстрый старт](examples/quick-start.md) - Hello World: приложение на Express и SDK
  • [OAuth внутри клиента](examples/in-client-oauth.md) - Поток авторизации с PKCE
  • [Layers Immersive](examples/layers-immersive.md) - Свои раскладки видео
  • [Режим камеры](examples/layers-camera.md) - Наложения на виртуальной камере
  • [Режим совместной работы](examples/collaborate-mode.md) - Общее состояние у участников
  • [Гостевой режим](examples/guest-mode.md) - Состояния: без аутентификации, аутентифицирован, авторизован
  • [Комнаты обсуждения](examples/breakout-rooms.md) - Определение комнат и состояние между комнатами
  • [Связь между приложениями](examples/app-communication.md) - connect и postMessage между экземплярами

Устранение неполадок

  • [Частые проблемы](troubleshooting/common-issues.md) - Быстрая диагностика и коды ошибок
  • [Отладка](troubleshooting/debugging.md) - Локальная разработка, ngrok, просмотр в браузере
  • [Миграция](troubleshooting/migration.md) - Заметки о переходе на новые версии SDK

Справочники

  • [Справочник по API](references/apis.md) - Все 100+ методов SDK
  • [Справочник по событиям](references/events.md) - Все обработчики событий SDK
  • [Справочник по Layers API](references/layers-api.md) - Методы рисования и отрисовки
  • [Справочник по OAuth](references/oauth.md) - Потоки OAuth для Zoom Apps
  • [Zoom Mail](references/zmail-sdk.md) - Интеграция с почтовым плагином

Примеры репозиториев

Официальные (от Zoom)

РепозиторийТипОбновлёнСтатусВерсия SDK
zoomapps-sample-jsHello World (чистый JS)дек. 2025Активен^0.16.26
zoomapps-advancedsample-reactПродвинутый (React + Redis)окт. 2025Активен0.16.0
zoomapps-customlayout-jsLayers APIнояб. 2023Устарел^0.16.8
zoomapps-texteditor-vuejsСовместная работа (Vue + Y.js)окт. 2023Устарел^0.16.7
zoomapps-serverless-vuejsБессерверный (Firebase)авг. 2024Устарел^0.16.21
zoomapps-cameramode-vuejsРежим камеры---
zoomapps-workshop-sampleВоркшоп---

Рекомендуется для новых проектов: используй @zoom/appssdk версии ^0.16.26.

Сообщество

ТипРепозиторийОписание
Библиотекаharvard-edtech/zacclZoom App Complete Connection Library

Полный список: см. [general/references/community-repos.md](../general/references/community-repos.md)

План обучения

  1. Начало: zoomapps-sample-js - Самый простой и самый свежий
  2. Продвинутый уровень: zoomapps-advancedsample-react - Всесторонний (OAuth внутри клиента, гостевой режим, совместная работа)
  3. Специализированные: выбирай по нужной функции (Layers, бессерверный вариант, режим камеры)

Критические ловушки (из реальной разработки)

1. Конфликт глобальной переменной

Скрипт с CDN объявляет window.zoomSdk. Если в твоём коде есть let zoomSdk, возникает SyntaxError: redeclaration of non-configurable global property. Используй let sdk = window.zoomSdk или импорт из NPM.

2. Список разрешённых доменов

URL твоего приложения должен быть в списке разрешённых доменов в Marketplace. Без этого Zoom показывает пустую панель без ошибки. Добавь также appssdk.zoom.us и все домены CDN, которые используешь.

3. Функции нужно перечислять

Доступны только API, перечисленные в config({ capabilities: [...] }). Вызов неперечисленного API выдаёт ошибку. Это верно и для обработчиков событий.

4. SDK работает только внутри Zoom

zoomSdk.config() выдаёт ошибку вне клиента Zoom. Всегда оборачивай в try/catch с запасным вариантом для браузера:

try { await zoomSdk.config({...}); } catch { showBrowserPreview(); }

5. URL ngrok меняется

Бесплатные URL ngrok меняются при перезапуске. В Marketplace нужно обновить 4 места: Home URL, Redirect URL, OAuth Allow List, Domain Allow List. Подумай о платном тарифе ngrok со стабильным поддоменом.

6. OAuth внутри клиента и веб-OAuth

Используй zoomSdk.authorize() (внутри клиента) для лучшего удобства: без перенаправления в браузер. К перенаправлению через веб возвращайся только при первой установке из Marketplace.

7. Состояние гонки CEF в режиме камеры

Режим камеры использует CEF, которому нужно время на инициализацию. drawImage и drawWebView могут не сработать, если вызвать их слишком рано. Сделай повторные попытки с экспоненциальной задержкой.

8. Настройка cookie

Встроенному браузеру Zoom нужны cookie с SameSite=None и Secure=true. Без этого сессии молча ломаются.

9. Проверка параметра state

Всегда проверяй параметр OAuth state, чтобы защититься от CSRF-атак. Генерируй криптографически случайное значение, сохраняй его и сверяй при обратном вызове.

Ресурсы


Нужна помощь? Начни с раздела «Сводный указатель» ниже: там вся навигация.


Сводный указатель

_Этот раздел перенесён из SKILL.md._

Путь быстрого старта

Если ты впервые работаешь с Zoom Apps, иди в таком порядке:

  1. Сначала выполни предварительные проверки -> [RUNBOOK.md](RUNBOOK.md)
  1. Прочитай об архитектуре -> [concepts/architecture.md](concepts/architecture.md)
  2. Схема «фронтенд и бэкенд», встроенный браузер, глубокие ссылки
  3. Пойми, как Zoom загружает твоё приложение и обменивается с ним данными
  1. Создай первое приложение -> [examples/quick-start.md](examples/quick-start.md)
  2. Готовый Hello World на Express и SDK
  3. Настройка ngrok для локальной разработки
  1. Разберись с контекстами запуска -> [concepts/running-contexts.md](concepts/running-contexts.md)
  2. Где работает приложение (inMeeting, inMainClient, inWebinar и т. д.)
  3. API и ограничения для каждого контекста
  1. Реализуй OAuth -> [examples/in-client-oauth.md](examples/in-client-oauth.md)
  2. OAuth внутри клиента с PKCE (лучший вариант для пользователя)
  3. Обмен и хранение токенов
  1. Добавь функции -> [references/apis.md](references/apis.md)
  2. Больше 100 методов SDK по категориям
  3. Примеры кода для каждого
  1. Устраняй неполадки -> [troubleshooting/common-issues.md](troubleshooting/common-issues.md)
  2. Быстрая диагностика частых проблем

Структура документации

zoom-apps-sdk/
├── SKILL.md                           # Обзор скилла (главный файл)
├── SKILL.md                           # Этот файл — путеводитель
│
├── concepts/                          # Основные архитектурные решения
│   ├── architecture.md               # Фронтенд/бэкенд, встроенный браузер, поток OAuth
│   ├── running-contexts.md           # Где работает приложение и API для каждого контекста
│   └── security.md                   # Заголовки OWASP, CSP, уровни доступа к данным
│
├── examples/                          # Готовый рабочий код
│   ├── quick-start.md                # Hello World: минимальное приложение на Express и SDK
│   ├── in-client-oauth.md            # OAuth внутри клиента с PKCE
│   ├── layers-immersive.md           # Layers API: иммерсивный режим (свои раскладки)
│   ├── layers-camera.md              # Layers API: режим камеры (виртуальная камера)
│   ├── collaborate-mode.md           # Режим совместной работы (общее состояние)
│   ├── guest-mode.md                 # Гостевой режим (от неаутентифицированного к авторизованному)
│   ├── breakout-rooms.md             # Интеграция с комнатами обсуждения
│   └── app-communication.md          # connect и postMessage между экземплярами
│
├── troubleshooting/                   # Руководства по решению проблем
│   ├── common-issues.md              # Быстрая диагностика, коды ошибок
│   ├── debugging.md                  # Локальная разработка, ngrok, просмотр в браузере
│   └── migration.md                  # Заметки о переходе на новые версии SDK
│
└── references/                        # Справочная документация
    ├── apis.md                        # Полный справочник по API (100+ методов)
    ├── events.md                      # Все события SDK
    ├── layers-api.md                  # Подробный справочник по Layers API
    ├── oauth.md                       # Потоки OAuth для Zoom Apps
    └── zmail-sdk.md                   # Интеграция с Zoom Mail

По сценариям

Хочу создать простое приложение Zoom

  1. [Архитектура](concepts/architecture.md) - Пойми схему
  2. [Быстрый старт](examples/quick-start.md) - Создай Hello World
  3. [OAuth внутри клиента](examples/in-client-oauth.md) - Добавь авторизацию
  4. [Безопасность](concepts/security.md) - Обязательные заголовки

Хочу иммерсивные раскладки видео (Layers API)

  1. [Layers Immersive](examples/layers-immersive.md) - Свои позиции видео
  2. [Справочник по Layers API](references/layers-api.md) - Все методы рисования
  3. [Связь между приложениями](examples/app-communication.md) - Синхронизация раскладки между участниками

Хочу наложение на виртуальной камере

  1. [Режим камеры](examples/layers-camera.md) - Отрисовка в режиме камеры
  2. [Справочник по Layers API](references/layers-api.md) - Методы рисования

Хочу совместную работу в реальном времени

  1. [Режим совместной работы](examples/collaborate-mode.md) - API общего состояния
  2. [Связь между приложениями](examples/app-communication.md) - Обмен сообщениями между экземплярами

Хочу гостевой или анонимный доступ

  1. [Гостевой режим](examples/guest-mode.md) - Три состояния авторизации
  2. [OAuth внутри клиента](examples/in-client-oauth.md) - Поток promptAuthorize

Хочу поддержку комнат обсуждения

  1. [Комнаты обсуждения](examples/breakout-rooms.md) - Определение комнат и синхронизация состояния

Хочу синхронизацию между основным клиентом и встречей

  1. [Связь между приложениями](examples/app-communication.md) - connect и postMessage
  2. [Контексты запуска](concepts/running-contexts.md) - Поведение при нескольких экземплярах

Хочу бессерверное развёртывание

  1. [Быстрый старт](examples/quick-start.md) - Сначала пойми базовую схему
  2. Пример: zoomapps-serverless-vuejs - Схема на Firebase

Хочу добавить интеграцию с Zoom Mail

  1. [Справочник по Zoom Mail](references/zmail-sdk.md) - REST API и почтовые плагины

У меня ошибки

  1. [Частые проблемы](troubleshooting/common-issues.md) - Таблица быстрой диагностики
  2. [Отладка](troubleshooting/debugging.md) - Локальная разработка, DevTools
  3. [Миграция](troubleshooting/migration.md) - Совместимость версий

Самые важные документы

1. Архитектура (ОСНОВА)

[concepts/architecture.md](concepts/architecture.md)

Пойми, как устроены Zoom Apps: фронтенд во встроенном браузере, бэкенд для OAuth и API, SDK как мост. Без этого остальное не имеет смысла.

2. Быстрый старт (ПЕРВОЕ ПРИЛОЖЕНИЕ)

[examples/quick-start.md](examples/quick-start.md)

Готовый рабочий код. Запусти что-нибудь рабочее, прежде чем переходить к продвинутым функциям.

3. Частые проблемы (САМЫЕ РАСПРОСТРАНЁННЫЕ СБОИ)

[troubleshooting/common-issues.md](troubleshooting/common-issues.md)

90% проблем с Zoom Apps — это список разрешённых доменов, конфликт глобальной переменной или не указанные функции.


Ключевые выводы

Критические находки:

  1. Конфликт глобальной переменной — ловушка №1
  2. Скрипт с CDN объявляет window.zoomSdk глобально
  3. let zoomSdk = ... вызывает SyntaxError в браузере Zoom
  4. Используй let sdk = window.zoomSdk или импорт из NPM
  1. Список разрешённых доменов обойти нельзя
  2. Если домен не внесён, приложение показывает пустую панель без единой ошибки
  3. Нужно указать твой домен, appssdk.zoom.us и все домены CDN
  4. URL ngrok меняются при перезапуске, поэтому Marketplace придётся обновлять каждый раз
  1. config() управляет всем
  2. Его нужно вызвать первым, в нём нужно перечислить все функции
  3. Неперечисленные функции вызывают ошибки
  4. Проверяй unsupportedApis на совместимость с версией клиента
  1. OAuth внутри клиента удобнее веб-OAuth
  2. authorize() оставляет пользователя в Zoom (без перенаправления в браузер)
  3. Перенаправление через веб нужно только при первой установке из Marketplace
  4. Всегда реализуй PKCE (code_verifier и code_challenge)
  1. Два экземпляра приложения могут работать одновременно
  2. Экземпляр в основном клиенте и экземпляр во встрече
  3. Для синхронизации между ними используй connect() и postMessage()
  4. Предварительная настройка — в основном клиенте, использование — во встрече
  1. У режима камеры есть особенности CEF
  2. Инициализация CEF занимает время
  3. Вызовы отрисовки могут не сработать, если вызвать их слишком рано
  4. Делай повторные попытки с экспоненциальной задержкой
  1. Настройки cookie важны
  2. Нужны SameSite=None и Secure=true
  3. Без этого сессии молча ломаются во встроенном браузере

Краткая справка

«Приложение показывает пустую панель»

-> [Список разрешённых доменов](troubleshooting/common-issues.md) - добавь домен в Marketplace

«SyntaxError: redeclaration»

-> [Глобальная переменная](troubleshooting/common-issues.md) - используй let sdk = window.zoomSdk

«config() выдаёт ошибку»

-> [Просмотр в браузере](troubleshooting/debugging.md) - SDK работает только внутри Zoom

«Вызов API молча не срабатывает»

-> [Права OAuth](troubleshooting/common-issues.md) - добавь нужные права в Marketplace

«Как реализовать [функцию]?»

-> [Справочник по API](references/apis.md) - найди метод, проверь нужные функции

«Как проверить локально?»

-> [Руководство по отладке](troubleshooting/debugging.md) - ngrok и настройка Marketplace


Версия документа

Основано на @zoom/appssdk v0.16.x (последняя: 0.16.26+)


Удачной разработки!

Начни с [Архитектуры](concepts/architecture.md), чтобы понять схему, затем пройди [Быстрый старт](examples/quick-start.md) и создай первое приложение.

Перевод: iiuniversitet. Оригинал: https://github.com/anthropics/knowledge-work-plugins/tree/main/partner-built/zoom-plugin/skills/zoom-apps-sdk, лицензия MIT. Изменения: перевод на русский язык.

Оригинал на английском
---
name: zoom-apps-sdk
description: Reference skill for Zoom Apps SDK. Use after routing to an in-client app workflow when building web apps that run inside Zoom meetings, webinars, the main client, or Zoom Phone.
user-invocable: false
triggers:
  - "zoom app"
  - "in-meeting app"
  - "app inside zoom"
  - "zoom client app"
  - "layers api"
  - "immersive mode"
  - "camera mode"
  - "collaborate mode"
  - "appssdk"
  - "in-client oauth"
  - "zoom mail"
  - "domain allowlist"
  - "domain whitelist"
  - "url whitelisting"
  - "blank panel"
  - "runningContext"
  - "zoomSdk"
---

# Zoom Apps SDK

Background reference for web apps that run inside the Zoom client. Prefer `choose-zoom-approach` first, then route here for Layers API, Collaborate Mode, in-client OAuth, and runtime constraints.

# Zoom Apps SDK

Build web apps that run inside the Zoom client - meetings, webinars, main client, and Zoom Phone.

**Official Documentation**: https://developers.zoom.us/docs/zoom-apps/
**SDK Reference**: https://appssdk.zoom.us/
**NPM Package**: https://www.npmjs.com/package/@zoom/appssdk

## Quick Links

**New to Zoom Apps? Follow this path:**

1. **[Architecture](concepts/architecture.md)** - Frontend/backend pattern, embedded browser, deep linking
2. **[Quick Start](examples/quick-start.md)** - Complete working Express + SDK app
3. **[Running Contexts](concepts/running-contexts.md)** - Where your app runs (inMeeting, inMainClient, etc.)
4. **[Zoom Apps vs Meeting SDK](concepts/meeting-sdk-vs-zoom-apps.md)** - Stop mixing app types
4. **[In-Client OAuth](examples/in-client-oauth.md)** - Seamless authorization with PKCE
5. **[API Reference](references/apis.md)** - 100+ SDK methods
6. **Integrated Index** - see the section below in this file
7. **[5-Minute Runbook](RUNBOOK.md)** - Preflight checks before deep debugging

**Reference:**
- **[API Reference](references/apis.md)** - All SDK methods by category
- **[Events Reference](references/events.md)** - All SDK event listeners
- **[Layers API](references/layers-api.md)** - Immersive and camera mode rendering
- **[OAuth Reference](references/oauth.md)** - OAuth flows for Zoom Apps
- **[Zoom Mail](references/zmail-sdk.md)** - Mail plugin integration

**Having issues?**
- App won't load in Zoom → Check [Domain Allowlist](#url-whitelisting-required) below
- SDK errors → [Common Issues](troubleshooting/common-issues.md)
- Local dev setup → [Debugging Guide](troubleshooting/debugging.md)
- Version upgrade → [Migration Guide](troubleshooting/migration.md)
- Forum-derived FAQs → [Forum Top Questions](troubleshooting/forum-top-questions.md)

**Building immersive experiences?**
- [Layers Immersive Mode](examples/layers-immersive.md) - Custom video layouts
- [Camera Mode](examples/layers-camera.md) - Virtual camera overlays

> **Need help with OAuth?** See the **[zoom-oauth](../oauth/SKILL.md)** skill for authentication flows.

## SDK Overview

The Zoom Apps SDK (`@zoom/appssdk`) provides JavaScript APIs for web apps running in Zoom's embedded browser:

- **Context APIs** - Get meeting, user, and participant info
- **Meeting Actions** - Share app, invite participants, open URLs
- **Authorization** - In-Client OAuth with PKCE (no browser redirect)
- **Layers API** - Immersive video layouts and camera mode overlays
- **Collaborate Mode** - Shared app state across participants
- **App Communication** - Message passing between app instances (main client <-> meeting)
- **Media Controls** - Virtual backgrounds, camera listing, recording control
- **UI Controls** - Expand app, notifications, popout
- **Events** - React to meeting state, participants, sharing, and more

## Prerequisites

- Zoom app configured as **"Zoom App"** type in [Marketplace](https://marketplace.zoom.us/)
- OAuth credentials (Client ID + Secret) with Zoom Apps scopes
- Web application (Node.js + Express recommended)
- **Your domain whitelisted** in Marketplace domain allowlist
- ngrok or HTTPS tunnel for local development
- Node.js 18+ (for the backend server)

## Quick Start

### Option A: NPM (Recommended for frameworks)

```bash
npm install @zoom/appssdk
```

```javascript
import zoomSdk from '@zoom/appssdk';

async function init() {
  try {
    const configResponse = await zoomSdk.config({
      capabilities: [
        'shareApp',
        'getMeetingContext',
        'getUserContext',
        'openUrl'
      ],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
    // 'inMeeting' | 'inMainClient' | 'inWebinar' | 'inImmersive' | ...

    const context = await zoomSdk.getMeetingContext();
    console.log('Meeting ID:', context.meetingID);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}
```

### Option B: CDN (Vanilla JS)

```html
<script src="https://appssdk.zoom.us/sdk.js"></script>

<script>
// CRITICAL: Do NOT declare "let zoomSdk" - the SDK defines window.zoomSdk globally
// Using "let zoomSdk = ..." causes: SyntaxError: redeclaration of non-configurable global property
let sdk = window.zoomSdk;  // Use a different variable name

async function init() {
  try {
    const configResponse = await sdk.config({
      capabilities: ['shareApp', 'getMeetingContext', 'getUserContext'],
      version: '0.16'
    });

    console.log('Running context:', configResponse.runningContext);
  } catch (error) {
    console.error('Not running inside Zoom:', error.message);
    showDemoMode();
  }
}

function showDemoMode() {
  document.body.innerHTML = '<h1>Preview Mode</h1><p>Open this app inside Zoom to use.</p>';
}

document.addEventListener('DOMContentLoaded', () => {
  init();
  setTimeout(() => { if (!sdk) showDemoMode(); }, 3000);
});
</script>
```

## Critical: Global Variable Conflict

The CDN script defines `window.zoomSdk` globally. **Do NOT redeclare it:**

```javascript
// WRONG - causes SyntaxError in Zoom's embedded browser
let zoomSdk = null;
zoomSdk = window.zoomSdk;

// CORRECT - use different variable name
let sdk = window.zoomSdk;

// ALSO CORRECT - NPM import (no conflict)
import zoomSdk from '@zoom/appssdk';
```

This only applies to the CDN approach. The NPM import creates a module-scoped variable, no conflict.

## Browser Preview / Demo Mode

The SDK only functions inside the Zoom client. When accessed in a regular browser:
- `window.zoomSdk` exists but `sdk.config()` throws an error
- Always implement try/catch with fallback UI
- Add timeout (3 seconds) in case SDK hangs

## URL Whitelisting (Required)

**Your app will NOT load in Zoom unless the domain is whitelisted.**

1. Go to [Zoom Marketplace](https://marketplace.zoom.us/)
2. Open your app -> **Feature** tab
3. Under **Zoom App**, find **Add Allow List**
4. Add your domain (e.g., `yourdomain.com` for production, `xxxxx.ngrok.io` for dev)

Without this, the Zoom client shows a blank panel with no error message.

## OAuth Scopes (Required)

Capabilities require matching OAuth scopes enabled in Marketplace:

| Capability | Required Scope |
|------------|----------------|
| `getMeetingContext` | `zoomapp:inmeeting` |
| `getUserContext` | `zoomapp:inmeeting` |
| `shareApp` | `zoomapp:inmeeting` |
| `openUrl` | `zoomapp:inmeeting` |
| `sendAppInvitation` | `zoomapp:inmeeting` |
| `runRenderingContext` | `zoomapp:inmeeting` |
| `authorize` | `zoomapp:inmeeting` |
| `getMeetingParticipants` | `zoomapp:inmeeting` |

**To add scopes:** Marketplace -> Your App -> **Scopes** tab -> Add required scopes.

Missing scopes = capability fails silently or throws error. Users must re-authorize if you add new scopes.

## Running Contexts

Your app runs in different surfaces within Zoom. The `configResponse.runningContext` tells you where:

| Context | Surface | Description |
|---------|---------|-------------|
| `inMeeting` | Meeting sidebar | Most common. Full meeting APIs available |
| `inMainClient` | Main client panel | Home tab. No meeting context APIs |
| `inWebinar` | Webinar sidebar | Host/panelist. Meeting + webinar APIs |
| `inImmersive` | Layers API | Full-screen custom rendering |
| `inCamera` | Camera mode | Virtual camera overlay |
| `inCollaborate` | Collaborate mode | Shared state context |
| `inPhone` | Zoom Phone | Phone call app |
| `inChat` | Team Chat | Chat sidebar |

See **[Running Contexts](concepts/running-contexts.md)** for context-specific behavior and APIs.

## SDK Initialization Pattern

Every Zoom App starts with `config()`:

```javascript
import zoomSdk from '@zoom/appssdk';

const configResponse = await zoomSdk.config({
  capabilities: [
    // List ALL APIs you will use
    'getMeetingContext',
    'getUserContext',
    'shareApp',
    'openUrl',
    'authorize',
    'onAuthorized'
  ],
  version: '0.16'
});

// configResponse contains:
// {
//   runningContext: 'inMeeting',
//   clientVersion: '5.x.x',
//   unsupportedApis: []  // APIs not supported in this client version
// }
```

**Rules:**
1. `config()` MUST be called before any other SDK method
2. Only capabilities listed in `config()` are available
3. Capabilities must match OAuth scopes in Marketplace
4. Check `unsupportedApis` for graceful degradation

## In-Client OAuth (Summary)

Best UX for authorization - no browser redirect:

```javascript
// 1. Get code challenge from your backend
const { codeChallenge, state } = await fetch('/api/auth/challenge').then(r => r.json());

// 2. Trigger in-client authorization
await zoomSdk.authorize({ codeChallenge, state });

// 3. Listen for authorization result
zoomSdk.addEventListener('onAuthorized', async (event) => {
  const { code, state } = event;
  // 4. Send code to backend for token exchange
  await fetch('/api/auth/token', {
    method: 'POST',
    body: JSON.stringify({ code, state })
  });
});
```

See **[In-Client OAuth Guide](examples/in-client-oauth.md)** for complete implementation.

## Layers API (Summary)

Build immersive video layouts and camera overlays:

```javascript
// Start immersive mode - replaces gallery view
await zoomSdk.runRenderingContext({ view: 'immersive' });

// Position participant video feeds
await zoomSdk.drawParticipant({
  participantUUID: 'user-uuid',
  x: 0, y: 0, width: 640, height: 480, zIndex: 1
});

// Add overlay images
await zoomSdk.drawImage({
  imageData: canvas.toDataURL(),
  x: 0, y: 0, width: 1280, height: 720, zIndex: 0
});

// Exit immersive mode
await zoomSdk.closeRenderingContext();
```

See **[Layers Immersive](examples/layers-immersive.md)** and **[Camera Mode](examples/layers-camera.md)**.

## Environment Variables

| Variable | Description | Where to Find |
|----------|-------------|---------------|
| `ZOOM_APP_CLIENT_ID` | App client ID | Marketplace -> App -> App Credentials |
| `ZOOM_APP_CLIENT_SECRET` | App client secret | Marketplace -> App -> App Credentials |
| `ZOOM_APP_REDIRECT_URI` | OAuth redirect URL | Your server URL + `/auth` |
| `SESSION_SECRET` | Cookie signing secret | Generate random string |
| `ZOOM_HOST` | Zoom host URL | `https://zoom.us` (or `https://zoomgov.com`) |

## Common APIs

| API | Description |
|-----|-------------|
| `config()` | Initialize SDK, request capabilities |
| `getMeetingContext()` | Get meeting ID, topic, status |
| `getUserContext()` | Get user name, role, participant ID |
| `getRunningContext()` | Get current running context |
| `getMeetingParticipants()` | List participants |
| `shareApp()` | Share app screen with participants |
| `openUrl({ url })` | Open URL in external browser |
| `sendAppInvitation()` | Invite users to open your app |
| `authorize()` | Trigger In-Client OAuth |
| `connect()` | Connect to other app instances |
| `postMessage()` | Send message to connected instances |
| `runRenderingContext()` | Start Layers API (immersive/camera) |
| `expandApp({ action })` | Expand/collapse app panel |
| `showNotification()` | Show notification in Zoom |

## Complete Documentation Library

### Core Concepts
- **[Architecture](concepts/architecture.md)** - Frontend/backend pattern, embedded browser, deep linking, X-Zoom-App-Context
- **[Running Contexts](concepts/running-contexts.md)** - All contexts, context-specific APIs, multi-instance communication
- **[Security](concepts/security.md)** - OWASP headers, CSP, cookie security, PKCE, token storage

### Complete Examples
- **[Quick Start](examples/quick-start.md)** - Hello World Express + SDK app
- **[In-Client OAuth](examples/in-client-oauth.md)** - PKCE authorization flow
- **[Layers Immersive](examples/layers-immersive.md)** - Custom video layouts
- **[Camera Mode](examples/layers-camera.md)** - Virtual camera overlays
- **[Collaborate Mode](examples/collaborate-mode.md)** - Shared state across participants
- **[Guest Mode](examples/guest-mode.md)** - Unauthenticated/authenticated/authorized states
- **[Breakout Rooms](examples/breakout-rooms.md)** - Room detection and cross-room state
- **[App Communication](examples/app-communication.md)** - connect + postMessage between instances

### Troubleshooting
- **[Common Issues](troubleshooting/common-issues.md)** - Quick diagnostics and error codes
- **[Debugging](troubleshooting/debugging.md)** - Local dev, ngrok, browser preview
- **[Migration](troubleshooting/migration.md)** - SDK version upgrade notes

### References
- **[API Reference](references/apis.md)** - All 100+ SDK methods
- **[Events Reference](references/events.md)** - All SDK event listeners
- **[Layers API Reference](references/layers-api.md)** - Drawing and rendering methods
- **[OAuth Reference](references/oauth.md)** - OAuth flows for Zoom Apps
- **[Zoom Mail](references/zmail-sdk.md)** - Mail plugin integration

## Sample Repositories

### Official (by Zoom)

| Repository | Type | Last Updated | Status | SDK Version |
|-----------|------|-------------|--------|-------------|
| [zoomapps-sample-js](https://github.com/zoom/zoomapps-sample-js) | Hello World (Vanilla JS) | Dec 2025 | Active | ^0.16.26 |
| [zoomapps-advancedsample-react](https://github.com/zoom/zoomapps-advancedsample-react) | Advanced (React + Redis) | Oct 2025 | Active | 0.16.0 |
| [zoomapps-customlayout-js](https://github.com/zoom/zoomapps-customlayout-js) | Layers API | Nov 2023 | Stale | ^0.16.8 |
| [zoomapps-texteditor-vuejs](https://github.com/zoom/zoomapps-texteditor-vuejs) | Collaborate (Vue + Y.js) | Oct 2023 | Stale | ^0.16.7 |
| [zoomapps-serverless-vuejs](https://github.com/zoom/zoomapps-serverless-vuejs) | Serverless (Firebase) | Aug 2024 | Stale | ^0.16.21 |
| [zoomapps-cameramode-vuejs](https://github.com/zoom/zoomapps-cameramode-vuejs) | Camera Mode | - | - | - |
| [zoomapps-workshop-sample](https://github.com/zoom/zoomapps-workshop-sample) | Workshop | - | - | - |

**Recommended for new projects:** Use `@zoom/appssdk` version `^0.16.26`.

### Community

| Type | Repository | Description |
|------|------------|-------------|
| Library | [harvard-edtech/zaccl](https://github.com/harvard-edtech/zaccl) | Zoom App Complete Connection Library |

**Full list**: See [general/references/community-repos.md](../general/references/community-repos.md)

### Learning Path

1. **Start**: `zoomapps-sample-js` - Simplest, most up-to-date
2. **Advanced**: `zoomapps-advancedsample-react` - Comprehensive (In-Client OAuth, Guest Mode, Collaborate)
3. **Specialized**: Pick based on feature (Layers, Serverless, Camera Mode)

## Critical Gotchas (From Real Development)

### 1. Global Variable Conflict
The CDN script defines `window.zoomSdk`. Declaring `let zoomSdk` in your code causes `SyntaxError: redeclaration of non-configurable global property`. Use `let sdk = window.zoomSdk` or the NPM import.

### 2. Domain Allowlist
Your app URL **must** be in the Marketplace domain allowlist. Without it, Zoom shows a blank panel with no error. Also add `appssdk.zoom.us` and any CDN domains you use.

### 3. Capabilities Must Be Listed
Only APIs listed in `config({ capabilities: [...] })` are available. Calling an unlisted API throws an error. This is also true for event listeners.

### 4. SDK Only Works Inside Zoom
`zoomSdk.config()` throws outside the Zoom client. Always wrap in try/catch with browser fallback:
```javascript
try { await zoomSdk.config({...}); } catch { showBrowserPreview(); }
```

### 5. ngrok URL Changes
Free ngrok URLs change on restart. You must update 4 places in Marketplace: Home URL, Redirect URL, OAuth Allow List, Domain Allow List. Consider ngrok paid plan for stable subdomain.

### 6. In-Client OAuth vs Web OAuth
Use `zoomSdk.authorize()` (In-Client) for best UX - no browser redirect. Only fall back to web redirect for initial install from Marketplace.

### 7. Camera Mode CEF Race Condition
Camera mode uses CEF which takes time to initialize. `drawImage`/`drawWebView` may fail if called too early. Implement retry with exponential backoff.

### 8. Cookie Configuration
Zoom's embedded browser requires cookies with `SameSite=None` and `Secure=true`. Without this, sessions break silently.

### 9. State Validation
Always validate the OAuth `state` parameter to prevent CSRF attacks. Generate cryptographically random state, store it, and verify on callback.

## Resources

- **Official docs**: https://developers.zoom.us/docs/zoom-apps/
- **SDK reference**: https://appssdk.zoom.us/
- **NPM package**: https://www.npmjs.com/package/@zoom/appssdk
- **Developer forum**: https://devforum.zoom.us/
- **GitHub SDK source**: https://github.com/zoom/appssdk

---

**Need help?** Start with Integrated Index section below for complete navigation.

---

## Integrated Index

_This section was migrated from `SKILL.md`._

## Quick Start Path

**If you're new to Zoom Apps, follow this order:**

1. **Run preflight checks first** -> [RUNBOOK.md](RUNBOOK.md)

2. **Read the architecture** -> [concepts/architecture.md](concepts/architecture.md)
   - Frontend/backend pattern, embedded browser, deep linking
   - Understand how Zoom loads and communicates with your app

3. **Build your first app** -> [examples/quick-start.md](examples/quick-start.md)
   - Complete Express + SDK Hello World
   - ngrok setup for local development

4. **Understand running contexts** -> [concepts/running-contexts.md](concepts/running-contexts.md)
   - Where your app runs (inMeeting, inMainClient, inWebinar, etc.)
   - Context-specific APIs and limitations

5. **Implement OAuth** -> [examples/in-client-oauth.md](examples/in-client-oauth.md)
   - In-Client OAuth with PKCE (best UX)
   - Token exchange and storage

6. **Add features** -> [references/apis.md](references/apis.md)
   - 100+ SDK methods organized by category
   - Code examples for each

7. **Troubleshoot** -> [troubleshooting/common-issues.md](troubleshooting/common-issues.md)
   - Quick diagnostics for common problems

---

## Documentation Structure

```
zoom-apps-sdk/
├── SKILL.md                           # Main skill overview
├── SKILL.md                           # This file - navigation guide
│
├── concepts/                          # Core architectural patterns
│   ├── architecture.md               # Frontend/backend, embedded browser, OAuth flow
│   ├── running-contexts.md           # Where your app runs + context-specific APIs
│   └── security.md                   # OWASP headers, CSP, data access layers
│
├── examples/                          # Complete working code
│   ├── quick-start.md                # Hello World - minimal Express + SDK app
│   ├── in-client-oauth.md            # In-Client OAuth with PKCE
│   ├── layers-immersive.md           # Layers API - immersive mode (custom layouts)
│   ├── layers-camera.md              # Layers API - camera mode (virtual camera)
│   ├── collaborate-mode.md           # Collaborate mode (shared state)
│   ├── guest-mode.md                 # Guest mode (unauthenticated -> authorized)
│   ├── breakout-rooms.md             # Breakout room integration
│   └── app-communication.md          # connect + postMessage between instances
│
├── troubleshooting/                   # Problem solving guides
│   ├── common-issues.md              # Quick diagnostics, error codes
│   ├── debugging.md                  # Local dev setup, ngrok, browser preview
│   └── migration.md                  # SDK version migration notes
│
└── references/                        # Reference documentation
    ├── apis.md                        # Complete API reference (100+ methods)
    ├── events.md                      # All SDK events
    ├── layers-api.md                  # Layers API detailed reference
    ├── oauth.md                       # OAuth flows for Zoom Apps
    └── zmail-sdk.md                   # Zoom Mail integration
```

---

## By Use Case

### I want to build a basic Zoom App
1. [Architecture](concepts/architecture.md) - Understand the pattern
2. [Quick Start](examples/quick-start.md) - Build Hello World
3. [In-Client OAuth](examples/in-client-oauth.md) - Add authorization
4. [Security](concepts/security.md) - Required headers

### I want immersive video layouts (Layers API)
1. [Layers Immersive](examples/layers-immersive.md) - Custom video positions
2. [Layers API Reference](references/layers-api.md) - All drawing methods
3. [App Communication](examples/app-communication.md) - Sync layout across participants

### I want a virtual camera overlay
1. [Camera Mode](examples/layers-camera.md) - Camera mode rendering
2. [Layers API Reference](references/layers-api.md) - Drawing methods

### I want real-time collaboration
1. [Collaborate Mode](examples/collaborate-mode.md) - Shared state APIs
2. [App Communication](examples/app-communication.md) - Instance messaging

### I want guest/anonymous access
1. [Guest Mode](examples/guest-mode.md) - Three authorization states
2. [In-Client OAuth](examples/in-client-oauth.md) - promptAuthorize flow

### I want breakout room support
1. [Breakout Rooms](examples/breakout-rooms.md) - Room detection and state sync

### I want to sync between main client and meeting
1. [App Communication](examples/app-communication.md) - connect + postMessage
2. [Running Contexts](concepts/running-contexts.md) - Multi-instance behavior

### I want serverless deployment
1. [Quick Start](examples/quick-start.md) - Understand the base pattern first
2. Sample: [zoomapps-serverless-vuejs](https://github.com/zoom/zoomapps-serverless-vuejs) - Firebase pattern

### I want to add Zoom Mail integration
1. [Zoom Mail Reference](references/zmail-sdk.md) - REST API + mail plugins

### I'm getting errors
1. [Common Issues](troubleshooting/common-issues.md) - Quick diagnostic table
2. [Debugging](troubleshooting/debugging.md) - Local dev setup, DevTools
3. [Migration](troubleshooting/migration.md) - Version compatibility

---

## Most Critical Documents

### 1. Architecture (FOUNDATION)
**[concepts/architecture.md](concepts/architecture.md)**

Understand how Zoom Apps work: Frontend in embedded browser, backend for OAuth/API, SDK as the bridge. Without this, nothing else makes sense.

### 2. Quick Start (FIRST APP)
**[examples/quick-start.md](examples/quick-start.md)**

Complete working code. Get something running before diving into advanced features.

### 3. Common Issues (MOST COMMON PROBLEMS)
**[troubleshooting/common-issues.md](troubleshooting/common-issues.md)**

90% of Zoom Apps issues are: domain allowlist, global variable conflict, or missing capabilities.

---

## Key Learnings

### Critical Discoveries:

1. **Global Variable Conflict is the #1 Gotcha**
   - CDN script defines `window.zoomSdk` globally
   - `let zoomSdk = ...` causes SyntaxError in Zoom's browser
   - Use `let sdk = window.zoomSdk` or NPM import

2. **Domain Allowlist is Non-Negotiable**
   - App shows blank panel with zero error if domain not whitelisted
   - Must include your domain AND `appssdk.zoom.us` AND any CDN domains
   - ngrok URLs change on restart - must update Marketplace each time

3. **config() Gates Everything**
   - Must be called first, must list all capabilities
   - Unlisted capabilities throw errors
   - Check `unsupportedApis` for client version compatibility

4. **In-Client OAuth > Web OAuth for UX**
   - `authorize()` keeps user in Zoom (no browser redirect)
   - Web redirect only needed for initial Marketplace install
   - Always implement PKCE (code_verifier + code_challenge)

5. **Two App Instances Can Run Simultaneously**
   - Main client instance + meeting instance
   - Use `connect()` + `postMessage()` to sync between them
   - Pre-meeting setup in main client, use in meeting

6. **Camera Mode Has CEF Quirks**
   - CEF initialization takes time
   - Draw calls may fail if too early
   - Use retry with exponential backoff

7. **Cookie Settings Matter**
   - `SameSite=None` + `Secure=true` required
   - Without this, sessions silently fail in embedded browser

---

## Quick Reference

### "App shows blank panel"
-> [Domain Allowlist](troubleshooting/common-issues.md) - add domain to Marketplace

### "SyntaxError: redeclaration"
-> [Global Variable](troubleshooting/common-issues.md) - use `let sdk = window.zoomSdk`

### "config() throws error"
-> [Browser Preview](troubleshooting/debugging.md) - SDK only works inside Zoom

### "API call fails silently"
-> [OAuth Scopes](troubleshooting/common-issues.md) - add required scopes in Marketplace

### "How do I implement [feature]?"
-> [API Reference](references/apis.md) - find the method, check capabilities needed

### "How do I test locally?"
-> [Debugging Guide](troubleshooting/debugging.md) - ngrok + Marketplace config

---

## Document Version

Based on **@zoom/appssdk v0.16.x** (latest: 0.16.26+)

---

**Happy coding!**

Start with [Architecture](concepts/architecture.md) to understand the pattern, then [Quick Start](examples/quick-start.md) to build your first app.

Источник: anthropics/knowledge-work-plugins / zoom-plugin / zoom-apps-sdk ↗. Ссылка проверена 2026-10-10.