How It Works
Webhooks let your Learning Management System (Moodle, Canvas, Docebo, custom portal) react to things that happen inside CertBoost — a user finishing a quiz, an assignment being created, etc. — without having to poll the API.
1. Register
POST a webhook URL via the API, specifying which events you want.
2. Event Fires
CertBoost builds a JSON payload, signs it with HMAC-SHA256, and POSTs it.
3. You React
Your receiver verifies the signature, then does whatever the LMS needs.
Registering a Webhook
Endpoint: POST /api/lms/v1/webhooks — Auth: any API key with ReadWrite permission.
- url (required) — HTTPS endpoint that receives POSTs
- events (required) — Array of event names, or ["*"] for every event
- description (optional) — Free-text label shown when listing
- secret (optional) — Shared secret for HMAC-SHA256 signing
Response 201 returns the created subscription with its new id.
Listing / Deleting / Testing
- GET
/api/lms/v1/webhooks— list yours - DELETE
/api/lms/v1/webhooks/{id}— remove one (204 on success) - POST
/api/lms/v1/webhooks/{id}/test— trigger a synthetic webhook.ping event
Supported Events
attempt.completed
A user finishes any quiz, simulation exam, adaptive quiz, or readiness-check diagnostic.
assignment.created
An admin creates an assignment for a user via POST /api/lms/v1/assignments.
webhook.ping
Synthetic event triggered manually by POST /webhooks/{id}/test for connectivity checks.
Future events: user.subscribed, user.unsubscribed, certificate.issued, challenge.finished, streak.broken.
Delivery Contract
CertBoost always POSTs JSON. Every delivery includes these headers and body envelope:
- Timeout: 10 seconds per request (configurable in appsettings.json)
- Retries: Fire-and-forget. One attempt is made; failed deliveries are logged but NOT re-queued in v1.
- Ordering: Best-effort, not guaranteed. Use
occurredAtfor ordering.
Payloads
attempt.completed
Typical LMS reaction: Write the percent into the course gradebook; mark a learning module complete if percent >= passing threshold.
assignment.created
Typical LMS reaction: Create a matching assignment in the LMS with the same due date. Deep-link the launchUrl so the student can jump straight into CertBoost.
webhook.ping
Signature Verification
If you supplied a secret when creating the subscription, every delivery includes:
The signature is HMAC-SHA256 of the raw request body (exact bytes, before JSON parsing) using the shared secret as the key.
Node.js (Express)
Python (Flask)
C# / ASP.NET
Best Practices
Return 2xx Fast
Reply as soon as the signature is verified; queue heavy processing.
Use signature verification
Treat unsigned payloads as untrusted. Verify with HMAC-SHA256 + timing-safe compare.
Consume idempotently
Guard by deliveryId or attemptId to avoid double-processing.
Subscribe narrowly
List only the events you actually need. Avoid wildcard subscriptions in production.
Log and alert
Log every delivery and alert if >1% fail or if no event arrives for 6 hours.
Protect the secret
Store in a vault. Rotate if leaked. Use separate secrets per environment.
Local Testing
ngrok or cloudflare tunnel -> your local webhook handler.
Your local app will receive a webhook.ping with the same signing pipeline. Verify end-to-end.