10.3.1.1 | TTA Notifications (v0.6)

10.3.1.1 | TTA Notifications

Version: 0.6

Table of Contents

Introduction

This Technical Agreement (TA) describes and specifies the technical responsibilities to which parties agree when connecting to exchange transactions to facilitate notifications.

Notifications are a useful mechanism to support the information requirements of the receiver. It enables doctors, patients or system users to become aware of new data and changes in existing data as soon as they are registered.

This specification describes how organizations in Dutch healthcare exchange such notifications in a consistent and secure manner, defining the functional principles and the technical choices required for interoperable, implementable notification exchange. As a technical foundation, we use the FHIR R5 Subscription Framework, applied in FHIR R4 and R4B via the Subscriptions R5 Backport Implementation Guide (IG).

This TA thus applies to either FHIR R4 or FHIR R4B. This version choice concerns only the subscription and notification framework itself; it does not require the resources a notification relates to (referenced via notification-event.focus) to conform to the same FHIR version. Furthermore, R4 and R4B MUST NOT be used interchangeably within a single notification relationship, as the notification resources differ between the two. A Subscription Server and Subscription Client that agree to exchange notifications MUST therefore agree on, and consistently use, the same FHIR version for the subscription and notification resources involved in that exchange.

Context

The initial reason for drawing up this generic technical agreement is the need for a FHIR specification for the exchange of the BgZ (Basisgegevensset Zorg) between healthcare organizations in the context of a referral. The actual agreements for the exchange of the BgZ are provided in the BgZ attachment. The exchange of the BgZ is not the first use-case that requires a FHIR specification for the exchange of a set of FHIR resources between healthcare organizations in the context of a transfer of care. The eOverdracht information standard and corresponding TA cover a similar use-case and already provide a specification for the exchange of FHIR resources using a Notified Pull pattern. As such, the relevant specifications in the eOverdracht information standard and TA have served as a basis for this document. At some points this document deviates from the eOverdracht information standard and TA (most specifically in the exchange of the notification). Where it deviates, it does not aim to replace the existing version of the eOverdracht standards and corresponding implementations. It rather aims to provide a direction for the next iteration of the eOverdracht information standard and TA.

The scope of this TA however is not limited to these use cases. It sets guidelines for the use and specification of notifications in other existing and future exchange agreement, including those required by EHDS.

Scope

In scope:

  • The exchange of notifications between healthcare provider organisations, including the payload mode used (see Notification Payload Model).

  • The selection and coding of notification topics (SubscriptionTopic).

  • The relationship with addressing (GF Addressing), authorization (GF Authorization), and patient consent (GF Toestemming/EHDS), without elaborating a specific addressing profile.

Exclusions (out of scope):

  • Cancellation of FHIR notifications is not supported. FHIR notifications are stateless.

  • Authentication and identification of the actors involved in the agreement (see TA I&A).

  • The substantive pull that may follow a notification, where the notification itself does not carry the content (see TA Pull).

  • The technical method by which consent is verified (see GF Toestemming and forthcoming EHDS regulation).

  • The concrete registration, publication, and resolution of notification endpoints (see GF Addressing).

  • Notifications that do not concern patient-related healthcare data exchange. The technical notification framework described in this TA may be used for these kind of notifications, but the patient-specific authorization, consent, privacy, and related governance requirements described herein do not apply.

Vocabulary

This TA uses several terms that carry a specific, technical meaning in FHIR distinct from their everyday English meaning. This section defines the terms this TA is built on.

  • Notification — as used in this TA, a general term for the notification payload sent from the Subscription Server to the Subscription Client when an event occurs. A notification is not a FHIR Resource type. Mechanically, a notification is a FHIR Bundle (type history for R4/R4B, per the Backport IG), whose first entry is a SubscriptionStatus (represented as a Parameters resource in the R4/R4B Backport). See Resource Definitions.

  • Subscription — a FHIR Resource representing a client's registered request to be notified about a SubscriptionTopic, constrained for R4/R4B use by the Backport IG. Every notification is linked to an actual, registered Subscription resource; the Backport IG does not support implicit Subscriptions.

  • SubscriptionTopic — a FHIR Resource, introduced in FHIR R4B, defining the class of event a Subscription can register for: which resource type and interactions trigger it, and what a Subscription is allowed to filter on. SubscriptionTopics are defined in accordance with the FHIR R4B standard, and Subscriptions in accordance with the R4/R4B backport (there is no difference between R4 and R4B). SubscriptionTopics SHOULD be able to be communicated out-of-band. The practical consequence of the choice for version R4B is that a SubscriptionTopic can consist of only one FHIR resource type, and a SubscriptionTopic in FHIR R4B defines triggers and filters for a single resource type.

  • notification-event.focus — the reference the Subscription Server places in a notification Bundle to identify the resource that triggered that specific event, i.e. the resource type the SubscriptionTopic monitors (see SubscriptionTopic). See Notification Payload Model for how this reference is used in id-only mode.

  • canonical — a URL used as a stable, versionable identifier for a FHIR definitional resource (such as a SubscriptionTopic), as opposed to a normal resource reference, which points at a specific instance on a specific server.

  • criteria — the Subscription.criteria element, which in the R4/R4B backport carries the canonical URL of the SubscriptionTopic a Subscription is bound to (via the backport-topic-canonical extension), not a free-text filter expression. Free-text-style scoping filters use the separate backport-filter-criteria extension instead.

Notification Payload Model

The payload mode determines what data travels inside the notification Bundle versus what must be retrieved later via a follow-up pull. Payload modes are requested per Subscription and may be accepted, modified, or rejected by the Subscription Server. Existing exchange agreements (e.g., Referral or Transfer standards) may also pre-define or restrict which modes are permissible for specific SubscriptionTopics.

Payload Mode

backport-payload-content Extension

Description

