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 own Zoom account under Settings → Integrations → Video Conferencing → + Connect account, and from then on VILT sessions get a Zoom join link automatically.
There is one way to connect: you click Continue to Zoom, approve on Zoom’s consent screen, and EmbayLMS holds a short-lived access token that it refreshes on its own. Meetings, participants and cloud recordings all stay inside your Zoom account.
Every meeting is created on your account. EmbayLMS has no shared Zoom account of its own to fall back on, so nothing about your sessions — attendee names, video, or recordings — ever lands in someone else’s Zoom tenancy. If your connection is missing or needs re-authorisation, EmbayLMS tells you when you schedule the session instead of quietly creating nothing.
Credentials are encrypted (AES-256-GCM) before storage and are never shown again to anyone, including Embay staff.
Requirement: a Zoom account where you can create an app in the Zoom App Marketplace (Account owner, or an admin with the relevant developer role). Cloud recording (optional, below) requires a paid Zoom plan.
Step 1 — Create a General (OAuth) app in Zoom
-
Sign in to the Zoom App Marketplace → Develop → Build App → General App.
-
Choose User-managed app (an admin-managed app also works if your Zoom admin prefers it) and leave Publish to Zoom App Marketplace off — an unpublished app works for your own account.
-
On Basic Information, copy the Client ID and Client Secret.
-
In OAuth Redirect URL and OAuth Allow List, enter the redirect URL exactly as EmbayLMS shows it in the connect dialog:
https://<your-tenant>.embaylms.com/api/integrations/zoom/callbackIt must match character for character — Zoom rejects the authorisation otherwise.
-
Under Scopes, add:
Scope Why meeting:writeCreate and update VILT meetings meeting:readRead a meeting back (used for webhook routing) recording:readCapture the cloud recording link after a session user:readIdentify which Zoom account was connected meeting:writecovers deleting a meeting when a session is cancelled — there is no separate delete scope. -
Save. You do not need to submit the app for review.
Step 2 — Connect in EmbayLMS
- Go to Settings → Integrations → Video Conferencing → + Connect account.
- Choose Zoom.
- Fill in:
| Field | Value |
|---|---|
| Display name | A label for this account (e.g. “Company Zoom”) |
| Redirect URL | Shown read-only — copy it into your Zoom app (step 1.4) |
| Client ID | From your Zoom app’s Basic Information |
| Client Secret | From your Zoom app’s Basic Information |
- Click Continue to Zoom. Approve the requested scopes on Zoom’s consent screen.
- Zoom returns you to EmbayLMS, which confirms “Your Zoom account is connected” and shows the linked Zoom account’s email in the account list.
If your environment has a platform-wide Zoom app configured by Embay, you can leave Client ID and Client Secret blank and EmbayLMS will use that shared app instead. This is a shared app, not a shared account: the tokens it issues still belong to the Zoom account you authorise with, and your meetings are still created there. Most tenants supply their own app.
Token refresh is automatic. The access token Zoom issues lasts about an hour. EmbayLMS refreshes it before it expires — including rotating the refresh token, which Zoom replaces on every refresh — so a connection made once keeps working. If a refresh ever fails (you removed the app in Zoom, or revoked access), the account is flagged Reauthorization needed in the list; connect it again to fix it. Until you do, scheduling a VILT session on that account fails with a message saying so, rather than creating a session with no link.
Step 3 — 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.
Because the meetings live on your Zoom account, the events are signed with your Zoom app’s Secret Token. You give EmbayLMS that token so it can verify them.
-
In the same Zoom app you created in step 1, open Feature → Event Subscriptions and turn event subscriptions on. Add a subscription.
-
Event notification endpoint URL — the URL is specific to your tenant, and EmbayLMS shows the exact value on the connected account in Settings → Integrations → Video Conferencing. It has the form:
https://<your-tenant>.embaylms.com/api/webhooks/zoom/<your-tenant> -
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 (
-
On the same screen, copy the app’s Secret Token.
-
Back in EmbayLMS, on the connected Zoom account, paste it into Secret Token under Webhook (auto-attendance and recordings) and click Save secret. The panel then shows the date it was set; the value itself is encrypted and never displayed again.
-
Only now click Validate in Zoom. EmbayLMS answers Zoom’s URL-validation challenge using your Secret Token, so validation fails until step 5 is done.
Order matters. Until the Secret Token is saved, your tenant’s webhook endpoint has nothing to verify against and returns 503 — including for Zoom’s validation challenge. Save the secret first, then validate in Zoom.
To turn webhooks off again, click Remove secret. EmbayLMS immediately stops accepting events from that Zoom app and attendance goes back to manual marking.
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 the session must belong to the tenant the event was delivered to, so one tenant’s Zoom app can never write into another tenant’s records.
- 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.
- An instructor’s manual mark always wins — automation never overwrites it.
- 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.
Disconnecting
Click the trash icon next to the account. EmbayLMS revokes the grant at Zoom (so EmbayLMS disappears from your Zoom account’s authorised apps) and deletes the stored tokens and webhook secret. If Zoom is unreachable at that moment the local credentials are still deleted, and the audit log records that the revocation did not complete — remove EmbayLMS manually from zoom.us → Settings → Installed Apps in that case.
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 you leave the video account as Default connected account, EmbayLMS uses the first account you connected. With no usable connection and no manual meeting link, creating the VILT session is refused with an explanatory message — see Troubleshooting.
If meeting creation itself fails after a healthy connection resolves (e.g. a Zoom outage or a missing scope), the session still saves — you can paste a join link manually on the session.
Manual meeting link — when you do not want EmbayLMS to create anything
You do not have to connect a video account at all. If you already hold a meeting URL — your own Zoom personal link, a Microsoft Teams meeting, Webex, or a recurring room your team always uses — paste it on the session and EmbayLMS creates nothing. That link is what learners join.
Where to enter it
- When creating the session: Course editor → the ILT module → Add session → choose VILT → Or paste a meeting link.
- On an existing session: Planned sessions → [session] → Video meeting → Manual meeting link. Save an address to set it; clear the field and save to remove it. You can do this at any time — before or after learners register.
Rules
| Rule | Detail |
|---|---|
| Format | An absolute https:// address only. http://, a bare hostname, or a path fragment is rejected with a message telling you so. |
| Session type | Virtual (VILT) sessions only. An in-person session’s place is the Location field. |
| Precedence | A meeting EmbayLMS created always wins. If a session has both an auto-created meeting and a manual link, learners join the created meeting; the manual link is kept in reserve. |
| Creation | While a manual link is present, EmbayLMS makes no call to Zoom or Google Meet at all — no meeting is created, so none needs cancelling. |
| Changing it | Setting or clearing the link changes where the session happens, so registered learners are emailed and their calendar invite is reissued — the same as moving a room. |
The tradeoff, stated plainly. Automation does not apply to a manual link. EmbayLMS did not create the meeting, receives no webhook events for it, and has no API access to it — so attendance is not marked automatically and no recording is captured. You mark attendance yourself on the session roster, and attach a recording URL by hand if you want one. If auto-attendance matters to you, connect the account (steps 1–3 above) instead of pasting a link.
Marking attendance: with webhooks configured (above), 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.
Configuration reference
| Field | Where | Value |
|---|---|---|
| Display name | Settings → Integrations → Video Conferencing | Label for the connected account |
| Redirect URL | Zoom app → OAuth Redirect URL + Allow List | https://<your-tenant>.embaylms.com/api/integrations/zoom/callback — must match exactly |
| Client ID / Secret | Zoom app → Basic Information | From your General (user-managed) OAuth app; encrypted at rest |
| Scopes | Zoom app → Scopes | meeting:write, meeting:read, recording:read, user:read |
| Webhook URL (optional) | Zoom app → Feature → Event Subscriptions | https://<your-tenant>.embaylms.com/api/webhooks/zoom/<your-tenant> — shown on the connected account |
| Secret Token (optional) | Zoom app → Feature → Event Subscriptions → EmbayLMS Webhook panel | Signs your webhook events; encrypted at rest, never displayed again |
| Webhook events (optional) | Zoom app → Event Subscriptions | meeting.participant_joined, meeting.participant_left, meeting.ended, recording.completed |
| Manual meeting link (optional) | Session → Video meeting, or the Add session form | An absolute https:// URL you already hold. Replaces meeting creation entirely; an auto-created meeting takes precedence over it. No auto-attendance, no recording capture |
Troubleshooting
| Symptom | Cause / fix |
|---|---|
| ”Zoom did not complete the connection.” after the consent screen | Almost always the redirect URL: it must be registered in the Zoom app’s OAuth Redirect URL and OAuth Allow List, character for character, including https:// and no trailing slash. Also check the Client ID/Secret were copied from the same app. |
| ”Connect a Zoom or Google Meet account … before scheduling a virtual session.” | The tenant has no connected video account. Either connect one under Settings → Integrations → Video Conferencing, or paste a manual meeting link on the session (see above) if you already have a meeting URL. |
”Enter a full web address that starts with https://…” | The manual meeting link was not an absolute https:// URL. Paste the complete address, including the scheme — teams.microsoft.com/... and http://... are both rejected. |
| ”A meeting link applies to virtual (VILT) sessions only.” | You entered a manual link on an in-person (ILT) session. Use the Location field for a room or address, or change the session type to VILT. |
| Pasted a manual link but learners still get the Zoom link | Intended: an auto-created meeting takes precedence. Learners join the meeting EmbayLMS created — that is the one whose recording and attendance are captured. To make the manual link the one they use, clear the Zoom URLs under Override the stored Zoom URLs. |
| ”This Zoom account needs to be authorized again.” | The refresh token no longer works — the app was removed in Zoom, access was revoked, or the app’s credentials were rotated. Disconnect the account and connect it again. |
| ”This Zoom account was connected the old way and is no longer supported.” | A legacy Server-to-Server connection. That method was retired; disconnect it and reconnect with the Connect button. |
| 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 creation fails with a 4xx from Zoom | Usually a missing scope or an account-plan limit. Add meeting:write to the app’s scopes; verify the authorising Zoom user can schedule meetings. |
| Webhook endpoint validation fails in Zoom | Three things must all be true: the URL is the per-tenant one (/api/webhooks/zoom/<your-tenant>), the Secret Token is already saved in EmbayLMS, and it matches the token in that same Zoom app. EmbayLMS verifies the signature before answering Zoom’s challenge, so an unsaved or mismatched secret fails validation. |
| Webhook endpoint returns 503 | No Secret Token is saved for that connected account yet. Paste it in the Webhook panel and save, then re-validate in Zoom. |
| Webhook endpoint returns 410 Gone | The Zoom app is still pointed at the old shared endpoint /api/webhooks/zoom. Change it to the per-tenant URL shown on the connected account. |
| 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 your Secret Token must be saved. |
| Attendance not auto-filling at all | Confirm the meeting.participant_joined/ended events are subscribed, the endpoint validated, and the Secret Token saved. Without webhooks, VILT attendance stays manual. |
| 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. |