Zoom for VILT sessions
EmbayLMS can automatically create a Zoom meeting when you schedule a VILT (virtual instructor-led) session — the Zoom equivalent of the Google Meet integration. You connect your tenant’s own Zoom account under Settings → Integrations → Video Conferencing → Add account → Zoom, and from then on VILT sessions get a Zoom join link automatically.
EmbayLMS connects using a Zoom Server-to-Server OAuth app (account credentials — the modern replacement for JWT apps). There is no per-user “Sign in with Zoom” pop-up; instead you create a Server-to-Server OAuth app in your Zoom account and paste its three credentials into EmbayLMS. The credentials are encrypted (AES-256-GCM) before storage and are never shown to anyone again.
Requirement: a Zoom account where you can create a Server-to-Server OAuth app in the Zoom App Marketplace (Account owner or admin with the Server-to-Server OAuth role). Cloud recording (optional, below) requires a paid Zoom plan.
Step 1 — Create a Server-to-Server OAuth app
- Sign in to the Zoom App Marketplace → Develop → Build App → Server-to-Server OAuth → Create.
- Name the app (e.g.
EmbayLMS). - On the App Credentials screen, copy the three values you’ll paste into
EmbayLMS:
- Account ID
- Client ID
- Client Secret
- Under Scopes, add meeting scopes so EmbayLMS can create, update, and delete
meetings on your account — e.g.
meeting:write:admin(andmeeting:read:admin). - Activate the app.
Step 2 — Connect in EmbayLMS
- Go to Settings → Integrations → Video Conferencing.
- Click Add account, choose Zoom.
- Fill in:
| Field | Value |
|---|---|
| Display name | A label for this account (e.g. “Company Zoom”) |
| Account ID | From the Zoom app’s App Credentials (Step 1) |
| Client ID | From the Zoom app’s App Credentials |
| Client Secret | From the Zoom app’s App Credentials |
- Click Connect & Verify. EmbayLMS validates the credentials by requesting a token from Zoom; if anything is wrong it tells you and nothing is saved. After connecting, you can re-test or disconnect the account at any time from the same page.
Using it
When you create a VILT session and select this Zoom account, EmbayLMS creates a scheduled Zoom meeting and stores the join link on the session. Specifically:
- The meeting is created with waiting room on, join-before-host off, and mute-on-entry, scheduled at the session’s start time and duration in the session’s timezone.
- Learners see the join link on the session page and in their registration email — exactly like Google Meet.
- Rescheduling a session (new time, duration, or title) updates the Zoom meeting; cancelling the session deletes the meeting so the link stops working.
- If no account is selected, EmbayLMS falls back to platform Zoom credentials when they are configured; otherwise it skips meeting creation.
If meeting creation fails (e.g. credentials revoked or missing scopes), the session still publishes — you can paste a join link manually on the session.
Marking attendance: with webhooks configured (below), EmbayLMS auto-marks attendance from Zoom join/leave events. You can always override any mark manually on the session’s roster — set a registrant
presentorabsentand save. Without webhooks, attendance is fully manual.
Optional — webhooks for auto-attendance and cloud recordings
With a Zoom webhook subscription, EmbayLMS automatically (a) marks attendance as learners join and leave the meeting, and (b) captures the cloud recording link. Both are optional; meeting creation works without them.
- In your Server-to-Server OAuth app, open the Feature → Event Subscriptions section and add a subscription.
- Event notification endpoint URL:
https://<your-tenant>.embaylms.com/api/webhooks/zoom - Subscribe to these events:
- Meeting → Participant/Host joined meeting (
meeting.participant_joined) - Meeting → Participant/Host left meeting (
meeting.participant_left) - Meeting → End Meeting (
meeting.ended) - Recording → All Recordings have completed (
recording.completed) — cloud recording only, paid Zoom plans
- Meeting → Participant/Host joined meeting (
- Validate the endpoint. EmbayLMS answers Zoom’s URL-validation challenge
automatically, and verifies every subsequent event’s HMAC signature using the
platform’s
ZOOM_WEBHOOK_SECRET.
How auto-attendance works. EmbayLMS embeds the session ID in the Zoom meeting’s agenda, so each event is routed to the right session and tenant.
- When a learner joins, EmbayLMS matches them by their Zoom account email to a registered learner and marks them present, awarding session credit immediately (their ILT module completes and course progress recomputes).
- A learner who joins at all counts as present; leave events are recorded to the audit trail but do not remove a present mark.
- When the meeting ends, every registrant who never joined is marked absent, closing the attendance window.
- Every webhook event is written to the append-only audit log (SOC 2 CC6.3).
Email matching matters. Auto-attendance can only match a participant Zoom includes an email for (authenticated joins) whose email equals the learner’s EmbayLMS email. Guests, dial-in-only participants, or learners who join with a different email are not matched — mark them manually on the roster.
Webhook signature verification depends on the platform-level
ZOOM_WEBHOOK_SECRETbeing configured. If it is unset, the webhook endpoint returns 503 and neither attendance nor recording links are captured — meeting creation still works regardless.
Configuration reference
| Field | Where | Value |
|---|---|---|
| Display name | Settings → Integrations → Video Conferencing | Label for the connected account |
| Account ID | Zoom app → App Credentials | Server-to-Server OAuth account ID |
| Client ID | Zoom app → App Credentials | OAuth client ID |
| Client Secret | Zoom app → App Credentials | OAuth client secret (encrypted at rest) |
| Scopes | Zoom app → Scopes | meeting:write:admin (+ meeting:read:admin) |
| Webhook URL (optional) | Zoom app → Event Subscriptions | https://<your-tenant>.embaylms.com/api/webhooks/zoom |
| Webhook events (optional) | Zoom app → Event Subscriptions | meeting.participant_joined, meeting.participant_left, meeting.ended, recording.completed |
Troubleshooting
| Symptom | Cause / fix |
|---|---|
| ”Could not connect to Zoom — check your Account ID, Client ID, and Client Secret.” | One of the three credentials is wrong, or the Server-to-Server OAuth app is not activated. Re-copy all three from the app’s App Credentials page and re-activate the app. |
| Connects, but VILT sessions have no Zoom link | Confirm the session is VILT (not in-person ILT) and that this Zoom account is selected on the session. Check the app has meeting write scope (meeting:write:admin). |
| Meeting creation fails with a 4xx from Zoom | Usually a missing scope or an account-plan limit. Add meeting:write:admin to the app’s scopes and re-activate; verify the host account can schedule meetings. |
| Recording link never appears on the session | Cloud recording must be enabled on the Zoom plan/meeting, the recording.completed event must be subscribed, and the platform ZOOM_WEBHOOK_SECRET must be set. The endpoint returns 503 when the secret is unset. |
| Webhook endpoint validation fails in Zoom | The endpoint URL must point at your tenant subdomain and the platform ZOOM_WEBHOOK_SECRET must match the value in the Zoom app. EmbayLMS rejects events whose signature or timestamp (older than 5 minutes) don’t validate. |
| A learner attended but was marked absent (or not marked) | Auto-attendance matches by Zoom account email. If they joined as a guest or with a different email than their EmbayLMS account, they won’t match — mark them present manually on the roster. Confirm the three meeting events are subscribed. |
| Attendance not auto-filling at all | Confirm the meeting.participant_joined/ended events are subscribed, the endpoint validated, and ZOOM_WEBHOOK_SECRET is set. Without webhooks, VILT attendance stays manual. |