How do you get real-time updates out of a FHIR server?
Polling a FHIR server for changes is wasteful and slow, and at scale it's the reason integrations fall behind. FHIR Subscriptions let a server push a notification when data matching your interest changes — the healthcare equivalent of a webhook. But subscriptions changed significantly between R4 and R5, and getting delivery reliable in a clinical setting takes more than registering an endpoint. Here's how the model works and how to build on it.
The two subscription models
R4 subscriptions are criteria-based: you register a Subscription with a search-string criteria (e.g. Observation?patient=123&code=...) and a channel, and the server notifies you when a matching resource changes. It works, but the criteria model is fragile, hard to scale on the server, and was implemented inconsistently across vendors.
R5 introduced topic-based subscriptions built around a SubscriptionTopic — a server-defined, named description of what can be subscribed to. Clients subscribe to a topic and add filters, rather than crafting arbitrary criteria. This is far more scalable and predictable, and it's the direction the ecosystem is moving. Crucially, the R5 model was backported so it can be used on R4 servers (the "R4B"/backport implementation guide), which is how many production systems adopt it today.
Channels: how notifications reach you
- rest-hook — the server POSTs to your HTTPS endpoint (the most common, webhook-style channel).
- websocket — the client holds a connection and receives notifications in real time.
- email / messaging — supported by the spec but rarely used for system integration.
For most integrations, a rest-hook to a hardened HTTPS endpoint is the right choice — but treat it like any inbound webhook: authenticate it, verify it, and never trust the payload blindly.
Payload types matter for security
Subscriptions can deliver different payload contents, and the choice has real PHI implications:
- empty — the notification says "something changed," and you fetch the data yourself over an authorized FHIR call. Most secure; no PHI in the notification.
- id-only — the notification includes resource ids to fetch. Minimal exposure.
- full-resource — the changed resource is delivered inline. Convenient but puts PHI in the delivery channel, so only over strong transport security and with care.
In clinical systems, empty or id-only plus an authorized fetch is usually the right default — it keeps PHI out of webhook logs and intermediaries.
Building for reliability
- Assume at-least-once delivery: notifications can be duplicated or retried, so make your handler idempotent.
- Assume notifications can be missed (endpoint down, network): keep a reconciliation path that periodically catches up via search, so a dropped notification doesn't mean lost data.
- Return quickly from the webhook and process asynchronously; slow handlers cause server-side retries and back-pressure.
- Monitor subscription health — servers can deactivate a subscription after repeated delivery failures.
When to use subscriptions
Subscriptions shine for event-driven workflows: a new lab result triggering a care-team alert, an ADT event updating a dashboard, a new document kicking off processing. They replace polling for freshness-sensitive use cases. For bulk or periodic data movement, FHIR Bulk Data ($export) is the better tool — subscriptions are for reacting to change, not moving volume.


