Skip to main content

Webhook integration

Your backend can receive classroom and courseware state changes through webhooks. Configure an HTTPS URL and event subscriptions for an application in the console. When an event occurs, the classroom service sends an HTTP POST containing event data to that URL. Client callbacks such as onClassInfoChanged execute inside the client SDK; server webhooks are received by your backend.

Webhook delivery

Swipe horizontally to see the full diagram

Webhook deliveryAcknowledge after persisting the event, then process it in a background job. Timeouts and non-2xx responses trigger retries. Deduplicate by appId + eventId.Console configurationHTTPS receiver · Event subscriptions · Signing secretClassroom serviceYour backendBackground job1 Event occursClass or courseware change3 Verify and persistCheck app · Deduplicate · StoreRetry on delivery failureEvent ID and payload stay unchanged; each attempt gets a new signing timestamp.2 HTTPS POSTEvent payload + signature4 HTTP 2xx · Acknowledge5 Process asynchronously
Acknowledge after persisting the event, then process it in a background job. Timeouts and non-2xx responses trigger retries. Deduplicate by appId + eventId.
Webhook delivery

Swipe horizontally to see the full diagram

Webhook deliveryAcknowledge after persisting the event, then process it in a background job. Timeouts and non-2xx responses trigger retries. Deduplicate by appId + eventId.Console configurationHTTPS receiver · Event subscriptions · Signing secretClassroom serviceYour backendBackground job1 Event occursClass or courseware change3 Verify and persistCheck app · Deduplicate · StoreRetry on delivery failureEvent ID and payload stay unchanged; each attempt gets a new signing timestamp.2 HTTPS POSTEvent payload + signature4 HTTP 2xx · Acknowledge5 Process asynchronously

Acknowledge after persisting the event, then process it in a background job. Timeouts and non-2xx responses trigger retries. Deduplicate by appId + eventId.

Configure the console​

  1. Deploy an HTTPS POST endpoint reachable by the service, such as https://api.example.com/webhooks/eduskit. Accept JSON and preserve the raw request body. Use a valid TLS certificate.
  2. Sign in to the console, open Callbacks, and select the application.
  3. Enter the callback URL, select at least one event, such as classroom.started, classroom.ended or courseware.ready, and save.
  4. Copy the signing secret shown after saving and store it in your receiving service's secret configuration. Webhooks use webhookSecret, separately from the Server SDK's appSecret.
  5. Create or start a classroom, or complete a courseware conversion in that application. Check the receiver's logs and persisted records. Saving configuration alone does not produce those business events.

Configuration is per application: one callback URL and one subscription set. The URL limit is 2048 characters. Current console/backend validation accepts HTTP and HTTPS; use HTTPS for production receivers.

The first configuration, a URL change, or Regenerate generates a new signing secret. Its plaintext is returned only at that time. Updating subscriptions while keeping the same URL preserves the secret. Update your receiver after changing the URL or regenerating the secret; the current configuration retains one valid secret. Clearing the URL and saving disables callbacks and removes the secret.

Some events in the subscription catalog do not yet produce notifications. See Webhook event list for actual event availability and fields.

Request format​

ItemFormat
MethodPOST to the configured URL
Content-Typeapplication/json
x-eduskit-event-idSame as body eventId
x-eduskit-event-typeSame as body type
x-eduskit-timestampUnix seconds used to sign this delivery attempt
x-eduskit-signaturev1= followed by a 64-character hexadecimal HMAC-SHA256 digest

Example body; IDs and times are illustrative:

{
"eventId": "evt_example_created",
"type": "classroom.created",
"appId": "app_example",
"timestamp": "2026-10-09T02:00:00.000Z",
"data": {
"classroomId": "cls_example",
"name": "Math class",
"status": "pending",
"teacherEduUserId": "eu_teacher",
"fromStatus": "creating"
}
}

The body's timestamp is the event creation time in ISO 8601. The header timestamp is generated when sending the attempt and is used for the verification time window. Retries retain the same eventId and event content but generate a fresh signing timestamp. The body does not include internal trace fields.

Receive an event​

  1. Read the raw body bytes and signature headers. Verify with the application's webhookSecret. Do not parse and reserialize JSON before verification.
  2. After verification, parse JSON, check that appId belongs to the receiving endpoint, and confirm that body eventId and type match the headers.
  3. Use a database unique constraint on (appId, eventId). Persist the received event and pending work in the same transaction. A duplicate event already persisted can be acknowledged immediately.
  4. Return 200 or 204 after persistence succeeds. Execute slow work in a background job. If persistence fails, return non-2xx so delivery can be retried.

See Webhook signature verification for the algorithm and Node.js, Python, Java, Go and PHP examples. These functions verify the signature and time window. Your application supplies the HTTP route, application checks, persistence and idempotency.

Event types and fields may expand. Preserve unknown fields as needed. A verified event that your business logic does not handle can be recorded and acknowledged, avoiding repeated deliveries for an unimplemented branch.

Acknowledgment, timeout and retries​

ConditionDelivery behavior
HTTP 200–299Success; no specific response body is required
Non-2xx, network error or timeoutRetry within the current dispatch
One HTTP request10-second timeout
One dispatchUp to 3 attempts including the first; delays are 200 ms and 400 ms
All attempts failThe message is requeued and may be delivered again; 3 is not the event's total attempt limit
No URL or event not subscribedSkip delivery to the receiver

Events can arrive more than once, late or out of order. Use persistent records for deduplication. An HTTP acknowledgment confirms receipt; your system tracks background work separately. Query the Classroom API for current state to avoid overwriting it with an older event. Replay of events skipped while a URL or subscription was disabled is not guaranteed.

Troubleshooting​

SymptomCheck
No notificationCorrect application, saved URL, selected event, event actually produced, reachable HTTPS endpoint
Signature mismatchWrong appSecret, old signing secret, body changed by JSON middleware or a gateway
Time-window rejectionReceiver clock synchronization; use the header timestamp rather than event creation time
Duplicate deliveryPrevious timeout/non-2xx; deduplication and business persistence in the same transaction
Started notification before client readinessServer state changes and client IM/RTC/whiteboard readiness are separate stages

Test valid signatures, modified bodies, expired timestamps, duplicate events, timeouts and HTTP 500 responses. Record appId, eventId, type, receive time and response status for delivery troubleshooting.

Data handling​

Include received user IDs, classroom/courseware names and resource URLs in your data inventory. Limit access to stored events, redact logs and define retention for payloads and deduplication keys. See Data collection and Privacy and compliance integration.