Professional API: Webhooks
Have your own systems told when something happens in your practice, instead of polling for it.
How Webhooks Work Here
A signed POST to an endpoint you register.
The Shape of a Delivery
You register an HTTPS endpoint in the Developer section of your professional dashboard and choose which events it should receive. When one of those events occurs, Orchard72 sends a JSON POST to your endpoint, signed with a secret unique to that endpoint.
Anything other than a 2xx response counts as a failure and is retried. A delivery attempt is abandoned if your endpoint has not responded within ten seconds.
Note
The Professional Events
The sixteen events a professional endpoint can subscribe to.
Event Slugs
appointment.created: a new appointment has been booked with your practiceappointment.rescheduled: an existing appointment has movedappointment.cancelled: an appointment has been cancelledengagement_letter.signed: a client has signed an engagement letterapproach.received: someone has approached your practice through the platformmessage.received: a new message has arrived in a conversationreferral.will_started: someone who arrived through your white-label partner page has started a willreferral.will_completed: a will started through your partner page has been signed and completedclient.created: a new client has been added to your practiceclient.withdrawn: a client has withdrawn from your practicewill.status_changed: a client’s will has moved to a new statuswill_review.requested: a client has asked for their will to be reviewedinvoice.issued: an invoice has been issued to a clientinvoice.paid: an invoice has been paidcomplaint.opened: a client has opened a complainttask.due: a matter task that is not yet done falls due today
Tip
Payloads
Identifiers and status, and nothing else.
What Is in the Body
A professional webhook payload carries the event slug, the identifier of the object that changed, named for it (for example appointment_id, client_id or invoice_id), and, where the object has one, its status. A few events add the identifier of the parent record as well: message.received carries conversation_id, task.due carries matter_id and will_review.requested carries will_id.
Client names, contact details, matter content and message bodies are never in the payload. That is deliberate: a webhook travels to an endpoint we do not control, so it carries only enough to tell you which record changed. Your receiver then fetches whatever detail it needs over the Professional API, authenticated as you and subject to the same consent rules.
Note
Headers on Every Delivery
X-Webhook-Signature: the HMAC signature described belowX-Webhook-Event: the event slug, so you can route without parsing the bodyX-Webhook-ID: a fresh identifier per delivery attempt, so it differs on every retryX-Webhook-Timestamp: the delivery time in Unix secondswebhook-id: amsg_-prefixed identifier for the event itself, which stays the same on every retry of it (Standard Webhooks)Content-Type: application/json
Verifying the Signature
Prove the delivery came from us before you act on it.
How to Verify
- Take the raw request body bytes, exactly as received. Do not parse and re-serialise the JSON first, because any reordering or whitespace change breaks the signature
- Compute an HMAC-SHA256 of those bytes using your endpoint’s signing secret as the key, and render it as a lower-case hex digest
- Compare it with the
X-Webhook-Signatureheader using a constant-time comparison, not== - Reject the delivery if they differ, and only then parse the body
Important
webhook-id values you have already processed and ignore repeats. Do not key on X-Webhook-ID: it is new on every attempt, so a retry would never match it.Retries and Failures
What happens when your endpoint is down.
The Backoff Schedule
A failed delivery is retried on a widening schedule: immediately, then after one minute, five minutes, thirty minutes, two hours, and thereafter once a day.
After ten consecutive failures the endpoint is deactivated and the account owner is emailed. Reactivate it from the Developer section once your receiver is healthy again.
Note
Building a Reliable Receiver
- Verify the signature, then acknowledge with a 2xx quickly and do the real work afterwards, because slow handlers time out and get retried
- De-duplicate on
webhook-id, which repeats on a retry, never onX-Webhook-ID, which does not - Fetch the detail you need from the Professional API rather than waiting for a richer payload
- Monitor your endpoint, because ten consecutive failures will switch it off
Related Topics
Can’t find what you’re looking for?
Our support team is here to help. Contact us and we’ll get back to you as soon as possible.
Contact Support
