Generated banner for Build Zoom Meeting SDK App
Generated logo for Build Zoom Meeting SDK App

Build Zoom Meeting SDK App

OpenAIOfficialCreated by ZoomDistributed by OpenAI

  • Skill
  • Tool integration
  • Software development
  • MIT
  • No issues found

From the author

Use when using Meeting SDK.
— the description by Zoom

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured workflow for developers integrating the Zoom Meeting SDK into their applications. It covers the lifecycle of a meeting integration, from initial product validation and platform selection to implementation and debugging. It emphasizes the distinction between the Meeting SDK, which is designed for human-led meetings, and other Zoom SDKs, while providing guidance on handling signatures, user identity, and meeting controls.

What it does

  • Guides developers through the integration of the Zoom Meeting SDK for web, mobile, and desktop platforms.
  • Provides a systematic workflow for joining and starting meetings.
  • Offers troubleshooting strategies for common issues like signature generation and permission errors.
  • Includes references for platform-specific implementations and AI Companion feature management.
  • Helps validate meeting parameters such as meeting numbers, passwords, and ZAK tokens.

When to use it

  • When you need to embed real Zoom meetings into your application.
  • When you are setting up a new Zoom Meeting SDK project for web, Android, iOS, or desktop.
  • When you encounter errors during the meeting join flow or signature validation.
  • When you need to manage AI Companion features within an embedded meeting context.

Advantages

  • Provides a clear, step-by-step path for successful SDK integration.
  • Centralizes access to platform-specific documentation and troubleshooting resources.
  • Helps distinguish between different Zoom SDK capabilities to ensure the right tool is used.
  • Includes a dedicated signature playbook to resolve common authentication failures.

Usage examples

“How do I start integrating the Zoom Meeting SDK for an Android app?”
The agent will guide you through verifying your environment, choosing the default UI for initial testing, and using the Android-specific reference pointers to resolve dependencies.
“I am getting an invalid signature error when trying to join a meeting.”
The agent will direct you to the signature playbook to verify your SDK signature generation logic and parameter matching.
“Can I use the Meeting SDK to build an automated AI notetaker bot?”
The agent will clarify that the Meeting SDK is for human use cases only and recommend using rtms for automated AI processing.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/openai/build-zoom-meeting-sdk-app/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip build-zoom-meeting-sdk-app.zip -d .agents/skills

Documentation by Zoom

Build Zoom Meeting SDK App

Use this skill when the user needs to join, start, or embed real Zoom meetings. If the user wants a fully custom non-meeting video experience, route to build-zoom-video-sdk-app.

Workflow

  1. Confirm product fit: Meeting SDK joins real Zoom meetings; Video SDK creates custom sessions; Zoom Apps SDK runs inside the Zoom client.

  2. Choose the target platform: web, Android, iOS, macOS, Windows, Electron, React Native, Unreal, or Linux bot.

  3. Validate the join or start path: meeting number, password, SDK signature, role, ZAK when hosting, waiting room behavior, and user identity.

  4. Implement the smallest join flow first, then add meeting controls, custom UI, raw data, recording, or bot behavior.

  5. Debug by isolating signature generation, SDK version, platform permissions, meeting settings, waiting room, raw data entitlement, and network constraints.

References

Files

references/webinars.md

Meeting SDK - Webinars

Embed webinar experiences using Meeting SDK.

Overview

Meeting SDK can join webinars, not just meetings. This guide covers webinar-specific features and considerations.

Webinar vs Meeting

FeatureMeetingWebinar
Max participants100-1000500-50,000
Participant rolesHost, co-host, participantHost, panelist, attendee
Attendee videoYesNo (view-only)
Attendee audioYesRaise hand to unmute
Q&ANoYes
RegistrationOptionalCommon
Practice sessionNoYes

Joining Webinars

Web SDK
const client = ZoomMtgEmbedded.createClient();

await client.init({
  zoomAppRoot: document.getElementById('meetingSDKElement'),
  language: 'en-US',
});

// Join webinar (same as meeting)
await client.join({
  sdkKey: SDK_KEY,
  signature: signature,
  meetingNumber: webinarId,  // Webinar ID
  userName: 'Attendee Name',
  userEmail: '[email protected]',  // Required for registration
  passWord: password,
  tk: registrantToken,  // If registration required
});
Registration Token

If the webinar requires registration:

// 1. Register via API first
const response = await axios.post(
  `https://api.zoom.us/v2/webinars/${webinarId}/registrants`,
  {
    email: '[email protected]',
    first_name: 'John',
    last_name: 'Doe'
  },
  { headers: { 'Authorization': `Bearer ${accessToken}` }}
);

// 2. Get registrant token
const registrantToken = response.data.registrant_id;

// 3. Use token when joining
await client.join({
  // ... other params
  tk: registrantToken,
});
Native SDKs (iOS/Android/Windows)
// iOS - Join webinar
let joinParam = ZoomSDKJoinWebinarParam()
joinParam.webinarNumber = webinarNumber
joinParam.userName = "Attendee"
joinParam.userEmail = "[email protected]"
joinParam.webinarPassword = password
joinParam.webinarToken = registrantToken  // If registered

meetingService.joinWebinar(with: joinParam)
// Android - Join webinar
val joinParams = JoinMeetingParams().apply {
    meetingNo = webinarId
    displayName = "Attendee"
    password = webinarPassword
}

// Webinar uses same joinMeeting API
meetingService.joinMeetingWithParams(context, joinParams, JoinMeetingOptions())

Attendee vs Panelist