Empty

empty

Contains no identifying metadata or clinical data. The Bundle merely signals that a matching event occurred for the Subscription.

Id-only

id-only

Contains a reference to the affected resource (notification-event.focus) but no clinical content.

Full-resource

full-resource

Contains the complete FHIR resource instance itself.

Full-resource mode does not participate in the Notified Pull pattern described below: there is no separate pull, no gap between notification and access. The notification is atomic — it carries the resource content itself, so sending it is the disclosure, not a precursor to one.

Sending a notification does not exempt the sender from the authorization and consent obligations that would otherwise apply to disclosing that same clinical content (see Privacy, Consent, and Authorization): a full-resource notification carries those obligations just as any other disclosure of the content would, and typically carries more of them than an id-only notification, since the content itself — not just a reference to it — leaves the sender's system. When full-resource mode is selected, the applicable consent and authorization basis must cover the direct disclosure of that clinical content to the receiver, and that basis must be verified and in place at the exact moment the notification is sent.

Payload Selection for the Notified Pull Pattern

In a Notified Pull exchange, the notification is sent before the receiving party has agreed to, or established the basis for, the exchange of the underlying data. At that stage, the payload is limited to what is strictly necessary. Therefore, the id-only and empty payload modes are specifically intended for this pattern.

When implementing Notified Pull, a decision must be made regarding which mode to use: id-only provides a direct reference to the affected resource to facilitate efficient retrieval, whereas empty conveys no identifying information.

Parties Exposed by an Id-Only Notification

An id-only notification puts the resource reference in front of more parties than just the intended, authorized receiver. Three of them matter here:

  • The addressed but unauthorized recipient. The receiver of the notification itself may not yet have any right to the content — the notification arrives before access has been granted or established, so at that moment it only knows a resource exists and where.

  • The observer. Anything the notification passes through — message brokers, proxies, logs, backups — stores or forwards the reference too, typically for longer than the exchange itself lasts and to people who were never party to it.

  • Linked parties. Two or more parties who each separately receive identifiers legitimately can compare notes: an identifier that means nothing to either one alone can let them link the same resource across their separate views, something neither could do on their own.

If the identifier itself gives nothing away, none of these three parties learns anything — that is the point of the requirements below. But the sending organisation has no way to control this through access rules of its own: all three kinds of exposure happen in systems it doesn't operate — the receiver's inbox, the observer's logs, another party's records. The only lever it has is how the identifier is constructed before it is sent. That is why the conditions that follow are fixed requirements on every identifier leaving a source system, not something each implementer weighs case by case.

Requirements for Using Id-Only

An identifier may be used as the reference in an id-only notification only if it satisfies the following requirements:

  1. Stability — a source SHALL return the same identifier for the same resource on every request.

  2. Opacity — a resource identifier SHALL NOT reveal creation order, volume, creation time, or content.

  3. Unpredictability — a resource identifier SHALL NOT be guessable, and SHALL NOT be computable or confirmable from real-world entity identifiers (a BSN, a patient number) by anyone who does not hold a secret of the source.

  4. Consumer opacity — a consumer SHALL treat received identifiers as opaque strings: it SHALL NOT parse them, derive meaning from them, or assume a format when querying, however carefully the identifier was constructed on the sending side.

An identifier that fails the opacity or unpredictability requirement leaks something about the resource to anyone who merely sees the notification, whether or not that party is ever granted access to the resource itself — which is exactly what disqualifies it from id-only use.

When a Reference Is Preferable to Empty

For a single-receiver resource whose identifier meets the requirements above, id-only SHOULD be used in preference to empty — that is the central rule this section argues for; broadly accessible resources are the exception, addressed at the end of this section.

Some resources are addressed to a single receiver: a Task assigned to one care organisation, for example, where exactly one authorized party ever receives a notification about that resource. Others are broadly accessible: an Observation or a Patient record may be shared with many parties over time, each receiving their own notification referencing the same resource. What follows argues the rule above for the single-receiver case.

A receiver fetches a resource from its source using the identifier that names it. When the notification carries that id, the receiver knows exactly which resource is meant and can fetch it directly, without searching for a candidate match.

Choosing empty to avoid disclosure through the identifier does not avoid disclosure — it moves it elsewhere. Without a reference, the receiver must locate the resource by searching instead of fetching it directly, and a search response can contain more resources than the one the notification actually concerned. A reference that meets the opacity and unpredictability requirements, retrieved by direct read, discloses exactly one resource and nothing else; a search, by contrast, can expose a broader set of resources than the notification ever intended to point to.

Within Notified Pull, the notification's reference SHOULD accordingly be sent by URL rather than withheld for single-receiver resources. Empty remains the right choice only where the identifier cannot meet the requirements above in the first place.

For broadly accessible resources, meeting the requirements is not sufficient on its own: the same reference value reaches every recipient, which gives linked parties material to cross-reference across their separate views of the same resource — something a single-receiver notification does not expose. Whether id-only remains appropriate for such resources, or whether per-recipient identifiers or empty mode should be used instead, is a decision for the information standard governing that exchange, not a default this document can set.

Empty Mode with a Leaked Id Is Pseudo Id-Only

The empty mode's distinguishing security property is precisely that it carries no identifier at all. If an implementer nonetheless exposes the resource id through another channel available to the receiver — for instance in a header or a token accompanying the notification — the opacity and unpredictability requirements are defeated in substance even though the payload mode is still labeled empty. Notifications built this way no longer deliver the protection the empty mode is meant to provide; functionally, they are pseudo id-only notifications: they carry the same disclosure id-only mode would, without meeting the requirements above and without being declared or governed as id-only under the agreed payload mode.

Schemes That Fail

