Skip to main content

Your system doesn't have to keep asking what's changed. Practor sends a signed POST to your server within about a minute of each event you chose.

Add an endpoint

A practice owner does this in Organization settings, under Integrations: press the client to open its panel.

  1. Open the client's Webhooks tab and press Add endpoint.
  2. Enter the https address on your server under URL.
  3. Untick any event your system doesn't need.
  4. Press Add endpoint.
  5. Press Copy and store the signing secret with your receiver.
  6. Press I have stored the secret.

The secret is shown once. A client can have five endpoints.

EventSent when
invoice.issuedAn invoice is issued
invoice.status_changedAn invoice is opened for amending, cancelled, becomes overdue, or has a payment voided
claim.status_changedA claim changes status
payment.recordedA payment is recorded against an invoice, which can leave it paid
coverage.verifiedThe insurer answers a check of a patient's medical insurance, or the check fails

Each message names the invoice it's about, except coverage.verified, which names the coverage.

A client only hears about records it's allowed to read. If it loses its Claims permission, claim.status_changed stops arriving, even with the event ticked. coverage.verified needs Read on Medical insurance.

The address has to use https and reach the public internet. Practor checks it when you save and again before every message.

MessageWhat to do
Enter a full URL, starting with https://.Type the whole address, https:// included
Webhook URLs must use https.Serve your receiver over https
Webhook URLs must point at a public address.Use an address the internet can reach, not one on a private network
Put credentials in your receiver, not in the URL.Take the user name and password out of the address
... could not be found.Check the host name. It's named at the start of the message
A client can have 5 webhook endpoints. Remove one first.Remove an endpoint you no longer use

Check that a message came from Practor

Every message carries three headers, following the Standard Webhooks specification:

HeaderWhat it holds
webhook-idThe event's id. It stays the same when a message is sent again
webhook-timestampWhen this attempt was made, in seconds since 1970
webhook-signaturev1, then the signature. For a day after you replace the secret it holds two, separated by a space, one for each secret

The signature is an HMAC-SHA256, in base64, of the id, the timestamp and the raw body joined with full stops. The key is your secret with its whsec_ prefix removed, decoded from base64. Any Standard Webhooks library checks all of this for you.

Reject a message whose signature doesn't match. Ignore one with an id you've already handled, because a retry sends the same id again.

Read what changed

A message holds no patient details. It says what happened and which record to read:

{
  "id": "...",
  "type": "claim.status_changed",
  "occurredAt": "2026-10-01T08:00:00.000Z",
  "data": {
    "object": "invoice",
    "id": "i2q6w8e0r4t7y1u3o5p9a6sd",
    "url": "https://.../api/v1/invoices/i2q6w8e0r4t7y1u3o5p9a6sd"
  }
}

Each event's name in the table links to its body in the API reference. Fetch the record at url with your integration key to see its current state. Answer the message with any 2xx within 10 seconds, and do the slower work after.

Handle a receiver that's down

Any answer outside 2xx, or none within 10 seconds, is a failure. Practor doesn't follow redirects. It tries each message 8 times, starting 30 seconds apart and doubling the wait each time, so the attempts span about an hour.

Recent deliveries, on the same tab, shows each message's result:

ResultWhat it means
DeliveredYour receiver answered 2xx. The status it answered follows
WaitingThe first attempt hasn't been made yet
Retrying after ... attemptsIt failed, and Practor will try again. What your receiver answered follows
Gave up after ... attemptsEvery attempt failed, or the endpoint was switched off. The reason follows. The message won't be sent again

If every message to one endpoint fails for three days, Practor switches the endpoint off and tells the practice owners. Messages for events that happen while an endpoint is off, while its client is suspended, or while the practice has integrations switched off, are never sent. After it's back on, catch up by asking for the invoices that changed: see Bill a visit and read back what it was paid.

Test, replace or switch off an endpoint

Press Manage on the endpoint:

Each endpoint lists the events it receives. Manage opens what you can do with it.
ToPress
Send a webhook.test message now. The answer reads "Test event delivered (200)", or "Test event not delivered:" and whySend a test event
Get a new secret. The old one keeps working for 24 hours, so you have time to update your receiverReplace the signing secret
Pause messages, then start them againSwitch off, then Switch on
Delete the endpointRemove, then Remove endpoint

A test message is signed like any other, with data.message in place of a record.

Was this helpful?

Next in Security and integrations

Integration API errors and limits Find the message the Practor API sent back to see what to fix. Retry a 429, a 500 or a timeout. Every other message says what to change. 5 min read