Skip to content

Webhooks API

Auth: API key. Scopes: webhooks:read / webhooks:write (management). Inbound delivery is authenticated by an HMAC signature, using the endpoint secret as the signing key, not by an API key.

Base path: /v1/webhooks

A webhook endpoint is a MedFlow-issued inbound URL plus a secret for pushing data into your workspace. Manage endpoints with the routes below. Partners deliver data to it, and MedFlow raises any events from that data on its own. For how webhooks fit together, see the Webhooks guide.


POST /v1/webhooks

bash
curl -X POST "https://api-staging.medflow.care/v1/webhooks" \
  -H "Authorization: Bearer $MEDFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Athena data feed",
    "active": true
  }'
FieldRequiredDescription
nameYesDisplay name for the endpoint
activeNoDefault true. Whether the endpoint accepts deliveries

Response 201. The secret is the signing key for delivery signatures. It is returned once, at creation, and never shown again, so store it securely.

json
{
  "webhookId": "<uuid>",
  "name": "<string>",
  "url": "<string>",
  "active": <boolean>,
  "secret": "<string>",
  "createdAt": "<ISO 8601>",
  "updatedAt": "<ISO 8601>"
}

GET /v1/webhooks

bash
curl "https://api-staging.medflow.care/v1/webhooks" \
  -H "Authorization: Bearer $MEDFLOW_API_KEY"

Returns an array of endpoints. The secret is omitted from list and get responses.


GET /v1/webhooks/:webhookId

bash
curl "https://api-staging.medflow.care/v1/webhooks/WEBHOOK_ID" \
  -H "Authorization: Bearer $MEDFLOW_API_KEY"

PATCH /v1/webhooks/:webhookId

Partial update of name or active. To rotate the secret without changing the URL, ask through Request access.

bash
curl -X PATCH "https://api-staging.medflow.care/v1/webhooks/WEBHOOK_ID" \
  -H "Authorization: Bearer $MEDFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "active": false }'

DELETE /v1/webhooks/:webhookId

Response 204. Deliveries to a deleted endpoint are rejected.


POST /v1/webhooks/:webhookId

An external system POSTs data to the endpoint: a JSON object or a FHIR R4 bundle. MedFlow accepts the delivery and ingests it for search, then works asynchronously: it raises any events the data maps to and starts the bound pathways. The response confirms acceptance, not a run, so there is no runId here.

Every delivery must be signed with the endpoint secret. MedFlow rejects an unsigned or invalid request with 401, so send the signature in the X-MedFlow-Signature header on each call (see Signing deliveries).

Also send an Idempotency-Key so retries are safe and so you can trace the delivery. MedFlow tags every run it starts from the delivery with that key, and you list them with GET /v1/runs?idempotencyKey=… (see Runs).

bash
curl -X POST "https://api-staging.medflow.care/v1/webhooks/WEBHOOK_ID" \
  -H "X-MedFlow-Signature: t=1784764800,v1=<hmac-sha256 hex>" \
  -H "Idempotency-Key: order-2481" \
  -H "Content-Type: application/json" \
  -d '{
    "resourceType": "Patient",
    "bundle": {}
  }'

You do not name an event in the request. MedFlow raises the event, if any, from the data itself, and the workspace’s event triggers act on it. Most deliveries simply keep search current.

Response 202 confirms the delivery was accepted for processing.

json
{
  "accepted": <integer>,
  "idempotencyKey": "<string> | null"
}

MedFlow verifies every inbound delivery with an HMAC-SHA256 signature. The endpoint secret returned at creation is the signing key, and it never travels on the request.

To sign a delivery:

  1. Take the raw request body and the current Unix time t in seconds.
  2. Compute v1 = HMAC-SHA256(secret, "{t}.{body}") as lowercase hex.
  3. Send X-MedFlow-Signature: t=<t>,v1=<v1>.

MedFlow recomputes the signature and rejects the delivery with 401 if it does not match, or if t is outside a five-minute window (replay protection). Rotate the signing secret without changing the URL through Request access.

If a system genuinely cannot sign, a bearer-secret fallback can be arranged for that endpoint at creation. Signing is the default and the preferred path.