Several identifier constructions are known to fail the stability, opacity, or unpredictability requirements stated above, and should not be used as the reference in an id-only notification. This list is illustrative, not exhaustive — other constructions can fail the same requirements; any identifier should be checked against the requirements themselves, not just against this list.

  • Ordered identifiers (sequential counters) — reveal creation order and volume, are guessable, and let a reader infer that a resource exists between two identifiers it has seen. Fails the opacity and unpredictability requirements.

  • Time-encoding identifiers (UUIDv1, UUIDv7) — reveal the moment of creation. Fails the opacity requirement.

  • Concatenated identifiers (e.g., department plus patient number plus date) — reveal content directly. Fails the opacity requirement.

  • Derived identifiers (an unkeyed hash of sensitive input; UUIDv5 is in this class) — reveal content to anyone who can brute-force the input space, such as the space of patient numbers. Fails the unpredictability requirement.

  • Low-entropy identifiers — guessable. An attacker with an overbroad or forged token can probe candidates, and operational mistakes silently hit valid resources; entropy is a layer of defense for the moment access control fails. Fails the unpredictability requirement.

  • Volatile identifiers (freshly generated per request) — opaque but not stable; they break lookup and deduplication for every receiver downstream. Fails the stability requirement.

A resource referenced only by an identifier from one of these failing schemes should be exchanged under empty mode within the Notified Pull pattern, not id-only.

Identifier Examples

Random, Keyed transformation, and Per-recipient are three constructions that satisfy the stability, opacity, and unpredictability requirements, each identifying the same internal resource, key 4711 in the source system's database — the values are illustrative. See Event Notification for the identifier from the Random example carried in an actual notification.

Constructing an Id: Random (UUIDv4)

A randomly generated value, created once and stored with the resource. Because it's random rather than derived from anything, it reveals nothing about the resource's creation order, timing, or content.

Resulting id: 5f2f9a4e-8c1d-4b6e-9d3a-7c0e2f4b8a1d

Constructing an Id: Keyed Transformation (HMAC)

A value computed from the resource's internal reference using a keyed cryptographic transformation. The same resource always produces the same identifier, but the identifier can't be reversed or predicted without the source's secret key.

Source value: Task/4711 Resulting id: j5xw6z3vnfxgk4ttmvwgc3dj

Constructing an Id: Per-Recipient

A variant of the keyed transformation above, where the key itself is derived per receiver. Each receiver ends up with a different identifier for the same resource, so receivers can't link it across their separate views — the tradeoff is that only the source can tell the two identifiers refer to the same resource.

Source values: Task/4711 + URA 12104037 (receiver A) Resulting id (receiver A): k2mdpq7fbzxtc4qslmvwgy3e

Source values: Task/4711 + URA 54783291 (receiver B) Resulting id (receiver B): r8ntgh5xowzslb9cqfj47x2n

Payload Mode Agreement and Enforcement

Payload modes SHALL be explicitly defined within the governing exchange agreement before a subscription is created. Systems SHALL NOT accept arbitrary subscription requests — only subscriptions and payload modes that have been formally agreed upon. Agreements on SubscriptionTopics SHOULD explicitly specify payload modes, though a single topic MAY permit more than one.

The payload mode is locked at the moment of subscription creation and SHALL only be changed through an explicit PATCH operation; every notification sent afterward SHALL adhere to the registered mode. How the mode gets set depends on who creates the subscription:

  • In-band creation. The receiver creates the Subscription resource and specifies the payload mode via the content field extension; if left empty, empty mode is assumed. The receiver SHALL only specify a mode pre-approved in the exchange agreement, and the sender is bound to that mode once it accepts. Senders SHALL NOT accept subscriptions requesting a mode outside the agreement.

  • Out-of-band creation. The sender creates the Subscription resource and specifies the payload mode in the content field, then sends a handshake notification to verify the channel is reachable. The receiver MAY inspect the payload mode by fetching the Subscription resource, but that check is not part of the handshake itself, and acknowledging the handshake does not constitute agreement on the payload mode. If the requested mode falls outside the exchange agreement, the receiver SHALL reject the handshake, or refuse to acknowledge it. Even after a successful handshake, the receiver retains the right to reject any later notification that deviates from the agreed payload mode.

Notification Patterns

The Notified Pull exchange pattern applies to different models of medical record exchange.

Source Initiated Notifications

In a source initiated notification pattern, the sending healthcare provider determines that another healthcare provider, the receiving provider, should be informed when specific events occur, even though the receiving provider did not explicitly request this. The sending organisation establishes and manages the notification relationship and sends notifications when relevant events occur.

Examples include referral or transfer updates and a specialist making a new consultation report available in the patient's record.

Receiver Initiated Notifications

In a receiver initiated notification pattern, the receiving healthcare provider explicitly requests to be informed when specific events occur. The receiving organisation initiates the notification relationship and the sending organisation delivers notifications when relevant events occur.

Examples include laboratory result notifications and notification of changes to specific patient information.

Quality and Privacy Considerations

Signal Fatigue and Specificity

A notification is an external trigger that can disrupt the receiver's ongoing work, so how it is scoped and delivered matters. The immediate receiver of a notification is the Subscription Client — a system, not a person — which may in turn direct it to a human, such as a healthcare professional's worklist or inbox. Signal fatigue can occur at either point: a system flooded with low-value notifications burns processing capacity and complicates prioritization, and a person flooded with low-value notifications starts to ignore them altogether, including the ones that matter. Too few notifications carries the opposite risk and can harm patient care. A SubscriptionTopic SHOULD therefore be scoped narrowly enough that the notifications it produces are relevant to the process they concern.

Great care SHOULD therefore be given to the specificity of notifications.

Privacy, Consent, and Authorization

