Skip to main content
Partner API webhooks tell your system when a consultation or prescription changes, so you do not have to poll. Every event is signed with the Standard Webhooks scheme, carries the complete consultation snapshot and has a version number for ordering. Verify the signature, deduplicate on webhook-id, keep the highest version, and answer with a 2xx status quickly. Last reviewed: 2026-11-04 Events follow the statuses described in Consultation lifecycle and the prescription data described in Prescriptions.

Register an endpoint

Manage endpoints in the Business portal or with the API. Scopes: webhooks:manage, plus consultations:read and prescriptions:read, because events carry full consultation and prescription data; every webhook endpoint and delivery route needs all three. Endpoints belong to one mode: test events go only to test endpoints, live events only to live endpoints. Endpoint URLs must use https on port 443, with a public host name. Redirects are not followed.

Event types

Accept event types you do not know and ignore them: new types can be added at any time.

Event envelope

The data object above is shortened. In real events data is the complete consultation resource, exactly as GET /v1/partner/consultations/{id} returns it at that version, including every prescription. Prescription events add prescription_id naming the prescription that changed.

Ordering: keep the highest version

Events can arrive late, more than once, or out of order. Prescription events in particular come from a periodic reconciliation and can arrive after a later consultation event. Do not apply events as partial updates. Instead:
  1. Read data.id (the consultation) and version.
  2. If you already stored a snapshot for that consultation with an equal or higher version, ignore the event.
  3. Otherwise replace your stored consultation wholesale with data.
Because every event carries the whole snapshot, the highest version is always the full current state, whatever order the events arrived in.

Headers

Deliveries follow the Standard Webhooks specification. Header names are case-insensitive: read them case-insensitively, as your framework normally does.

Verify the signature

Your endpoint’s signing secret looks like whsec_ followed by standard base64 (A-Z, a-z, 0-9, +, /, = padding). The HMAC key is the decoded bytes of the part after whsec_, not the secret string. The signature is the base64-encoded HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{body}, where body is the raw request body bytes: verify before parsing JSON, because re-serialising changes the bytes.
  1. Read webhook-id, webhook-timestamp and webhook-signature. Reject the request if webhook-id or webhook-signature is missing or empty, or if webhook-timestamp, trimmed, is not only the digits 0-9.
  2. Reject the request if the timestamp is more than 300 seconds away from your clock, in either direction, both counted in whole seconds (drop the fraction of your clock). Exactly 300 seconds is accepted.
  3. Decode your secret: strip whsec_ and base64-decode the rest strictly. Hi Doctor secrets decode to 32 bytes; a secret that is not valid standard base64 of 24 to 64 bytes never verifies.
  4. Compute the HMAC-SHA256 of {webhook-id}.{timestamp}. followed by the raw body, writing the timestamp as an integer without leading zeros, and base64-encode it with padding.
  5. Split webhook-signature on single spaces. In each entry, the version is the text before the first , and the signature is everything after it. Ignore entries whose version is not exactly v1 or whose signature is empty.
  6. Accept if your value equals any v1 signature, using a constant-time comparison.
Any Standard Webhooks library verifies Hi Doctor deliveries: the official standardwebhooks packages exist for Node.js, Python and other languages, and some webhook platforms ship compatible verifiers. Pass the secret with its whsec_ prefix and the raw body. The samples below implement the same steps with only the standard library.
Both samples run in this documentation’s test suite against the signature vectors exported by the Hi Doctor backend, including the rotation, non-ASCII body and Standard Webhooks specification examples, and against malformed headers and secrets.

Process events safely

The consumer below applies the three rules together: verify, dedupe on webhook-id, keep the highest version. Replace the in-memory maps with your database.

How are failed deliveries retried?

  • Answer with any 2xx status as soon as you have stored the event. Process it afterwards. Anything else, a timeout or a connection error counts as a failure. Hi Doctor waits up to 10 seconds for a response and reads at most 64 KB of it.
  • A failed delivery is retried on this schedule after the previous attempt: 1 minute, 5 minutes, 30 minutes, 2 hours, 8 hours, 24 hours, 24 hours. That is the first attempt plus 7 retries, 8 attempts in total, after which the delivery is marked exhausted.
  • The same event can be delivered more than once, for example when a delivery succeeded but the acknowledgement was lost. Deduplicate on webhook-id: it is the event id, identical on every attempt and replay. Each attempt is signed again with a fresh webhook-timestamp, so the signature changes between attempts.
  • Hi Doctor disables an endpoint automatically when 50 deliveries in a row have failed, or when it has kept failing for more than 3 days. It then emails your partner contact and shows a banner in the Business portal. Pending deliveries are kept; re-enable the endpoint once it is fixed and they resume.

Replay

POST /v1/partner/webhook-deliveries/{id}/replay resets the existing delivery for immediate delivery, with the same delivery id, event id and body: its status returns to pending, attempt_count to 0 and the retry schedule starts again. It does not create a second delivery. A pending delivery that a worker is sending at that moment is left as it is. Replaying is itself safe to repeat. Use it after fixing an endpoint, or replay from the deliveries list in the Business portal.

Secret rotation

POST /v1/partner/webhook-endpoints/{id}/rotate-secret returns a new whsec_ secret once. For the next 24 hours every delivery is signed with both secrets, newest first, so webhook-signature carries two space-separated entries:
Deploy the new secret within that window. A verifier holding either secret finds a matching entry, so nothing fails while you deploy. After 24 hours only the new secret signs.

Test events

POST /v1/partner/webhook-endpoints/{id}/test sends an endpoint.test event with a fixed sample body, signed like any other event. Use it to check your URL, TLS and signature code. To test real consultation events, use test mode.

Retention

Events and delivery records are deleted after about 30 days by a periodic cleanup. A delivery is kept longer while it was created or replayed within the last 30 days or is being sent, and an event is kept while it still has a delivery; a few older events can be kept longer. Do not rely on any record outliving 30 days: store what you need on your side. Endpoint errors, such as an invalid URL or event list, are listed in Partner API errors.

Frequently asked questions

Do I need webhooks, or can I poll?

You can read consultations by polling the consultation list, but webhooks tell you about every change without polling. Each event carries the full consultation, so one event is enough to update your records.

Why do events arrive out of order or twice?

Deliveries can be late, retried or replayed, and prescription events come from a periodic reconciliation. Deduplicate on the webhook-id header and keep the snapshot with the highest version number.

How many times is a failed delivery retried?

Up to 8 attempts in total: the first attempt plus 7 retries, spread from 1 minute to 24 hours apart. After that the delivery is marked exhausted, and you can replay it.

When is an endpoint disabled automatically?

When 50 deliveries in a row have failed, or when the endpoint has kept failing for more than 3 days. Hi Doctor emails your partner contact, and pending deliveries resume once you re-enable it.

Can I use a Standard Webhooks library to verify signatures?

Yes. Any Standard Webhooks library verifies Hi Doctor deliveries. Pass the secret with its whsec_ prefix and the raw request body.

What happens to signatures when I rotate the secret?

For 24 hours every delivery is signed with both the new and the old secret, so a verifier holding either one keeps working while you deploy.

How long are events kept?

About 30 days. Store what you need on your side.

Next steps

Test mode

Trigger real consultation events against your test endpoint.

Business portal

Manage endpoints, deliveries and replays.

Go-live checklist

What must be in place before live mode.