Webhooks
How Medblocks pushes events to your server: endpoints, event types, signatures, retries, and auto-disable.
Webhooks let Medblocks notify your backend the moment something happens in Connect. A PatientFlow finishes, a refresh token stops working, a background pull settles. Your server registers an HTTPS endpoint and Medblocks delivers signed JSON payloads to it.
This page covers the model. For working receiver code, see the Webhooks section.
Endpoint
An endpoint is the URL on your server that receives deliveries. It is owned by an organization, has a public id (wh_*), and stores:
| Field | Purpose |
|---|---|
url | Your HTTPS endpoint. http://localhost is allowed only for local dev. |
events | Event-type filter. Either ["*"] (everything) or an explicit list of event types. |
status | active accepts deliveries; disabled skips them. Auto-flipped after the retry worker exhausts attempts. |
description | Optional dashboard label. |
metadata | Up to 50 arbitrary keys you control, echoed back on reads. |
api_version | API version pinned at registration. Immutable. Every event fired by this endpoint carries the same version. |
Event
An event is one delivery attempt for one fact. It has its own public id (evt_*) and travels in this envelope:
{
"id": "evt_01J9YR9N3X4VZ6P2K5RH7M3LMP",
"object": "event",
"type": "patient_flow.completed",
"api_version": "2026-04-25",
"created_at": "2026-04-25T14:35:00.000Z",
"data": { "object": { "id": "pf_...", "resource_type": "patient_flow", "..." : "..." } }
}event.type is the discriminator. event.data.object is shaped by type. The four event types are:
| Type | Fires when |
|---|---|
patient_flow.completed | A patient finishes the hosted flow (success or failure). |
connection.token_refresh_failed | A previously-active connection lost its refresh token and the patient needs to reconnect. |
records.sync.completed | A background pull finished and new records are available. |
records.sync.failed | A background pull errored and will not retry without intervention. |
Signature
Every delivery includes a Medblocks-Signature header of the form:
t=1714060800,v1=<hex>The HMAC-SHA256 v1 digest is computed over ${t}.${rawBody} with your endpoint’s signing secret. The secret is returned once when you create or rotate the endpoint. Store it server-side.
Two failure modes the signature protects against:
- Replay. The timestamp
tmust be within a tolerance window (default 5 minutes). Reject older deliveries. - Tampering. The HMAC catches any body or header modification in transit.
See Webhook Signatures for the verification implementation and the raw-body trap that frameworks fall into.
Retries
Medblocks retries delivery with exponential backoff if your receiver returns a non-2xx response or times out. Each attempt updates event.attempts, event.next_attempt_at, event.last_status_code, and event.last_response_body (truncated to 4 KB).
After the retry worker exhausts attempts on one endpoint, that endpoint is auto-flipped to disabled — no event is emitted for this transition. Detect it by polling GET /webhooks/{id} (or your dashboard). Fix the receiver, then re-enable via PATCH /webhooks/{id} with status: "active".
Manual Redelivery
POST /events/{id}/redeliver re-enqueues the same event.id for another attempt. Useful after fixing a bug in your receiver. Receivers must be idempotent: the same event.id is delivered again, so dedupe by id.
Redelivery is rate-limited to one call per minute per event.
API Version Pinning
api_version on the endpoint freezes the payload shape. When Medblocks ships a breaking change to an event payload, existing endpoints keep receiving the old shape until you opt in by creating (or updating) the endpoint at a newer version. Pin the version your receiver was written against.
Related
- Webhooks Quickstart for a working receiver.
- Webhook Events Catalog for every payload shape.
- Webhooks · Managing Endpoints for the
mb.webhooks.*SDK methods. - Register a webhook endpoint for the exact schema.