Consent and authorization address different aspects of deciding whether data may be exchanged and are established through different mechanisms. Consent is the patient's permission for their data to be exchanged for a given purpose. Authorization determines whether all applicable conditions for exchanging data are satisfied, including both the patient's consent (where required) and whether a specific receiving party is entitled to receive notifications for a given SubscriptionTopic and a specific patient. This TA delegates these determinations to GF Authorization and GF Patient Consent rather than defining them. A Subscription MUST NOT be activated, and a notification MUST NOT be sent, unless all applicable authorization and consent conditions are satisfied.

Both payload modes require consent and authorization to have been established, but what they must cover differs (see Notification Payload Model):

  • Empty / id-only notifications carry no clinical content, but are not privacy-neutral: the fact that a resource of a given type changed, tied to a specific patient (via the Subscription) and that care relationships exist between patient and sender and patient and receiver, is itself a thin disclosure about that patient's record. This is the baseline privacy footprint of any notification under this TA. The Subscription Server MUST NOT activate a Subscription until patient consent has been verified (see Preconditions).

  • Full-resource notifications carry clinical content directly and are subject to the same consent and authorization requirements as any other disclosure of that content — equivalent to a Push of the data itself. The exchange agreement selecting full-resource for a topic MUST establish that the applicable consent basis covers disclosure of that content to the receiver, not merely disclosure of the fact that it exists, and that basis MUST already be established at the moment a notification is sent — not deferred to a later point, since full-resource mode has no separate content-access step to defer it to.

In both cases, the Subscription Server MUST verify authorization and consent before a notification is sent (see Implementation Obligations).

Preconditions

This TA sets the following rules for the use of notifications and Subscriptions:

  • All notifications and subscriptions (in-band and out-of-band) that are accepted MUST be well-defined by SubscriptionTopics agreed upon between all parties involved (binding to a topic canonical is required by R4B; the requirement that parties mutually agree the topic beforehand is added by this TA).

  • All consent requirements specified by GF Toestemming/EHDS for the type of information disclosure associated with the Subscription's payload mode MUST be satisfied before a Subscription is activated (see Privacy, Consent, and Authorization).

  • The receiver's authorization to access the SubscriptionTopic for a specific patient MUST be established via GF Authorization before a Subscription is activated (see Privacy, Consent, and Authorization).

  • All endpoints MUST adhere to network Twiin security level standards: 10.4.7 | Network level security. Mutual TLS MUST be applied.

FHIR Technical Specification

Conformance

Implementations MUST conform to the HL7® FHIR® R4/R4B Subscriptions R5 Backport Implementation Guide. This TA repeats selected implementer obligations from that guide so that the required behavior can be understood without a detailed study of the Backport specification.

Sequence Diagram

The diagram below illustrates the technical flow of the Notified Pull notification pattern between the Subscription Client (receiving organisation) and the Subscription Server (sending organisation): subscription registration, handshake, recurring event/heartbeat notifications, and catch-up after a disruption. The actual content retrieval (the pull itself) is out of scope of this TA (see TA Pull).

sequence-diagram-corrected.png
A notification exchange between two organisations proceeds in a number of steps. Steps 1 and 2 are preparatory (once per subscription/topic); steps 3 and 4 are the operational steps that recur per event. Step 5 covers recovery after a missed notification or a channel outage.


Not every step and operation is required according to the R4B standard. We will specify those that are optional here.

  1. Subscription registration. On the sending organisation's side, a Subscription is created for the receiving organisation, bound to a pre-agreed SubscriptionTopic. This agreement rests with the receiver: they want to be notified about this topic. How the Subscription is technically established can be determined per use case:

    • in-band: POSTed by the Subscription Client itself. If the Subscription Server's endpoint is not already known, the receiving organisation can similarly resolve it via GF Addressing.

    • out-of-band: set up by the Subscription Server based on a previously made agreement. For out-of-band subscriptions, the Subscription Client's notification endpoint, if not already known, can be looked up via GF Addressing (Endpoint.connectionType = hl7-fhir-rest, payloadType = Subscription).

    Out-of-band Subscription creation is typically associated with the source initiated notification pattern, while in-band Subscription creation is typically associated with the receiver initiated notification pattern. These concepts are related but distinct: the notification pattern describes which party initiates the notification relationship, whereas in-band and out-of-band describe the technical mechanism used to establish the Subscription.

  2. Handshake Immediately after registration, the Subscription Server MUST send a handshake-notification to the Subscription Client's notification endpoint to confirm the channel; only a successful handshake sets Subscription.status to active.

    For the rest-hook channel type, a handshake is mandatory: per the FHIR R4/R4B Subscriptions Backport IG, the Subscription Server SHALL set the initial Subscription.status to requested and SHALL update it to active only after a successful handshake-notification has been sent and accepted; any error in the handshake SHALL result in status being set to error.

  3. Event notifications. Whenever an event occurs on the Subscription Server's side that matches the topic (and any applicable filter), the Subscription Server sends an event-notification Bundle. Each notification receives a monotonically increasing event-number so that the Subscription Client can detect missed notifications. The Bundle carries a focus reference (literal reference) to the source resource at the Subscription Server, and clinical content only if the Subscription's payload mode is full-resource (see Notification Payload Model).

  4. Heartbeats (if used). At pre-agreed intervals, the Subscription Server sends a heartbeat-notification so that the Subscription Client can detect a channel outage, even when no events are actually occurring (see Heartbeat Notification for whether this applies to a given Subscription).

  5. Catch-up after disruption. When the Subscription Client detects a gap in the event-number sequence or a missing expected heartbeat, it uses the $events and $status operations on the Subscription at the Subscription Server to retrieve missed notifications or verify the Subscription status.

    The $status operation informs the Subscription Client of the state of the subscription. The Subscription Server MUST support this operation.

    The $events operation asks the server to replay past notifications. Subscription Servers MAY support this operation; support is not required.

  6. Follow up on notification The receiver can subsequently retrieve the content behind the focus reference via the sender's FHIR endpoint. The content pull and associated access control fall outside this specification (see GF's Identification, Authentication, Authorisation, Consent and the TA Pull).

