Webhook envelope
Every webhook body has the same envelope; data depends on type.
{
"id": "evt_01JA7XQ4…", // identical across retries and redeliveries — dedupe on it
"type": "participant.joined",
"createdAt": "2026-10-14T09:31:12.000Z",
"organizationId": "org_123",
"data": {
"meetingId": "cm2x8k3…",
"externalMeetingId": "algebra-10a-2026-10-14",
"kind": "MEETING",
"participantId": "cm2p…",
"user": { "id": "cm2u…", "externalId": "student-1001", "name": "Aarav P.", "role": "STUDENT" },
"device": "android",
"joinedAt": "2026-10-14T09:31:10.000Z"
}
}
Webhook events
Subscribe to individual types, or to * for everything (including types added later). Sample payloads for each type are in the webhooks guide.
Meetings & classes
| Type | When | data |
|---|
meeting.created | A meeting or live class was scheduled/created | WebhookMeetingData |
meeting.updated | Title, schedule or settings changed | WebhookMeetingData |
meeting.started | The host or first participant started the room | WebhookMeetingData |
meeting.ended | The room ended (host ended it, or everyone left) | WebhookMeetingData |
meeting.cancelled | A scheduled meeting or class was cancelled | WebhookMeetingData |
Participants
| Type | When | data |
|---|
participant.joined | Someone joined the room | WebhookParticipantData |
participant.left | Someone left (includes durationSeconds) | WebhookParticipantData |
participant.waiting | Someone is waiting in the waiting room | WebhookWaitingRoomData |
participant.admitted | A host admitted someone from the waiting room | WebhookWaitingRoomData |
Recordings
| Type | When | data |
|---|
recording.started | Cloud recording started | WebhookRecordingData |
recording.ready | The recording is processed and playable | WebhookRecordingData |
recording.failed | Recording or processing failed (failureReason) | WebhookRecordingData |
recording.deleted | A recording was deleted (deletedAt) | WebhookRecordingData |
Transcripts
| Type | When | data |
|---|
transcript.ready | The AI transcript of a recording is available | WebhookTranscriptData |
insights
| Type | When | data |
|---|
insights.ready | AI notes (summary, chapters, quiz draft) of a recording are ready | WebhookInsightsData |
Attendance
| Type | When | data |
|---|
attendance.finalized | Attendance for a class session is final | WebhookAttendanceData |
Users
| Type | When | data |
|---|
user.created | An org member was provisioned | WebhookUserData |
user.updated | An org member’s name, role or metadata changed | WebhookUserData |
user.deactivated | An org member was deactivated | WebhookUserData |
Enrollments
| Type | When | data |
|---|
enrollment.created | A student was enrolled in a class or batch | WebhookEnrollmentData |
enrollment.removed | A student was removed from a class or batch | WebhookEnrollmentData |
Classes
| Type | When | data |
|---|
class.created | An academic class was created | WebhookClassData |
class.updated | An academic class changed | WebhookClassData |
poll
| Type | When | data |
|---|
poll.closed | | unknown |
question
| Type | When | data |
|---|
question.answered | | unknown |
webhook.test is sent only by “Send test event” and cannot be subscribed to. Participant events include the device (web, android, ios, unknown), and participant.left includes durationSeconds.
Embedded room events (browser)
Delivered with postMessage to your page (or to your native app's WebView bridge). Payloads and commands are described in the embedding guide.
| Event | When |
|---|
ready | The embedded room (or recording player) loaded and accepted your origin |
joined | Your user connected to the class |
left | Your user left, was removed, joined elsewhere, or the connection failed |
participant-joined / participant-left | Someone else joined or left |
recording-started / recording-stopped | Cloud recording state changed |
hand-raised | A hand went up or down |
meeting-ended | The host ended the meeting for everyone |
error | Something went wrong (code, message, fatal) |
play / pause / ended | Recording player only |
Browser events are for your UI; use webhooks for anything you store (attendance, billing, analytics) — they are signed, retried and do not depend on the user's tab staying open.