Push events to your own systems with webhooks
Register an HTTPS endpoint, choose the events, and receive them the moment they happen.
An event, delivered
Diagram: An event, delivered. Steps:
- Something happens (enrolment confirmed, payment received…)
- Event written
- POST to your https endpoint
- Retried on failure
- Delivery recorded
Connections:
- Something happens (enrolment confirmed, payment received…) → Event written
- Event written → POST to your https endpoint
- POST to your https endpoint → Retried on failure
- Retried on failure → Delivery recorded
- Open Administration → Settings → Webhooks and select Add an endpoint.
- Enter a name and the URL. It must be
https— events carry learner identifiers. - Tick the events you want, or select none to receive every event including ones added later.
- Select Add endpoint. Deliveries and their responses are recorded against the endpoint.
The events
| Event | Fires when |
|---|---|
enquiry.created | A new enquiry was raised, whether typed by staff or posted to the API. |
application.stage_changed | An application moved to a different pipeline stage. |
enrolment.confirmed | A learner was enrolled in a programme. |
learner.status_changed | A learner's status changed. |
submission.created | A learner submitted work for an assessment. |
invoice.issued | An invoice was issued to a learner. |
payment.received | A payment was recorded against an invoice. |
That is the whole catalogue today. Events are added to it rather than invented per subscription, so an endpoint subscribed to everything keeps working as the list grows.
Verify a delivery
Every request carries a signature over the timestamp and the raw body, keyed by the subscription secret shown once when you create the endpoint:
X-Pallara-Signature: t=1755500000,v1=<hex hmac-sha256>
Recompute HMAC-SHA256(secret, "<t>.<raw body>") and compare in constant time. Reject a delivery whose timestamp is outside your tolerance window — that is what stops a captured request being replayed at you later.
A failed delivery is retried six times with exponential backoff. A 4xx is treated as understood and refused, and is not retried — retrying a request the receiver has rejected is noise, not resilience. Return 2xx quickly and do your work asynchronously.