System Roles and Responsibilities

Subscription Server

The Subscription Server runs on the sending organisation's side and is responsible for managing Subscriptions and delivering notifications. The Subscription Server MUST:

  • Create Subscription resources for the agreed SubscriptionTopic(s) (based on pre-agreed topics or as a result of a Subscription Client requesting a subscription);

  • Send event-notification Bundles in which event-number is incremented in a concurrency-safe manner;

  • Support the $status operation on the Subscription, as well as read and search with search parameters status, criteria, channel.endpoint, channel.type, and channel.payload;

  • Verify before each send that a valid Subscription exists for this receiver, that the receiver is authorized (via GF Authorization) to receive notifications for the SubscriptionTopic and patient involved, and that the consent conditions for the patient involved have been met (see Privacy, Consent, and Authorization);

  • Support the creation of Subscriptions by Subscription Clients (in-band managed Subscriptions), accepting only Subscriptions for pre-agreed SubscriptionTopics;

  • Send handshake-notification Bundles when Subscription.status is set to requested (with retry), and update Subscription.status accordingly.

The Subscription Server MAY:

  • Support the $events operation on the Subscription.

  • Send heartbeat-notification Bundles at established intervals (with retry), where agreed for the Subscription (see Heartbeat Notification).

Subscription Client

The Subscription Client runs on the receiving organisation's side and consumes notifications. The Subscription Client MUST:

  • Receive notification Bundles at the notification endpoint and forward them internally to the processing system;

  • Accept handshake-notification Bundles at the notification endpoint, since Subscription.status cannot become active until this succeeds (see Handshake Notification);

  • Check every incoming Bundle for continuity, using the highest processed event-number; missed notifications may be retrieved via the $events operation at the Subscription Server.

The Subscription Client MAY:

  • Check at agreed intervals whether a heartbeat-notification has been missed, where heartbeat is used for the Subscription (see Heartbeat Notification); if so, the Subscription status SHOULD be queried via $status.

  • Create Subscription resources on its own initiative for the agreed SubscriptionTopic(s) at a Subscription Server.

The Subscription Client is responsible for signalling and recovering from faulty communication, and SHOULD therefore keep track of the state of its Subscriptions.

Implementation Obligations

  • Logging. Both parties MUST log the sending and receipts of subscriptions and notifications — including handshake, and heartbeat where used — with enough detail to reconstruct, after the fact, which notifications were sent, received, or missed for a given Subscription. This is not addressed by the Backport IG, and is required by this TA to support incident investigation and to substantiate that the authorization and consent verifications below were actually performed at the time a notification was sent, not only that a rule requiring them exists.

  • Authorization verification. The Subscription Server MUST verify, before activating a Subscription and again immediately before sending each notification, that the receiver is authorized (via GF Authorization) to receive notifications for the SubscriptionTopic and the specific patient involved. This is independent of, and in addition to, the consent verification below — authorization can be withdrawn or expire on its own timeline, separate from patient consent.

  • Consent verification. The Subscription Server MUST verify, immediately before sending each notification, that the consent conditions applicable to that payload mode (see Privacy, Consent, and Authorization) are still met — not only at Subscription creation time. Consent MAY be withdrawn after a Subscription is created; the server is responsible for reflecting that at send time.

  • Error reporting. All transactions MUST return a FHIR OperationOutcome with an appropriate HTTP status code in case of errors (R4B does not mandate an OperationOutcome on every error path; this is required by this TA).

  • Retry. Clients MUST retry transient errors (5xx, network errors) with exponential backoff (R4B only permits retry without specifying a strategy; this TA requires exponential backoff specifically).

  • Idempotency. Processing MUST be idempotent: re-delivering a previously processed notification MUST NOT cause duplicate side effects (not addressed by R4B; required by this TA).

Resource Definitions

Notification

A notification is a FHIR Bundle of type history, conforming to the Backport profile backport-subscription-notification. The Bundle MUST contain a Parameters resource (SubscriptionStatus, conforming to backport-subscription-status-r4) with at least:

  • subscription — reference to the registered Subscription;

  • statusactive or off;

  • typeevent-notification, handshake-notification, or heartbeat-notification.

Unlike a handshake-notification or heartbeat-notification, an event-notification reports an actual event, so when type is event-notification, the Parameters resource MUST additionally carry:

  • notification-event.event-number — monotonically increasing number to detect missed events;

  • notification-event.timestamp — the moment the event occurred at the Subscription Server.

Whether notification-event.focus, or the resource content itself, is also present depends on the Subscription's payload mode (see Notification Payload Model for what each mode is and why an exchange agreement would choose it):

  • Id-only mode. The Bundle MUST carry notification-event.focus and MUST NOT carry further clinical content.

  • Full-resource mode. The Bundle MUST additionally carry the resource content itself.

  • Empty mode. The Bundle MUST NOT carry notification-event.focus or any clinical content.

SubscriptionTopic

A SubscriptionTopic defines the events for which notifications are sent. A SubscriptionTopic:

  • MUST carry a unique SubscriptionTopic.url naming the topic;

  • MUST specify, via resourceTrigger.resource and SubscriptionTopic.resource, the single resource type it monitors (e.g. Task or Observation);

  • MUST specify, via resourceTrigger.supportedInteraction, which interactions trigger it (e.g. create, update);

  • MAY define, via canFilterBy, which fields a Subscription is allowed to filter on (e.g. Task.owner, Task.for, or Observation.code, Observation.subject);

  • MAY further narrow the topic via queryCriteria, using coded criteria (e.g. a SNOMED procedure code to specialise a generic Task topic for transfer-of-care use cases, or a generic Observation topic for a specific lab test).

Subscription