Role Detection
// Web SDK
client.on('user-updated', (payload) => {
  const { userId } = payload;
  const user = client.getUser(userId);

  // Check role
  if (user.isHost) {
    console.log('User is host');
  } else if (user.userRole === 'panelist') {
    console.log('User is panelist');
  } else {
    console.log('User is attendee');
  }
});
Attendee Limitations

Attendees in webinars have restricted capabilities:

ActionAttendee Can Do?
View videoYes
Send videoNo
Listen to audioYes
Unmute selfNo (must be promoted)
Send chatTo panelists/everyone (if enabled)
Ask Q&AYes
Raise handYes

Q&A Feature

Web SDK Q&A
// Check if Q&A is enabled
const qaClient = client.getQAClient();
const isQAEnabled = qaClient.isQAEnabled();

// Ask a question
await qaClient.askQuestion('What is the pricing?', false);  // false = public

// Answer a question (panelist/host only)
await qaClient.answerQuestion(questionId, 'The pricing is...');

// Get all questions
const questions = qaClient.getAllQuestions();
questions.forEach(q => {
  console.log(`Q: ${q.text}`);
  console.log(`A: ${q.answerText || 'Unanswered'}`);
});

// Q&A events
client.on('question-created', (payload) => {
  console.log('New question:', payload.question.text);
});

client.on('answer-created', (payload) => {
  console.log('Answer:', payload.answer.text);
});
Native SDK Q&A
// iOS
let qaController = meetingService.getWebinarQAController()

// Ask question
qaController?.askQuestion("What is the pricing?", isAnonymous: false)

// Get questions (host/panelist)
let questions = qaController?.getAllQuestionList()

Raise Hand

Web SDK
// Raise hand
client.raiseHand();

// Lower hand
client.lowerHand();

// Check status
const myself = client.getCurrentUser();
console.log('Hand raised:', myself.bRaiseHand);

// Event
client.on('user-updated', (payload) => {
  if (payload.bRaiseHand !== undefined) {
    console.log(`${payload.userId} ${payload.bRaiseHand ? 'raised' : 'lowered'} hand`);
  }
});
Native SDK
// iOS
let webinarController = meetingService.getWebinarController()
webinarController?.raiseHand()
webinarController?.lowerHand()

Promote/Demote Attendees

Hosts can promote attendees to panelists:

// Web SDK (host only)
const webinarClient = client.getWebinarClient();

// Promote to panelist (allows video/audio)
await webinarClient.promoteAttendee(userId);

// Demote back to attendee
await webinarClient.demoteAttendee(userId);

// Allow attendee to talk (temporary unmute)
await webinarClient.allowAttendeeTalk(userId);
await webinarClient.disallowAttendeeTalk(userId);

Polling

Web SDK Polling
// Get polling client
const pollingClient = client.getPollingClient();

// Check if polling available
const isAvailable = pollingClient.isPollingEnabled();

// Submit poll answer (attendee)
await pollingClient.submitPollAnswer(pollId, [
  { questionId: 'q1', answerIds: ['a1'] }
]);

// Poll events
client.on('poll-started', (payload) => {
  console.log('Poll started:', payload.poll);
  displayPoll(payload.poll);
});

client.on('poll-ended', (payload) => {
  console.log('Poll ended');
});

Practice Session

Before a webinar starts, hosts can run a practice session:

// Detect practice session
client.on('meeting-status-changed', (payload) => {
  if (payload.status === 'practice') {
    console.log('In practice session - attendees cannot join yet');
  } else if (payload.status === 'webinar') {
    console.log('Webinar is live');
  }
});

Chat in Webinars

Chat permissions differ in webinars:

// Get chat privilege
const chatClient = client.getChatClient();
const privilege = chatClient.getPrivilege();

// privilege values:
// 1 = No one
// 2 = Host and panelists only
// 3 = Everyone publicly
// 4 = Everyone publicly and privately

// Send to panelists (attendee)
await chatClient.send('Question about pricing', /* to all panelists */);

// Send to everyone (if allowed)
await chatClient.sendToAll('Hello everyone!');

Webinar-Specific Events

// Web SDK events
client.on('webinar-invite', (payload) => {
  // Attendee invited to become panelist
});

client.on('webinar-depromote', (payload) => {
  // Demoted from panelist to attendee
});

client.on('webinar-allow-attendee-chat', (payload) => {
  // Chat permissions changed
});

client.on('webinar-attendee-status', (payload) => {
  // Attendee count updated
  console.log('Attendees:', payload.attendeeCount);
});

Best Practices

For Large Webinars
  1. Disable attendee video - Already default for webinars

  2. Use Q&A instead of chat - More organized for large audiences

  3. Pre-register attendees - Better tracking and control

  4. Test with practice session - Verify setup before going live

UI Considerations
// Adjust UI based on role
function setupUI(role) {
  if (role === 'attendee') {
    // Hide video controls (can't send video)
    hideElement('#videoControls');

    // Show Q&A and raise hand
    showElement('#qaPanel');
    showElement('#raiseHandButton');

    // Disable unmute (until promoted)
    disableElement('#unmuteButton');
  } else if (role === 'panelist' || role === 'host') {
    // Full controls
    showAllControls();
  }
}

Resources

Requirements and compatibility

Written for: OpenAI Codex

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Zoom
Publisher
OpenAI (Official)
Distributed by
OpenAI
Source
openai/plugins · plugins/zoom/skills/meeting-sdk · commit d420d13
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from plugins/zoom/LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Zoom or OpenAI.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download build-zoom-meeting-sdk-app.zip