Webhook events
Prerequisites: the Webhooks option on your account and a declared endpoint. Authentication, signing and retries are covered in Configuring a webhook; this page describes only what the calls contain.
Webhook events
Prerequisites: the Webhooks option on your account and a declared endpoint. Authentication, signing and retries are covered in Configuring a webhook; this page describes only what the calls contain.
What is emitted
One event actually reaches your endpoint: certificate_completed, sent when a certificate award is
recorded.
The form offers a second one, certificate_expired. Nothing in the platform ever emits it: expiry is
sent under the certificate_completed name instead, as described below. In the back office, the
Event Types section shows both as selectable chips, certificate completed and certificate
expired; selecting the second alone means your endpoint never receives anything, with no error and
no warning.
⚠️ Subscribe to certificate_completed, whichever case you care about. An endpoint subscribed
only to certificate_expired is silent, including when a certificate expires.
The three paths that trigger certificate_completed
A learner meets a certificate rule. The common case, in real time, as soon as their activity satisfies the rule. Only certificate rules emit: gamification badges trigger no call.
A certificate passes its expiry date. An hourly pass picks up expired awards and sends the reminder email, then emits a call. Three conditions must all hold: the certificate is a per-capsule certificate, it has a validity duration, and its expiry reminder is switched on. A per-skill certificate never produces this call. Once per award only: the award is flagged as reminded and never comes round again.
Beedeez runs a catch-up pass on a certificate, to award what is missing to eligible learners. One call per award created.
What the call contains
The body is the certificate award itself, as JSON, with no envelope: no event name, no emission timestamp, no delivery identifier. The fields always present:
| Field | Type | Contents |
|---|---|---|
_id | identifier | The award; stable, usable as an idempotency key |
_userId, _badgeId, _ownerId | identifiers | The learner, the certificate, the account |
name, description | text | The certificate labels |
name_i18n, description_i18n | list | Translations, shaped as { lang, value } |
ruleType | text | certifCapsule or certifSkill |
creationDate | date | When it was earned |
expires | date | Absent when the certificate has no validity duration |
expiryReminderSent | boolean | true on the call triggered by expiry |
disabled | boolean | true if the award is superseded or already expired |
acknowledged | boolean | The learner has seen the certificate in the app |
createdAt, updatedAt | dates | Database write times |
Four fields appear only when the rule produced them: score, successRate, correctAnswersRate,
and _lessonActiveIds, which lists the capsules that validated the certificate.
{
"_id": "6712a9f4c3b5e10d2f8a4471",
"_ownerId": "5f2c1ab8d9e4470012a3c001",
"_userId": "66e1b0447a2c9d0011f4e882",
"_badgeId": "64c73f10ae5b220019d0a1c7",
"name": "Electrical authorisation B1V",
"ruleType": "certifCapsule",
"creationDate": "2026-03-11T09:42:18.204Z",
"expires": "2027-03-11T00:00:00.000Z",
"expiryReminderSent": false,
"disabled": false,
"acknowledged": false,
"successRate": 92,
"_lessonActiveIds": ["66f0d2213b8c4a0014ee7710"],
"createdAt": "2026-03-11T09:42:18.209Z",
"updatedAt": "2026-03-11T09:42:18.209Z"
}Answer within five seconds
Beedeez waits 5 seconds for your response, whatever timeout you set on the endpoint, and treats anything else as a failure. Nothing replays a failed call, so acknowledge the request first and do your own processing afterwards rather than holding the connection open.
Volume
One call per award, per subscribed endpoint, with no batching: ten learners certified on the same day produce ten calls to each endpoint, and a catch-up pass on a certificate a thousand learners have earned produces a thousand, in one burst.
What it does not do
The body carries no identity data: no name, no email address, no employee number, no group
membership. _userId is an internal identifier, so writing into an HRIS requires an API call to
resolve the learner. And no event exists for learners, capsules, tracks or sessions.
The trap
Expiry arrives under the name certificate_completed. An endpoint subscribed to
certificate_completed therefore receives both cases, award and expiry, with the same body.
💡 To tell them apart, read expiryReminderSent: true on the expiry call, false on the award.
Comparing expires against the current time confirms it.
Going further
- Configuring a webhook: authentication, signing and what happens on failure
- Validity, expiry and renewal: the expiry reminder that drives the second path
- API resources: the API that turns
_userIdinto a real learner - Automating activity export to your SFTP: the route for everything no event covers