A Subscription is the FHIR resource that models a long-running agreement between a Subscription Server (sender) and a Subscription Client (receiver) about which notifications should be delivered, and where. When created in-band, the content MUST adhere to these rules:

  • MUST be bound to exactly one pre-agreed SubscriptionTopic, referenced via Subscription.criteria using the extension backport-topic-canonical.

  • MAY carry a scoping filter via the extension backport-filter-criteria to narrow which events qualify (e.g. filter by Task.owner or Observation.code).

  • channel.type MUST be rest-hook, pointing at the Subscription Client's notification endpoint. (R4 backport allows a server to support any channel type it chooses — rest-hook, websocket, email, message; this TA restricts the channel type to rest-hook.)

  • channel.payload MUST be application/fhir+json, with the extension backport-payload-content set to the payload mode agreed for the Subscription (empty, id-only, or full-resource — see Notification Payload Model).

Transactions

The transactions below take place between the Subscription Server and the Subscription Client over an mTLS-secured channel (see Preconditions). The wire format and behavioural details follow the Subscriptions R5 Backport for R4; below we limit ourselves to the requirements that are additional or more restrictive in this context.

Creating a Subscription

A Subscription is created on the sender's side. This happens either out-of-band (the sender sets up the Subscription based on a notification endpoint obtained from the receiver via GF Addressing, having verified via GF Authorization that the receiver is entitled to receive notifications for this SubscriptionTopic) or in-band (the receiver, having similarly resolved the Subscription Server's endpoint via GF Addressing if not already known, POSTs a Subscription to the Subscription Server, which verifies the same authorization before accepting it).

A Subscription is intended as a long-running agreement between the Subscription Server and Subscription Client about a topic, not as a per-event object.

Use Case Roles

Actor

Role

Subscription Client

Creates (in-band) or is the target of (out-of-band) the Subscription

Subscription Server

Persists the Subscription and validates it against the agreed SubscriptionTopic

Referenced Standards

  • HL7® FHIR® R4/R4B — Subscriptions R5 Backport Implementation Guide

  • GF Addressing (for endpoint resolution, in-band or out-of-band)

  • HTTPS over mTLS

Exchange — Request

Trigger: A receiving organisation (or the sender, on its behalf, out-of-band) wants to be notified about a pre-agreed SubscriptionTopic.

Description: The Subscription carries the SubscriptionTopic canonical (extension backport-topic-canonical) on Subscription.criteria, optionally a scoping filter (backport-filter-criteria), channel.type = rest-hook with the Subscription Client's notification endpoint, and channel.payload = application/fhir+json with extension backport-payload-content set per the payload mode agreed for that Subscription (see Notification Payload Model).

Technical Details:

Field

Value / Description

HTTP Method

POST

Endpoint

/Subscription

Headers

Content-Type: application/fhir+json

Exchange — Response

Description: The Subscription Server accepts or rejects the Subscription and (if accepted) sets its status, after which the handshake transaction follows.

Technical Details:

HTTP Status Code

Meaning

201 Created

Subscription successfully created; status set to requested

400 Bad Request

Request could not be parsed or failed FHIR validation

422 Unprocessable Entity

SubscriptionTopic not agreed/known, or business rules violated; OperationOutcome returned

Payload: On success: the created Subscription resource (201 Created). On error: a FHIR OperationOutcome with details.

Rules

The Subscription resource MUST satisfy the content requirements set out in Resource Definitions → Subscription. In addition, a Subscription created via this transaction:

  • MUST be set to active only after a successful handshake (see Handshake Notification), and set to off (not deleted) upon retirement.

Example

A Subscription request combining the topic canonical, a scoping filter, and the id-only payload mode:

JSON
{
  "resourceType": "Subscription",
  "status": "requested",
  "criteria": "SubscriptionTopic/task-status-change",
  "_criteria": {
    "extension": [
      {
        "url": "http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-topic-canonical",
        "valueCanonical": "https://example.org/fhir/SubscriptionTopic/task-status-change"
      },
      {
        "url": "http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-filter-criteria",
        "valueString": "Task.owner=Organization/receiver-org"
      }
    ]
  },
  "channel": {
    "type": "rest-hook",
    "endpoint": "https://receiver.example/fhir/notifications",
    "payload": "application/fhir+json",
    "_payload": {
      "extension": [
        {
          "url": "http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-payload-content",
          "valueCode": "id-only"
        }
      ]
    }
  }
}

