4 min read

Webhooks

ArkCloud Health can send signed events to an HTTPS endpoint your organisation registers. It is built, experimental, and switched off on the hosted service today. This page also lists the inbound receivers, which accept events from specific providers.

Outbound webhooksAvailable with configuration

Built and switched off on the hosted service. When on, ArkCloud sends signed event notices (identifiers and statuses, not patient details or note text) to an HTTPS address your administrator registers and verifies, with retries and a delivery log. Never yet run against a customer's receiver.

Requires: ArkCloud switches the API on for the deployment, then your administrator enables webhooks and verifies an endpoint.

Outbound webhooks (experimental)

An administrator registers an HTTPS endpoint in Settings → API & Integrations → Webhooks, chooses events, and verifies it with a signed ping. Events (visits booked and completed, notes signed, charges posted, claims created and submitted, remittances posted, eligibility results, payments, denials) are signed with HMAC-SHA256, retried with growing delays, and recorded in a delivery history. They carry identifiers and statuses, never names, dates of birth or note text.

Delivery runs only when the deployment operator has enabled the API and your organisation has switched webhooks on. It has not yet been exercised against a customer's own receiver in production. The event list, payload fields and verification code are in the API reference; questions to [email protected].

Two things in the product use the word "webhook" and are not this feature: the background-worker alert URL (WORKER_ALERT_WEBHOOK), which notifies the operator of this deployment when a job fails, and an unsigned webhook action in the workflow engine whose trigger nothing currently calls. Neither uses the signing or delivery described above.

Inbound webhook receivers

Each receiver refuses events it cannot authenticate, and does nothing until its provider is set up to send to it. The Stripe, Amazon Connect and Twilio receivers are configured by whoever operates the deployment (environment variables or the provider's own dashboard); the EHR and referral-push receivers use a secret held on one organisation's connection.

Stripe

POST /api/webhooks/stripe

Authentication: Stripe-Signature header verified with the Stripe SDK (constructEvent) against STRIPE_WEBHOOK_SECRET, or STRIPE_CONNECT_WEBHOOK_SECRET for events from connected accounts. Answers 500 when the Stripe key or secret is not set, so nothing is accepted unverified.

Handles: payment_intent.succeeded / payment_failed, charge.refunded, refund.updated / refund.failed, charge.refund.updated, charge.dispute.created / updated / funds_withdrawn / funds_reinstated / closed, setup_intent.succeeded, account.updated, checkout.session.completed, customer.subscription.created / updated / deleted, invoice.paid / payment_failed. Each event id is recorded, so a replayed event is answered without being applied twice; a processing failure is answered 500 so that Stripe retries it.

app/api/webhooks/stripe/route.ts

Amazon Connect contact events

POST /api/webhooks/connect

Authentication: HMAC-SHA256 of the raw body in an x-signature header, keyed with the deployment environment variable CONNECT_WEBHOOK_SECRET. Answers 503 when that variable is unset. The tenant is resolved from the instance ARN. Replays are refused: each event id is recorded once, and an event whose time is more than 24 hours old or more than 5 minutes in the future is rejected. Amazon EventBridge does not sign events this way, so an intermediary you operate (for example API Gateway with a Lambda) must add the signature; none is provided.

Handles: INITIATED, CONNECTED_TO_AGENT, DISCONNECTED and CONTACT_FLOW_EVENT contact events, recorded as call interactions.

app/api/webhooks/connect/route.ts

EHR events (per connection)

POST /api/ehr/webhooks?connectionId=…

Authentication: HMAC-SHA256 of the raw body, compared with an X-Hub-Signature-256 / X-Hub-Signature / X-Signature / X-Epic-Signature header, keyed with the connection's own webhook secret. Events are refused when the connection has no secret, and no screen sets one today, so in practice this receiver accepts nothing.

Handles: Patient, encounter, appointment and charge events for an EHR sync connection. EHR sync is not available, and the Rehab outside-records and referral-exchange connections do not use this receiver; see the EHR pages.

app/api/ehr/webhooks/route.ts

Twilio inbound SMS (STOP replies)

POST /api/webhooks/twilio-sms

Authentication: X-Twilio-Signature verified with the Twilio SDK against the Twilio auth token (the deployment environment, or a value saved on the back-office Credentials page). Answers 503 when no token is set and 403 when the signature is missing or wrong.

Handles: Replies to ArkCloud texts. STOP and the other carrier-standard opt-out keywords withdraw the patient's SMS consent; START or UNSTOP do not restore it. Works only once the Twilio number's incoming-message webhook points here.

app/api/webhooks/twilio-sms/route.ts

FHIR referral push (Rehab referral exchange, per connection)

POST /api/integrations/referral-exchange/<connectionId>/inbound

Authentication: X-ArkCloud-Timestamp and X-ArkCloud-Signature: sha256=<HMAC-SHA256 of "<timestamp>.<raw body>">, keyed with the connection's own push secret, which a Rehab administrator sets. Timestamps more than 5 minutes off are refused; bodies over 5 MB get 413.

Handles: One FHIR R4 Bundle carrying a referral from a referring partner. 202 imported or held for review, 200 duplicate, 401 signature, 404 unknown or disabled connection, 422 failed validation (kept for staff review), 503 retry later. Tested only against a simulated partner.

app/api/integrations/referral-exchange/[connectionId]/inbound/route.ts; lib/ehr/referral-exchange/push-auth.ts

Twilio call-recording callback

POST /api/connect/recording-callback

Authentication: X-Twilio-Signature verified with the Twilio SDK against the Twilio auth token: the one saved on the back-office Credentials page, else the one set for the service (the same source as the SMS webhook). Answers 503 when neither is set.

Handles: Recording-status callbacks from Twilio. The voice call paths that would produce recordings are not usable today; see the Twilio page.

app/api/connect/recording-callback/route.ts

Need events in another system?

If the events above do not cover it, tell us what has to flow and where. We will say plainly whether it can be done today.

Custom integrations