Additional Notes

  • Subscriptions can contain only one resource type (a constraint of the Backport IG's SubscriptionTopic profile).

Handshake Notification

After a Subscription is created, the Subscription Server sends a handshake-notification Bundle to the Subscription Client's notification endpoint. On success, Subscription.status is set to active; on failure, retries MUST be attempted with exponential backoff, and on persistent failure the status is set to error.

Use Case Roles

Actor

Role

Subscription Server

Sends the handshake-notification and updates Subscription.status

Subscription Client

Receives the handshake-notification at its notification endpoint

Referenced Standards

  • HL7® FHIR® R4/R4B — Subscriptions R5 Backport Implementation Guide

  • HTTPS over mTLS

Exchange — Request

Trigger: The Subscription Server has accepted a new Subscription and its status is requested.

Description: The Subscription Server sends a handshake-notification Bundle (type = handshake-notification) to the Subscription Client's notification endpoint to confirm reachability, with retry on failure using exponential backoff (the Backport IG only permits retry, without specifying a strategy; the exponential-backoff strategy itself is required by this TA).

Technical Details:

Field

Value / Description

HTTP Method

POST

Endpoint

Subscription Client's notification endpoint (Subscription.channel.endpoint)

Headers

Content-Type: application/fhir+json

Exchange — Response

Description: On success, the Subscription Server sets Subscription.status to active; on persistent failure, status is set to error.

Technical Details:

HTTP Status Code

Meaning

200 OK

Handshake received and accepted

4xx/5xx

Handshake failed; Subscription Server MUST retry with exponential backoff (this strategy is required by this TA; R4B only permits retry without specifying one), then sets status to error on persistent failure

Payload: Typically empty (200 OK); on error, a FHIR OperationOutcome.

Example

A handshake-notification Bundle, sent while Subscription.status is still requested:

JSON
{
  "resourceType": "Bundle",
  "type": "history",
  "entry": [
    {
      "resource": {
        "resourceType": "Parameters",
        "parameter": [
          { "name": "subscription", "valueReference": { "reference": "Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59" } },
          { "name": "status", "valueCode": "requested" },
          { "name": "type", "valueCode": "handshake-notification" }
        ]
      }
    }
  ]
}

Additional Notes

  • This resource does not need to be stored persistently by the receiver beyond updating its own Subscription state.

Event Notification

For each event matching the topic and filter, the Subscription Server sends one event-notification Bundle to the Subscription Client's notification endpoint.

Use Case Roles

Actor

Role

Subscription Server

Detects the matching event and sends the event-notification, incrementing event-number

Subscription Client

Receives the event-notification and checks continuity of event-number

Referenced Standards

  • HL7® FHIR® R4/R4B — Subscriptions R5 Backport Implementation Guide

Exchange — Request

Trigger: An event occurs at the Subscription Server matching the active Subscription's topic and filter criteria.

Description: The Subscription Server sends an event-notification Bundle (type = event-notification) carrying a monotonically increasing event-number (assigned in a concurrency-safe manner) and a notification-event.focus reference to the source resource. The Bundle MUST NOT carry clinical content beyond what the SubscriptionTopic's selected payload mode permits (see Notification Payload Model).

Technical Details:

Field

Value / Description

HTTP Method

POST

Endpoint

Subscription Client's notification endpoint

Headers

Content-Type: application/fhir+json

Exchange — Response

Description: The receiver acknowledges receipt and, if it wishes to access the content, performs a separate, authorised pull via the sender's FHIR endpoint (out of scope of this TA, see TA Pull).

Technical Details:

HTTP Status Code

Meaning

200 OK

Notification received and accepted (not persisted)

422 Unprocessable Entity

Business rules violated (e.g. event-number out of sequence); OperationOutcome returned

Payload: Typically empty (200 OK).

Rules

The notification MUST carry the fields listed in Resource Definitions → Notification, with type = event-notification. In addition, an event-notification:

  • MUST assign the event-number in a concurrency-safe manner;

  • MUST NOT carry clinical content beyond what the SubscriptionTopic's selected payload mode permits (see Notification Payload Model).

Example

An id-only event-notification Bundle for a SubscriptionTopic that monitors Task (used here only as an example resource type — the actual type depends on the agreed SubscriptionTopic), trimmed to the relevant fields — whose first entry reports the event, and whose second entry documents the fetch of the resource it concerns. The focus reference uses the identifier from the Random (UUIDv4) example under Identifier Examples:

JSON
{
  "resourceType": "Bundle",
  "type": "history",
  "entry": [
    {
      "fullUrl": "urn:uuid:c3a5d8f1-9b2e-4d67-8a4c-5e1f7b9d2a36",
      "resource": {
        "resourceType": "Parameters",
        "parameter": [
          {
            "name": "subscription",
            "valueReference": {
              "reference": "Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59"
            }
          },
          { "name": "status", "valueCode": "active" },
          { "name": "type", "valueCode": "event-notification" },
          {
            "name": "notification-event",
            "part": [
              { "name": "event-number", "valueString": "42" },
              { "name": "timestamp", "valueInstant": "2026-07-16T09:15:00Z" },
              {
                "name": "focus",
                "valueReference": {
                  "reference": "Task/5f2f9a4e-8c1d-4b6e-9d3a-7c0e2f4b8a1d"
                }
              }
            ]
          }
        ]
      }
    },
    {
      "fullUrl": "https://sender.example/fhir/Task/5f2f9a4e-8c1d-4b6e-9d3a-7c0e2f4b8a1d",
      "request": {
        "method": "GET",
        "url": "Task/5f2f9a4e-8c1d-4b6e-9d3a-7c0e2f4b8a1d"
      },
      "response": { "status": "200" }
    }
  ]
}

Two identifiers appear here that relate to the Task resource itself:

  • focus.reference: "Task/5f2f9a4e-8c1d-4b6e-9d3a-7c0e2f4b8a1d" — the resource's logical id, satisfying stability, opacity, and unpredictability. This is what makes the notification id-only rather than empty.

  • fullUrl: "https://sender.example/fhir/Task/5f2f9a4e-8c1d-4b6e-9d3a-7c0e2f4b8a1d", together with request.url and response.status — the same logical id, prefixed with the source's base URL, resolved by a direct GET rather than a search: the receiver fetches exactly the resource it needs, without exposing any broader set of resources.

Additional Notes

  • Content access following the focus reference is reassessed for authorisation at the moment of access.

Heartbeat Notification (Optional)

At pre-agreed intervals, the Subscription Server sends a heartbeat-notification Bundle. This serves as a keep-alive signal for the channel and allows the Subscription Client to detect a silent outage even when no events are occurring.

Per the Backport IG, whether heartbeats are used is settled through a request/accept mechanism at Subscription creation: the Subscription Client requests a heartbeat interval (via the backport-heartbeat-period extension on Subscription.channel), and the Subscription Server MAY accept that request as given, modify it, or omit heartbeats altogether. A prior agreement between the parties MAY restrict this mechanism — for example, by fixing the interval in advance or ruling out heartbeats entirely, or requiring the Subscription Server to support and accept heartbeat requests.

For out-of-band Subscriptions, the request/accept mechanism above does not apply, because there is no live request from the Subscription Client: the Subscription Server creates the Subscription unilaterally. Whether heartbeats are used, and at what interval, must therefore be settled entirely by the prior agreement between the parties, and the Subscription Server sets the heartbeat interval on the Subscription it creates accordingly.

The value of using heartbeats depends on the notification pattern being used.

Heartbeats provide assurance at two levels simultaneously: they verify that the technical communication path is functioning, and that the specific FHIR subscription contract remains active and operational.

For source initiated notifications, the sending organisation controls and verifies the establishment of the notification channel itself, so only the first assurance (technical path) is needed, and retries provide an alternative for this. Heartbeats are therefore less valuable for source initiated notifications.

For receiver initiated notifications, heartbeats provide valuable confirmation that the Subscription remains active and that the notification service continues to operate as expected.

Use Case Roles

Actor

Role

Subscription Server

Sends heartbeat-notifications at the agreed interval, with retry

Subscription Client

Optionally checks at agreed intervals whether an expected heartbeat was missed

Referenced Standards

  • HL7® FHIR® R4/R4B — Subscriptions R5 Backport Implementation Guide

Exchange — Request

Trigger: The pre-agreed heartbeat interval for an active Subscription elapses.

Description: The Subscription Server sends a heartbeat-notification Bundle (type = heartbeat-notification) as a keep-alive signal for the channel.

Technical Details:

Field

Value / Description

HTTP Method

POST

Endpoint

Subscription Client's notification endpoint

Headers

Content-Type: application/fhir+json

Exchange — Response

Description: The receiver resets its missed-heartbeat timer; if a heartbeat is missed, the receiver SHOULD query $status.

Technical Details:

HTTP Status Code

Meaning

200 OK

Heartbeat received

4xx/5xx

Heartbeat delivery failed; Subscription Server MUST retry with exponential backoff (this strategy is required by this TA; R4B only permits retry without specifying one)

Payload: Typically empty (200 OK).

Example

A heartbeat-notification Bundle for an active Subscription:

JSON
{
  "resourceType": "Bundle",
  "type": "history",
  "entry": [
    {
      "resource": {
        "resourceType": "Parameters",
        "parameter": [
          { "name": "subscription", "valueReference": { "reference": "Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59" } },
          { "name": "status", "valueCode": "active" },
          { "name": "type", "valueCode": "heartbeat-notification" }
        ]
      }
    }
  ]
}

Additional Notes

  • Heartbeat sending is optional per Subscription, agreed at creation time.

$status and $events Operations ($events Optional)

The receiver uses:

  • $status to query the current state of a Subscription at the Subscription Server — typically after a missed heartbeat;

  • $events to retrieve a specific event-number or a range thereof — typically after detecting a gap in the sequence.

Use Case Roles

Actor

Role

Subscription Client

Invokes $status and/or $events for recovery purposes

Subscription Server

Supports the $status and $events operations, and read/search on Subscription (parameters: status, criteria, channel.endpoint, channel.type, channel.payload)

Referenced Standards

  • HL7® FHIR® R4/R4B — Subscriptions R5 Backport Implementation Guide (GET [base]/Subscription/[id]/$status and $events operations)

Exchange — Request

Trigger: The receiver detects a gap in the event-number sequence, or a missing expected heartbeat.

Description: The Subscription Client invokes $status to query the current state of the Subscription, or $events to retrieve a specific event-number or range thereof.

Technical Details:

Field

Value / Description

HTTP Method

GET

Endpoint

/Subscription/[id]/$status or /Subscription/[id]/$events

Headers

Accept: application/fhir+json

Exchange — Response

Description: The Subscription Server returns the current SubscriptionStatus, or replays the requested event-notification(s).

Technical Details:

HTTP Status Code

Meaning

200 OK

Status or requested event(s) returned

404 Not Found

Unknown Subscription id

422 Unprocessable Entity

Requested event-number range invalid or no longer available

Payload: On success: a SubscriptionStatus Parameters resource (status) or one or more notification-event Bundles (event). On error: a FHIR OperationOutcome.

Additional Notes

  • Used for recovery only; not part of the regular operational flow.

  • Temporary agreement: retention period for replayable events is to be agreed per use case.

Using This TA

This TA defines the generic notification mechanism; it does not itself activate any exchange. Putting it into use for a specific case means agreeing, beyond what this document fixes, on the SubscriptionTopic involved, the payload mode for that topic, and the authorization and consent basis that applies.

Changes since 0.5

  • Identifier construction examples (Random, Keyed Transformation, Per-Recipient) rewritten to state each construction's property and resulting id, rather than showing pseudocode.

  • Examples section renamed to Identifier Examples and scoped to identifier construction only; the id-only notification example moved to Event Notification, where its fields are actually defined.

  • Example payloads added to Creating a Subscription, Handshake Notification, Event Notification, and Heartbeat Notification.

  • Notification Content section renamed to Resource Definitions, to accurately cover Notification, SubscriptionTopic, and Subscription; relocated to precede Transactions instead of following it.

  • SubscriptionTopic definition given the same MUST/MAY structure as Subscription; Notification definition trimmed to field-level implications, with payload-mode rationale left to Notification Payload Model.

  • Duplicated content rules in Creating a Subscription and Event Notification replaced with references back to Resource Definitions.

  • Transactions and its five sub-transaction headings promoted one heading level, correcting a mismatch between heading depth and content weight.

  • Error Handling folded into Implementation Obligations as three additional obligations (error reporting, retry, idempotency); the resulting duplicate idempotency note under Event Notification removed.

  • Closing section reworked into Using This TA.

  • Table of Contents added.

  • Sequence diagram added, and corrected so the handshake is shown as mandatory rather than optional, the recovery operation is named $events rather than $event, and both in-band and out-of-band Subscription creation are shown, including the in-band addressing lookup this made visible was missing from the surrounding text.