10.3.1.1 | TA Notifications
Version: 0.7
Introduction
This Technical Agreement (TA) describes and specifies the technical responsibilities to which parties agree when connecting to exchange transactions to facilitate notifications.
Notifications support the information needs of receivers: they enable healthcare professionals, patients, or the systems they use to become aware of new data and changes in existing data as soon as these are registered.
This specification describes how Dutch healthcare organizations 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 via the Subscriptions R5 Backport Implementation Guide (IG).
This TA applies to FHIR R4 only. This version choice concerns only the subscription and notification framework itself; it does not require the resources referenced by notification-event.focus or notification-event.additional-context to conform to the same FHIR version.
FHIR R4B and R5. This TA is specified for FHIR R4. For reference, the main differences in later versions are as follows. Under FHIR R4B, the Backport IG uses the SubscriptionTopic resource for topic definitions, and a SubscriptionStatus resource instead of a Parameters resource as the first entry of the notification Bundle, with a separate Bundle profile (backport-subscription-notification). In FHIR R5, topic-based subscriptions are part of the core specification: Subscription.topic replaces the use of Subscription.criteria, and notifications use Bundle type subscription-notification. Adopting either version requires a new version of this TA; it is not an implementer option under this version.
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, known in English as the Common Clinical Dataset) between healthcare organizations in the context of a referral. The BgZ is the Dutch patient summary: a standardized set of core patient data (e.g. problems, medication, allergies, procedures) intended to be exchangeable across care settings, comparable in purpose to the International Patient Summary. 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 agreements, 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 mechanism by which notification topics are scoped and narrowed (SubscriptionTopic, including trigger conditions and filter parameters).
-
The relationship with addressing (GF Addressing), authorization (GF Authorization), and the processing basis for exchange, including patient consent (GF Toestemming and, where applicable, EHDS), without elaborating a specific addressing profile.
Exclusions (out of scope):
-
Recall of a notification once sent. A notification cannot be withdrawn or cancelled after delivery; a notification relationship is ended by setting the Subscription's status to off (see Updating a Subscription).
-
Authentication and identification of the actors involved in the agreement (see TA I&A).
-
The retrieval of content that may follow a notification, where the notification itself does not carry that content, and any pattern that combines a notification with such a retrieval. This TA specifies only the notification (see TA Pull for the retrieval).
-
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 kinds of notifications, but the patient-specific authorization, consent, privacy, and related governance requirements described herein do not apply.
-
The definition of specific SubscriptionTopics, including their coding and use-case binding, for a given exchange agreement or use case, and any routing information this makes available to the receiver (see the applicable use-case-specific technical agreement).
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.
-
Subscription Server — the system, run by the sending organisation, that persists Subscriptions and sends notifications to Subscription Clients. See System Roles and Responsibilities for its full obligations.
-
Subscription Client — the system, run by the receiving organisation, that receives notifications at its notification endpoint and consumes them. See System Roles and Responsibilities for its full obligations.
-
zorgaanbieder — the healthcare provider organisation on whose behalf notifications are sent or received, identified by its URA and registered in the Landelijk Register Zorgaanbieders (LRZa; see GF Addressing). This TA uses the Dutch term because it denotes this specific registered party, which is distinct from the party technically operating the systems involved (see GTK); "healthcare provider" could also be read as an individual healthcare professional.
-
GTK (Gekwalificeerd Twiin Knooppunt, qualified Twiin node) — a node qualified under the Twiin afsprakenstelsel through which a zorgaanbieder takes part in data exchange. A zorgaanbieder may operate its own GTK, or use a GTK offered by another party; a single GTK MAY act on behalf of multiple zorgaanbieders.
-
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 of type
history, whose first entry is a Parameters resource carrying the subscription status information (backport-subscription-status-r4). See Resource Definitions. -
Subscription — a FHIR Resource that records the agreement between a Subscription Server and a Subscription Client about which notifications are delivered, for which SubscriptionTopic, and where. It is created either by the Subscription Client (in-band) or by the Subscription Server (out-of-band); see Creating a Subscription. Profiled for topic-based use in R4 by the Backport IG. Every notification MUST be linked to an actual, registered Subscription resource; the Backport IG does not support sending notifications without one.
-
SubscriptionTopic — the definition of 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. In FHIR R4 there is no SubscriptionTopic resource; the Backport IG leaves topic definitions out of scope for R4. A topic is therefore identified at runtime solely by its canonical URL, and defined at design time in the applicable use-case-specific technical agreement (see Resource Definitions → SubscriptionTopic).
-
notification-event.focus — the reference, carried in the notification-event part of the Parameters resource (
backport-subscription-status-r4) that forms the first entry of the notification Bundle, to the resource that triggered that specific event, i.e. the resource type the SubscriptionTopic monitors (see SubscriptionTopic). Present only in id-only and full-resource mode, absent in empty mode (see Notification Payload Model and Resource Definitions → Notification). -
canonical — a URL used as a stable, versionable identifier for a FHIR definitional resource (such as a SubscriptionTopic), as opposed to a literal reference, which points at a specific instance on a specific server.
-
id — as used in this TA, the logical id of a resource (
Resource.id), as carried in a literal reference such asnotification-event.focus. Distinct from identifier. -
identifier — the FHIR Identifier datatype (
system+value). Not used in this TA to refer toResource.id; see id. -
criteria — the
Subscription.criteriaelement, which under the Backport IG SHALL contain the canonical URL of the SubscriptionTopic the Subscription is bound to, not an R4 search expression. Scoping filters are carried separately, in one or morebackport-filter-criteriaextensions onSubscription.criteria, each in the filter syntax defined by the Backport IG ([filterParameter]=[value], optionally with a:[modifier]), using only filter parameters the topic definition allows (e.g.owner=http://fhir.nl/fhir/NamingSystem/ura|12104037). The[resourceType].prefix the Backport IG allows for disambiguation is not needed, since each topic monitors a single resource type.
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. The Subscription Server either accepts the requested mode or rejects the Subscription; it SHALL NOT accept a Subscription with a modified payload mode (see Payload Mode Agreement and Enforcement). The Backport IG permits a server to accept a Subscription with modifications; this TA excludes that for the payload mode. Existing exchange agreements (e.g., Referral or Transfer standards) may also pre-define or restrict which modes are permissible for specific SubscriptionTopics.
The payload modes, defined by the Backport IG (Backport IG payload modes) are:
|
Payload Mode |
|
Description |
|---|---|---|
|
Empty |
|
Contains no reference to the resource that triggered the event and no clinical data. The Bundle merely signals that a matching event occurred for the Subscription; the only reference it carries is to the Subscription itself. |
|
Id-only |
|
Contains a reference to the affected resource ( |
|
Full-resource |
|
Contains the complete FHIR resource instance itself. |
Authorization and Processing Basis for the Push Pattern
Full-resource mode has no separate retrieval step: there is 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 processing-basis obligations that would otherwise apply to disclosing that same clinical content – see Privacy, Consent, and Authorization for what full-resource mode specifically requires.
Payload Selection when the Receiver Retrieves Content Afterwards
This section addresses notifications after which the receiver retrieves the content separately — a Notified Pull–style exchange is a common example. The notification does not presuppose that the basis for that retrieval already exists; it may, or it may still need to be established. The payload is therefore limited to what is strictly necessary. The id-only and empty payload modes exist for exactly this kind of situation.
When choosing between them — full-resource mode is out of scope for this section, since sending it discloses the content directly rather than deferring access (see Authorization and Processing Basis for the Push Pattern) — id-only provides a literal reference to the affected resource to facilitate efficient retrieval, whereas empty conveys no identifying information.
Data 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 ids legitimately can compare notes: an id 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 id itself gives nothing away beyond its own recurrence, it adds nothing to what these three parties learn about the resource's content, order, timing, or real-world identity. A stable id necessarily still allows a party who sees it more than once to recognise that two notifications concern the same resource rather than two different ones; this minimal disclosure is inherent to the stability requirement itself (see Requirements for Using Id-Only) and cannot be eliminated without abandoning id-only mode altogether. 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 id is constructed before it is sent. That is why the conditions that follow are fixed requirements on every id leaving a source system, not something each implementer weighs case by case. The notification as a whole also discloses metadata regardless of payload mode: the event-number reveals how many events have occurred for the Subscription, the timestamp when each occurred, and the Subscription reference which Subscription they belong to (see Resource Definitions → Subscription). That metadata is inherent to the notification mechanism and is not addressed by requirements on the id.
Requirements for Using Id-Only
An id may be used as the reference in an id-only notification only if it satisfies the following requirements:
-
Stability — a source SHALL return the same id for the same resource on every request. Where the source uses per-recipient ids (see Appendix A), the id MAY differ between receivers, but SHALL remain the same for each individual receiver.
-
Opacity — a resource id SHALL NOT reveal creation order, volume, creation time, or content.
-
Unpredictability — a resource id SHALL NOT be guessable, and SHALL NOT be computable or confirmable from real-world identifying numbers (a BSN, a patient number) by anyone who does not hold a secret of the source.
-
Consumer opacity — a consumer SHALL treat received ids as opaque strings: it SHALL NOT parse them, derive meaning from them, or assume a format when querying, however carefully the id was constructed on the sending side.
An id 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.
See Appendix A: Id Construction - Illustrative Examples for constructions that satisfy or fail these requirements.
When a Reference Is Preferable to Empty
For a single-receiver resource whose id 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 id 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 id does not avoid disclosure to the intended recipient — it moves it elsewhere, to the search response. It does, however, avoid disclosure to the observer and to linked parties (see Data exposed by an id-only notification), since no id is sent for them to see, log, or compare in the first place. 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. This is a matter of data minimisation, not of access control: a search returns only resources the receiver is authorized to access, but within that authorization, more than the event concerned. How much more depends on how narrowly the receiver's authorization is scoped. Where authorization is limited to the resource an event concerns, the difference between direct read and search largely disappears, and the case for id-only rests mainly on efficient retrieval.
For single-receiver resources whose id meets the requirements above, the notification’s reference SHOULD be sent, as an absolute URL in notification-event.focus, rather than withheld. Empty remains the right choice only where the id 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 ids or empty mode should be used instead, is a decision for the use-case-specific technical agreement governing that exchange (see Requirements on Use-Case-Specific Technical Agreements), 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 reference to the resource concerned. 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 payload mode is still labeled empty even though the receiver in practice obtains the id. 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 being declared or governed as id-only under the agreed payload mode. This holds regardless of whether the leaked id itself would satisfy the requirements in Requirements for Using Id-Only, the defect lies in the undeclared, ungoverned channel, not necessarily in the id's construction.
Payload Mode Agreement and Enforcement
The permitted payload modes are defined per topic in the governing exchange agreement before a Subscription is created (see Requirements on Use-Case-Specific Technical Agreements); a single topic MAY permit more than one. Systems SHALL NOT accept a Subscription for a SubscriptionTopic or payload mode that has not been formally agreed upon (see Preconditions); this does not require pre-agreement of scoping filter values (backport-filter-criteria), which MAY be set freely within the bounds of the filter parameters the SubscriptionTopic definition allows.
The payload mode is fixed when a Subscription is created and SHALL NOT be changed on an existing Subscription. Each payload mode requires its own processing basis and authorization (see Privacy, Consent, and Authorization), so a change of mode is a new activation: it requires a new Subscription, subject to the checks and handshake that apply to any new Subscription (see Replacing a Subscription). Every notification SHALL adhere to the payload mode registered on its Subscription. If the governing exchange agreement no longer permits the payload mode of an existing Subscription, that Subscription SHALL be set to off and, where notifications are still required, replaced. How the mode gets set depends on who creates the Subscription:
-
In-band creation (FHIR: In-Band Managed Subscription). The receiver creates the Subscription resource and specifies the payload mode via the
backport-payload-contentextension onchannel.payload; if omitted, 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 (FHIR: Out-of-Band Managed Subscription). The sender creates the Subscription resource and specifies the payload mode in the
backport-payload-contentextension, then sends a handshake notification to verify the channel is reachable. Agreement on the payload mode is established beforehand, via the governing exchange agreement, not via the handshake. A handshake carries no clinical content regardless of the agreed payload mode, so successfully processing one demonstrates reachability and correct Bundle handling, not that the receiver has verified the specific payload mode set on the Subscription. The receiver MAY inspect the payload mode by fetching the Subscription resource to confirm it matches the exchange agreement, but this is a separate check, not part of the handshake. If the requested mode falls outside the exchange agreement, the receiver SHALL reject the handshake, or refuse to acknowledge it. The same applies if the SubscriptionTopic carried in the handshake (topic) is not one the receiver has agreed to receive. Even after a successful handshake, the receiver retains the right to reject any later notification that deviates from the agreed payload mode. -
The notification format (JSON or XML) is carried on channel.payload. Unlike the payload mode, it MAY be changed on an existing Subscription by the party that created it, provided the new format is one the Subscription Client supports: for in-band Subscriptions through Updating a Subscription, for out-of-band Subscriptions by the Subscription Server itself (see Resource Definitions → Subscription). Every notification sent afterward SHALL conform to the registered format.
Notification Patterns
Source and receiver initiation are independent of payload mode; the distinction below applies to notifications generally, not only to those following the Notified Pull pattern.
Source Initiated Notifications
In a source initiated notification pattern, the sending healthcare provider initiates the Subscription for a receiving provider, under a SubscriptionTopic the receiving provider has agreed to receive through the applicable use-case-specific technical agreement. The receiving provider does not request the individual notification relationship, but the topic itself is never something the sender can impose unilaterally. 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, and where a topic definition allows further narrowing through filter parameters, a Subscription SHOULD use backport-filter-criteria to apply it (see SubscriptionTopic and Subscription) rather than relying on topic-level scoping alone.
Great care SHOULD therefore be given to the specificity of notifications.
Privacy, Consent, and Authorization
Processing basis and authorization address different aspects of deciding whether data may be exchanged and are established through different mechanisms. The processing basis is the legal ground under GDPR and, where applicable, EHDS that permits the data to be exchanged for a given purpose. This may, depending on the case, be the patient's consent, but other legal grounds may also apply; this TA does not presume consent is the applicable basis in every case. Authorization determines whether all applicable conditions for exchanging data are satisfied, including both the applicable processing basis (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 Toestemming (and, where applicable, EHDS) rather than defining them. A notification MUST NOT be sent unless all applicable authorization and processing-basis conditions are satisfied at the time it is sent.
All payload modes require the applicable processing basis 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 applicable processing basis and authorization are verified per notification, before it is sent, for the patient that notification concerns (see Implementation Obligations). Creating or activating a Subscription discloses no patient data to the receiver and therefore requires no patient-specific verification. For in-band creation, the Subscription Server's response to the Subscription Client is itself an external disclosure, so the Client's authorization for the SubscriptionTopic is verified before the Subscription is accepted (see Preconditions).
-
Full-resource notifications carry clinical content directly and are subject to the same processing-basis 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 processing basis covers disclosure of that content to the receiver, not merely disclosure of the fact that it exists, and that basis MUST already be in place 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.
Where an event by design concerns no identified patient (see Resource Definitions → SubscriptionTopic), the patient-specific verification does not apply to that event; verification of the receiver's authorization for the SubscriptionTopic still does. This does not make such a notification privacy-neutral. Whether the data it concerns is in fact non-identifying, and on what basis it may be disclosed, is established in the use-case-specific technical agreement, not assumed by this TA.
In all cases, the Subscription Server MUST verify authorization and the applicable processing basis 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 the Backport IG; the requirement that parties mutually agree the topic beforehand is added by this TA).
-
For in-band creation, the Subscription Server MUST verify via GF Authorization, before accepting a Subscription, that the Subscription Client is authorized for the SubscriptionTopic. All processing-basis and authorization requirements for the patient a notification concerns (processing basis per GF Toestemming and, where applicable, EHDS; authorization via GF Authorization) MUST be satisfied before that notification is sent (see Privacy, Consent, and Authorization).
-
All endpoints MUST adhere to Network level security standards. Mutual TLS MUST be applied.
-
For in-band creation, the Subscription Server SHALL verify, before accepting a Subscription, that the Subscription Client's
channel.endpointis the address of an Endpoint of that zorgaanbieder in GF Addressing with payloadTypeNotification(see Sequence Diagram, step 1). Whether, and when, this is verified again during the lifetime of the Subscription is not prescribed by this TA. -
The Subscription Client SHALL verify, at the application layer, that each received notification originates from the zorgaanbieder associated with the relevant Subscription, independent of mTLS-layer authentication of the delivering GTK (see Subscription Client).
Authorization for Sender-Initiated Pulls
For sender-initiated (out-of-band) Subscriptions, an event-notification may carry an authorization value for the subsequent pull (see Resource Definitions → Notification). Whether and how a pull may rely on the prior notification, and whether authorization and the processing basis are reassessed at the moment of access, are governed by GF Authorization and TA Pull, not by this TA. For receiver-initiated (in-band) Subscriptions, no authorization value is carried.
FHIR Technical Specification
Conformance
Implementations MUST conform to the HL7® FHIR® Subscriptions R5 Backport Implementation Guide, version 1.1.0 (STU 1.1), using its FHIR R4 package (hl7.fhir.uv.subscriptions-backport.r4). 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 notification mechanism this TA specifies 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. This mechanism can be used, for example, as the notification component of a Notified Pull–style exchange. The actual content retrieval (the pull itself) is out of scope of this TA (see TA Pull).
Not every step and operation is required by the Backport IG. Those that are optional are indicated below.
-
Subscription registration. On the sending organisation's side, a Subscription is created for the receiving organisation, bound to a pre-agreed SubscriptionTopic. The agreement on the topic rests with both parties: in the receiver initiated pattern, the receiver requests to be notified; in the source initiated pattern, the sender initiates the Subscription under a topic the receiver has agreed to (see Notification Patterns). How the Subscription is technically established can be determined per use case:
-
in-band: POSTed by the Subscription Client to the Subscription Server's FHIR endpoint, known beforehand or resolved via GF Addressing as an Endpoint of the sending zorgaanbieder with connectionType
hl7-fhir-rest, payloadTypeSubscriptionand a payloadMimeType withfhirVersion=4.0. The SubscriptionTopics a Subscription Server supports are discoverable via itsCapabilityStatement(see Subscription Server). -
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 as an Endpoint of the receiving zorgaanbieder with connectionType
hl7-fhir-rest, payloadTypeNotificationand a payloadMimeType withfhirVersion=4.0.
The payloadType codes Subscription and Notification are defined in the GF Addressing code system http://minvws.github.io/generiekefuncties-docs/CodeSystem/nl-gf-data-categories-cs (GF Addressing IG 0.9.9). An Endpoint is "of" a zorgaanbieder when it is referenced from that zorgaanbieder's Organization or one of its HealthcareServices; Endpoint.managingOrganization identifies the party managing the Endpoint, not the zorgaanbieder using it. Endpoint selection, including status and period, follows GF Addressing. Where a later version of GF Addressing changes these codes, this TA follows that version.
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. -
-
Handshake Immediately after registration, the Subscription Server MUST send a handshake to the Subscription Client's notification endpoint to confirm the channel; only a successful handshake sets
Subscription.statustoactive.For the rest-hook channel type, a handshake is mandatory: per the Backport IG, the Subscription Server SHALL set the initial
Subscription.statustorequestedand SHALL update it toactiveonly after a successful handshake has been sent and accepted; any error in the handshake SHALL result in status being set toerror. -
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 an event-number that increases by one for each event notified, so that the Subscription Client can detect missed notifications (see Resource Definitions → Notification). Unless the payload mode is
empty, the notification carries a focus reference (literal reference) to the source resource at the Subscription Server; it carries clinical content only if the payload mode isfull-resource(see Notification Payload Model). -
Heartbeats (if used). At pre-agreed intervals, the Subscription Server sends a heartbeat 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).
-
Catch-up after disruption. When the Subscription Client detects a gap in the event-number sequence or a missing expected heartbeat, it uses the
$eventsand$statusoperations on the Subscription at the Subscription Server to retrieve missed notifications or verify the Subscription status.The
$statusoperation informs the Subscription Client of the state of the subscription. The Subscription Server MUST support this operation.The
$eventsoperation asks the server to replay past notifications. Subscription Servers MAY support this operation; support is not required. -
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. Its conformance baseline is the Backport IG's Subscription Server CapabilityStatement, with a few extra requirements.
Required by the Backport IG:
-
Support the
$statusoperation on the Subscription. -
Support read and search on Subscription with the parameters
status,criteria,url,type,payload(FHIR R4) andpayload-type. -
Send a
handshakeand transitionSubscription.statusfromrequestedtoactive(orerror) for therest-hookchannel type. -
Optional support of
$events. -
Optional support of heartbeat; see Heartbeat Notification for how this TA layers on top of it.
Beyond the Backport IG, this TA specifies that the Subscription Server MUST:
-
Create Subscription resources only for pre-agreed SubscriptionTopics (the topic-binding mechanism itself is the IG's; requiring prior mutual agreement on which topics are valid is added by this TA — see Preconditions);
-
Assign
event-numberin a concurrency-safe manner — the IG does not address concurrent assignment; -
Verify, before sending each notification, that a valid Subscription exists for the receiver, and that authorization and the applicable processing basis are still valid for the patient involved (see Implementation Obligations for the full timing rules — this verification obligation is a TA addition, not an IG requirement);
-
Where the applicable use-case-specific technical agreement specifies in-band creation for a given SubscriptionTopic, support Subscription creation by Subscription Clients for that topic, accepting only pre-agreed topics from entitled Clients — support for in-band creation is conditional on the use-case agreement, not a blanket capability;
-
Where it supports in-band creation, support the Updating a Subscription transaction, accepting only the changes that transaction permits. The FHIR update interaction itself is not restricted by the Backport IG; the restriction is a TA addition.
-
Register its FHIR base URL in GF Addressing as an Endpoint of each zorgaanbieder it acts for, with connectionType
hl7-fhir-restand payloadTypeSubscription, also where it only creates Subscriptions out-of-band, so that Subscription Clients can verify the subscription reference in notifications (see Resource Definitions → Notification). -
Retry failed handshake and notification delivery with exponential backoff specifically — the IG only requires retry as such, without specifying a strategy (see Implementation Obligations);
-
Support both
application/fhir+jsonandapplication/fhir+xmlfor every transaction under this TA — FHIR R4 does not require a server to support both formats; this is a requirement of this TA alone.
The Subscription Server SHOULD:
-
Where it supports in-band Subscription creation, advertise the SubscriptionTopics it supports in its
CapabilityStatement, using thecapabilitystatement-subscriptiontopic-canonicalextension defined by the Backport IG, so that Subscription Clients can discover them.
Subscription Client
The Subscription Client runs on the receiving organisation's side and consumes notifications. The Backport IG does not define a separate conformance statement for this role. 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.statuscannot become active until this succeeds (see Handshake Notification); -
Check every incoming Bundle for continuity, using the highest processed event-number. Upon detecting a gap, at minimum: (a) log the gap (see Implementation Obligations), and (b) query $status to confirm the Subscription's current state (active, off, or error). Where $events is supported, missed notifications SHOULD additionally be retrieved through it (see $status and $events Operations). Where $events is not supported, or does not cover the missed range, further reconciliation of the missed content follows the route stated in the applicable use-case-specific technical agreement (see Requirements on Use-Case-Specific Technical Agreements).
-
Verify, upon receiving a notification, that it originates from the zorgaanbieder associated with the relevant Subscription, not merely from a GTK authenticated at the mTLS layer, since a single GTK MAY act on behalf of multiple zorgaanbieders. The notification Bundle itself carries no identity of the sending zorgaanbieder: the claimed sending organisation is taken from the authentication context of the notification request, as established per TA I&A and GF Authorization, and cross-checked at the application layer against the zorgaanbieder associated with the Subscription. For out-of-band Subscriptions, that association is recorded when the handshake is received, from the authentication context of that request. This TA does not define the authentication context itself.
-
Support at least one of
application/fhir+jsonorapplication/fhir+xml. The format used for the notifications of a given Subscription is the one set in that Subscription'schannel.payload.
The Subscription Client SHOULD:
-
Where heartbeats are used for a Subscription, check at the agreed interval whether a heartbeat notification has been missed, and compare its events-since-subscription-start with the highest processed event-number. On a missed heartbeat or a discrepancy, query $status and treat the discrepancy as a gap (see the gap-handling requirement above).
The Subscription Client MAY:
-
Create Subscription resources on its own initiative for the agreed SubscriptionTopic(s) at a Subscription Server, and retire them or change their notification format through Updating a Subscription.
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 receipt 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 processing-basis verifications below were actually performed at the time a notification was sent, not only that a rule requiring them exists. This requirement concerns the notification channel itself, not access to patient record content; where applicable, logging of actual content access remains separately governed by NEN 7513.
-
Authorization verification. The Subscription Server MUST verify, immediately before sending each notification, including each retry of it and each replay through
$events, that the receiver is authorized (via GF Authorization) to receive notifications for the SubscriptionTopic and the patient that notification concerns, or, where the event by design concerns no identified patient, for the SubscriptionTopic alone. For in-band creation, it MUST in addition verify, before accepting the Subscription, that the Subscription Client is authorized for the SubscriptionTopic. This is independent of, and in addition to, the processing-basis verification below. Authorization can be withdrawn or expire on its own timeline, separate from the processing basis. -
Processing-basis verification. The Subscription Server MUST verify, immediately before sending each notification, including each retry of it and each replay through
$events, that the processing basis applicable to that payload mode (see Privacy, Consent, and Authorization) still applies for the patient that notification concerns. Where the basis is consent, it MAY be withdrawn after a Subscription is created; the server is responsible for reflecting that at the time a notification is sent. -
Error reporting. All transactions MUST return a FHIR OperationOutcome with an appropriate HTTP status code in case of errors (neither FHIR R4 nor the Backport IG mandates an OperationOutcome on every error path; this is required by this TA).
-
Retry. The sending party of a transaction (for notifications the Subscription Server, for Subscription creation and update and the
$statusand$eventsoperations the Subscription Client) MUST retry transient errors (5xx, network errors, and 429 Too Many Requests) with exponential backoff. Other 4xx responses indicate a permanent error (e.g. malformed request, failed validation) and MUST NOT be retried (the Backport IG only permits retry without specifying a strategy; this TA requires exponential backoff specifically). Where a 429 response carries a Retry-After header, the sending party SHALL NOT retry before the indicated time. For notifications, retries are exhausted when the maximum retry duration set by the use-case-specific technical agreement has elapsed (see Delivery failure and Subscription status). As an illustration only: each interval 1.5 times the previous, capped at 12 hours. -
Delivery failure and Subscription status. While the Subscription Server is retrying a failed event-notification or heartbeat, it SHALL set the Subscription's status to error, and SHALL set it back to active upon the next successful delivery. When retries are exhausted, it SHALL set the status to off; a Subscription set to off is not reactivated, and where notifications are still required, a new Subscription is created (see Replacing a Subscription). A notification rejected with a permanent error (4xx other than 429) is not retried, keeps its event-number, and sets the status to error. The Subscription Server MUST continue to support $status, and $events where supported, on a Subscription set to off for the retention period agreed for replayable events. The same applies to the handshake, where the Backport IG requires any handshake error to set the status to error. A handshake rejected with a permanent error is not retried and the status is then set to off, since a Subscription that was never activated has no later delivery from which to recover.
-
Idempotency. Processing MUST be idempotent: re-delivering a previously processed notification MUST NOT cause duplicate side effects. This includes notifications for the same event under a replaced and a replacement Subscription (see Replacing a Subscription). Not addressed by the Backport IG; required by this TA.
Resource Definitions
Notification
A notification is a FHIR Bundle of type history, conforming to the Backport profile backport-subscription-notification-r4. The first entry MUST be a Parameters resource conforming to backport-subscription-status-r4, with at least:
-
subscription— reference to the registered Subscription; MUST be an absolute URL, resolvable by the Subscription Client without prior knowledge of the Subscription Server's base URL — consistent with hownotification-event.focusis recommended to be sent (see When a Reference Is Preferable to Empty). The Subscription Client SHALL verify that the base URL of this reference belongs to the sending zorgaanbieder, and SHALL NOT dereference a reference that does not match. For in-band Subscriptions, this is the base URL to which the Client submitted the Subscription; for out-of-band Subscriptions, the address of an Endpoint of that zorgaanbieder in GF Addressing with payloadType Subscription (see Sequence Diagram, step 1). -
status— the current status of the Subscription (requested, active, error, or off); a handshake is typically sent while the status is still requested;
-
type—handshake,heartbeat, orevent-notificationin notifications the Subscription Server sends;query-statusandquery-eventoccur only in responses to the$statusand$eventsoperations (see $status and $events Operations ). -
topic — the canonical URL of the SubscriptionTopic, identical to Subscription.criteria. Required by this TA in every notification, so that the Subscription Client can verify the topic of an out-of-band Subscription upon receiving its handshake (see Payload Mode Agreement and Enforcement).
Every entry in the Bundle MUST carry a request element, as required for history Bundles (invariants bdl-3 and bdl-4). For the first entry, the request MUST match a request to the $status operation on the Subscription. For further entries, the request SHOULD reflect the interaction that triggered the event (e.g. PUT for an update), per the Backport IG.
Unlike a handshake or heartbeat, an event-notification reports an actual event, so when type is event-notification, the Parameters resource MUST additionally carry:
-
notification-event.event-number— sequence number that increases by one for each event notified under the Subscription, used to detect missed events. An event for which the notification is withheld because the authorization or processing-basis verification fails (see Implementation Obligations) is not assigned an event-number; a notification that was permitted but failed delivery is. This is a TA addition; the Backport IG does not address withheld notifications. -
notification-event.timestamp— the moment the event occurred at the Subscription Server. Notifications for the same event under different Subscriptions MUST carry the same timestamp (see Replacing a Subscription). Optional in the Backport IG; required by this TA.
When type is heartbeat, the Parameters resource MUST additionally carry events-since-subscription-start: the total number of events assigned an event-number for the Subscription since its creation (see event-number above), not counting handshake and heartbeat notifications. The Backport IG counts all events generated for the Subscription regardless of delivery; under this TA, an event whose notification is withheld is not counted as generated for the Subscription, while a notification that failed delivery is. This allows the Subscription Client to detect missed event-notifications, including the most recent one, in the absence of later events (optional in the Backport IG; required by this TA).
Whether notification-event.focus, or the resource content itself, is also present depends on the Subscription's payload mode (see Notification Payload Model):
-
Id-only mode. The Parameters resource MUST carry notification-event.focus. Each further Bundle entry MUST carry the resource URL in fullUrl and request, and MUST NOT carry the resource content.
-
Full-resource mode. The Parameters resource MUST carry notification-event.focus, and the Bundle MUST carry the resource content itself in entry.resource.
-
Empty mode. The Parameters resource MUST NOT carry notification-event.focus or notification-event.additional-context, and the Bundle MUST NOT contain any entry other than the Parameters resource.
Authorization value (sender-initiated only)
For sender-initiated (out-of-band) Subscriptions, an event-notification MAY carry an authorization value that the Subscription Client needs for the subsequent pull, as two additional parts of notification-event: authorization-type (Coding), identifying the authorization mechanism the value belongs to, and authorization-value (string), carrying the value itself.
These parts are not defined in version 1.1.0 of the Backport IG; they follow the names used in its 1.2.0 ballot (notification-authorization-hint), and remain conformant to 1.1.0, whose slicing of notification-event parts is open. Where a published version of the Backport IG changes these names, this TA follows that version.
The meaning of the value, the applicable authorization-type codes, how the value is used in the subsequent pull, and how long it remains valid are defined by GF Authorization, not by this TA (see Authorization for Sender-Initiated Pulls). This TA only requires that the value:
-
MUST satisfy the opacity and unpredictability requirements (see Requirements for Using Id-Only);
-
MUST be single-use or time-bounded, since it is exposed to every party that handles the notification (see Data exposed by an id-only notification);
-
MUST NOT be present for receiver-initiated (in-band) Subscriptions.
SubscriptionTopic
In FHIR R4, a SubscriptionTopic is not a resource exchanged or stored at runtime: the Backport IG leaves topic definitions out of scope for R4, and a Subscription refers to a topic solely by its canonical URL. A SubscriptionTopic is therefore a design-time definition, published in the use-case-specific technical agreement that defines it (see Requirements on Use-Case-Specific Technical Agreements). That definition:
-
MUST assign the topic a unique canonical URL;
-
MUST specify the single resource type it monitors (e.g. Task or Observation). This TA restricts each topic to one monitored resource type; this is a choice of this TA, not a constraint of FHIR or the Backport IG;
-
MUST specify which interactions trigger it (
create,update,delete), and any further trigger condition, such as a coded value (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); -
MUST state, for the events it defines, how the patient an event concerns is resolved: via a filter parameter set on the Subscription itself (e.g. a
patientfilter, resolvable at Subscription-creation time), via a designated element on the triggering resource (e.g.Task.for, resolvable only once the event occurs), or not at all, where the event by design concerns no identified patient (e.g. a request for care based on the care need only, before the patient is disclosed). Where a topic covers events of both kinds, for instance a workflow in which the patient is identified only at a later stage, the definition MUST state from which point the patient is resolvable;
-
MAY define filter parameters a Subscription is allowed to use in
backport-filter-criteria, each with its name, the element of the monitored resource it applies to, and the form of its value (e.g. filter parameter owner onTask.owner.identifier, with a URA as value). Where a filter parameter identifies an organisation, it SHOULD apply to the identifier of the reference and take the organisation's URA as value (e.g.owner=http://fhir.nl/fhir/NamingSystem/ura|12104037), since a literal reference to an Organization on the Subscription Server is not known to the Subscription Client.
A use-case-specific technical agreement MAY additionally publish the definition as an R4B or R5 SubscriptionTopic resource, as a machine-readable reference. Under this TA, such a resource is documentation, not a runtime artifact.
Choosing a Resource Type to Monitor
A SubscriptionTopic SHOULD monitor a coordination/workflow resource (e.g. Task) when what matters to the receiver is a change in process state — who owns something, what step it is in, whether it is complete. It SHOULD monitor a data resource directly (e.g. Observation, DocumentReference) when what matters is that specific clinical content has become available or changed, independent of any workflow around it.
These are not mutually exclusive: a single real-world event, such as a referral becoming available for pickup, can be framed as either a workflow-state change (the coordinating Task moving to a "ready" state) or a data-availability change (the referral content itself appearing), and different use cases may reasonably choose either framing depending on what the receiving system needs to act on. This choice is made in the use-case-specific technical agreement (see Requirements on Use-Case-Specific Technical Agreements); this TA does not mandate one framing over the other.
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. The content MUST adhere to these rules:
-
MUST conform to the Backport IG Subscription profile (
backport-subscription). -
MUST be bound to exactly one pre-agreed SubscriptionTopic, by carrying the topic's canonical URL in
Subscription.criteria. -
MAY carry one or more scoping filters via the extension
backport-filter-criteriaonSubscription.criteria, in the filter syntax defined by the Backport IG and using filter parameters allowed by the topic definition (e.g.owner=http://fhir.nl/fhir/NamingSystem/ura|12104037). -
channel.typeMUST berest-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+jsonorapplication/fhir+xml. For in-band creation, the Subscription Client sets a format it supports. For out-of-band creation, the Subscription Server sets a format the Subscription Client supports, as established by prior agreement or by the Subscription Client's endpoint registration in GF Addressing (Endpoint.payloadMimeType). The extension backport-payload-content is set to the payload mode agreed for the Subscription (empty,id-only, orfull-resource; see Notification Payload Model). For in-band Subscription creation, this extension MAY be omitted, in which case empty mode is assumed (see Payload Mode Agreement and Enforcement); for out-of-band creation, the Subscription Server SHALL set the extension explicitly. -
Subscription.idis carried in every notification, in every payload mode, and is visible to every party that handles a notification (see Data exposed by an id-only notification). It MUST therefore satisfy the opacity and unpredictability requirements in Requirements for Using Id-Only. Where a Subscription concerns a single patient, its id is a stable reference to that patient's notifications; this TA does not require per-recipient or rotating Subscription ids, but an exchange agreement MAY. -
MAY carry the extension
backport-heartbeat-periodonchannel(0..1,unsignedInt, seconds) to request or convey the heartbeat interval (see Heartbeat Notification).
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, under a SubscriptionTopic the receiver has agreed to receive, based on a notification endpoint obtained via GF Addressing) or in-band (the receiver, having resolved the Subscription Server's endpoint via GF Addressing if not already known, POSTs a Subscription to the Subscription Server, which verifies via GF Authorization that the receiver is authorized for the SubscriptionTopic before accepting it).
The Subscription resource may be submitted as application/fhir+json or application/fhir+xml, independent of the notification format set in channel.payload (see Subscription Server).
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® Subscriptions R5 Backport Implementation Guide 1.1.0 (R4)
-
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: This transaction follows the standard FHIR create interaction on /Subscription, per the Backport IG (see Referenced Standards). The Subscription carries the SubscriptionTopic canonical URL in Subscription.criteria, optionally a scoping filter (backport-filter-criteria).
Beyond the IG, this TA requires:
-
channel.type = rest-hook; the IG permits other channel types (websocket, email, message), this TA restricts to rest-hook only; -
channel.payload = application/fhir+jsonorchannel.payload = application/fhir+xmlwith extensionbackport-payload-contentset per the payload mode agreed for that Subscription (see Notification Payload Model).
Technical Details:
|
Field |
Value / Description |
|---|---|
|
HTTP Method |
POST |
|
Endpoint |
|
|
Headers |
|
Exchange — Response
Description: Standard FHIR create responses apply, plus one TA-specific business rule: 422 Unprocessable Entity when the SubscriptionTopic is not pre-agreed.
Technical Details:
|
HTTP Status Code |
Meaning |
|---|---|
|
201 Created |
Subscription successfully created; status set to |
|
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
activeonly after a successful handshake (see Handshake Notification), and set tooff(not deleted) upon retirement: by the Subscription Server for out-of-band Subscriptions, and through Updating a Subscription for in-band Subscriptions. -
For in-band creation, the channel.endpoint SHALL be verified against GF Addressing before the Subscription is accepted (see Preconditions); a Subscription whose endpoint does not match SHALL be rejected with 422 Unprocessable Entity.
Example
A Subscription request combining the topic canonical, a scoping filter, and the id-only payload mode:
{
"resourceType": "Subscription",
"status": "requested",
"criteria": "https://example.org/fhir/SubscriptionTopic/task-status-change",
"_criteria": {
"extension": [
{
"url": "http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-filter-criteria",
"valueString": "owner=http://fhir.nl/fhir/NamingSystem/ura|12104037"
}
]
},
"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
A Subscription is bound to exactly one SubscriptionTopic (see Resource Definitions → Subscription); a topic monitors a single resource type (see Resource Definitions → SubscriptionTopic).
Updating a Subscription
A Subscription created in-band can be updated by the Subscription Client that created it, for two purposes only: retiring the Subscription by setting its status to off, and changing the notification format in channel.payload. Any other change requires a new Subscription (see Replacing a Subscription). Out-of-band Subscriptions are updated by the Subscription Server itself; that is not a transaction under this TA.
Use Case Roles
|
Actor |
Role |
|---|---|
|
Subscription Client |
Updates a Subscription it created in-band |
|
Subscription Server |
Validates the update against the permitted changes and applies it |
Referenced Standards
-
HL7® FHIR® R4, RESTful API, update interaction
-
HL7® FHIR® Subscriptions R5 Backport Implementation Guide 1.1.0 (R4)
-
HTTPS over mTLS
Exchange — Request
Trigger: The Subscription Client wants to retire an in-band Subscription, or to change its notification format.
Description: This transaction follows the standard FHIR update interaction on /Subscription/[id]. Beyond FHIR and the Backport IG, this TA restricts which changes are permitted (see Rules).
|
Field |
Value / Description |
|---|---|
|
HTTP Method |
PUT |
|
Endpoint |
|
|
Headers |
|
Exchange — Response
Description: Standard FHIR update responses apply, plus the TA-specific business rules below.
|
HTTP Status Code |
Meaning |
|---|---|
|
200 OK |
Update applied; the updated Subscription is returned |
|
400 Bad Request |
Request could not be parsed or failed FHIR validation |
|
403 Forbidden |
The requesting party is not the Subscription Client that created the Subscription |
|
404 Not Found |
Unknown Subscription id |
|
422 Unprocessable Entity |
The update contains a change other than those permitted, or the Subscription is already off; OperationOutcome returned |
Payload: On success: the updated Subscription resource. On error: a FHIR OperationOutcome.
Rules
-
Only the Subscription Client that created the Subscription MAY update it, as established from the authentication context of the request (see Subscription Client).
-
The permitted changes are: status set to off, and channel.payload set to another format the Subscription Client supports (see Resource Definitions → Subscription). All other elements, including criteria, backport-filter-criteria, channel.endpoint, channel.type, backport-payload-content and backport-heartbeat-period, SHALL be unchanged; otherwise the update SHALL be rejected with 422.
-
The status of a Subscription is maintained by the Subscription Server (see Implementation Obligations). The Subscription Server SHALL treat status in an update as a request: off retires the Subscription; any other value is ignored and the current status is retained.
-
A Subscription that is off SHALL NOT be updated; such an update SHALL be rejected with 422.
-
A changed format applies to every notification sent after the 200 OK response.
Example
Retiring the Subscription from the example in Creating a Subscription:
PUT https://sender.example/fhir/Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59
{
"resourceType": "Subscription",
"id": "7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59",
"status": "off",
"criteria": "https://example.org/fhir/SubscriptionTopic/task-status-change",
"_criteria": {
"extension": [
{
"url": "http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-filter-criteria",
"valueString": "owner=http://fhir.nl/fhir/NamingSystem/ura|12104037"
}
]
},
"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
A replacement Subscription is created through Creating a Subscription; the replaced in-band Subscription is then retired through this transaction (see Replacing a Subscription).
Replacing a Subscription
A Subscription is replaced, rather than modified, when its payload mode changes (see Payload Mode Agreement and Enforcement). It MAY also be replaced for other reasons. The party that created the Subscription (the Subscription Client for in-band, the Subscription Server for out-of-band) performs the replacement.
Rules
-
The replacement Subscription MUST be active before the Subscription it replaces is set to
off, so that no events are lost during replacement. The replaced Subscription SHALL be set tooffonce the replacement has been confirmedactive; for in-band Subscriptions through Updating a Subscription. -
During the overlap, an event matching both Subscriptions results in a notification under each, each with its own event-number. The Subscription Client MUST deduplicate these notifications using the combination of notification-event.focus and notification-event.timestamp (see Resource Definitions → Notification).
-
Where either Subscription is in empty mode, notifications carry no focus and cannot be deduplicated. A duplicate empty notification only leads to a redundant query, which the Subscription Client MUST process idempotently.
-
This TA does not end the validity of an authorization value when a Subscription is replaced; its validity is governed by GF Authorization.
-
The Subscription Server MUST continue to support
$statuson the replaced Subscription, and$eventswhere supported, for the retention period agreed for replayable events, so that a gap detected before replacement can still be recovered. -
For out-of-band Subscriptions, the Subscription Client associates the replacement Subscription with the zorgaanbieder upon its own handshake, as for any new Subscription (see Subscription Client). The association is not inherited from the replaced Subscription.
Handshake Notification
After a Subscription is created, the Subscription Server sends a handshake Bundle to the Subscription Client's notification endpoint. On success, Subscription.status is set to active. On any failure, the status is set to error, as required by the Backport IG; for transient errors, retries MUST be attempted with exponential backoff, and the status is set to active upon a successful retry, or to off when retries are exhausted (see Implementation Obligations).
Use Case Roles
|
Actor |
Role |
|---|---|
|
Subscription Server |
Sends the handshake and updates |
|
Subscription Client |
Receives the handshake at its notification endpoint |
Referenced Standards
Exchange — Request
Trigger: The Subscription Server has accepted a new Subscription and its status is requested.
Description: This transaction follows the Backport IG's handshake flow: the Subscription Server sends a handshake Bundle (type = handshake) to the Subscription Client's notification endpoint to confirm reachability. Beyond the IG, this TA requires retry on failure using exponential backoff specifically (see Implementation Obligations).
Technical Details:
|
Field |
Value / Description |
|---|---|
|
HTTP Method |
POST |
|
Endpoint |
Subscription Client's notification endpoint ( |
|
Headers |
Per |
Exchange — Response
Description: Standard Backport IG handshake responses apply (status transitions to active on success and to error on any error); the TA-specific additions are the exponential-backoff retry strategy and the subsequent transition to active or off (see Implementation Obligations).
Technical Details:
|
HTTP Status Code |
Meaning |
|---|---|
|
200 OK |
Handshake received and accepted |
|
429, 5xx, network errors |
Handshake failed (transient); Subscription Server sets status to |
|
Other 4xx |
Handshake rejected (permanent); Subscription Server sets status to |
Payload: Typically empty (200 OK); on error, a FHIR OperationOutcome.
Example
A handshake Bundle, sent while Subscription.status is still requested:
{
"resourceType": "Bundle",
"type": "history",
"entry": [
{
"fullUrl": "urn:uuid:9e41b2d7-3c85-4f1a-b6e0-2d7c8a5f4e13",
"resource": {
"resourceType": "Parameters",
"parameter": [
{ "name": "subscription", "valueReference": { "reference": "https://sender.example/fhir/Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59" } },
{ "name": "topic", "valueCanonical": "https://example.org/fhir/SubscriptionTopic/task-status-change" },
{ "name": "status", "valueCode": "requested" },
{ "name": "type", "valueCode": "handshake" }
]
},
"request": {
"method": "GET",
"url": "https://sender.example/fhir/Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59/$status"
},
"response": { "status": "200" }
}
]
}
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
Exchange — Request
Trigger: An event occurs at the Subscription Server matching the active Subscription's topic and filter criteria.
Description: This transaction follows the Backport IG's event-notification flow. The Subscription Server sends an event-notification Bundle (type = event-notification) carrying an event-number that increases by one for each event notified (assigned in a concurrency-safe manner; see Resource Definitions → Notification) and, unless the payload mode is empty, a notification-event.focus reference to the source resource. The Bundle MUST NOT carry clinical content beyond what the Subscription's payload mode permits (see Notification Payload Model).
Technical Details:
|
Field |
Value / Description |
|---|---|
|
HTTP Method |
POST |
|
Endpoint |
Subscription Client's notification endpoint |
|
Headers |
Per |
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 |
|
429, 5xx, network errors |
Delivery failed (transient); Subscription Server MUST retry with exponential backoff, with status |
|
Other 4xx |
Notification rejected (permanent); Subscription Server MUST NOT retry, sets status to |
A Subscription Client SHALL NOT reject a notification because of a gap in, or repetition of, the event-number sequence. Gaps are handled as described under Subscription Client; repeated delivery of a previously processed notification is accepted with 200 OK and processed idempotently (see Implementation Obligations).
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. The IG does not address concurrent assignment, so this is a TA addition, not an IG requirement.
-
MUST NOT carry clinical content beyond what the Subscription'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. The first entry reports the event; the second entry identifies the resource that triggered it. The focus reference uses the id from the Random (UUIDv4) example under Id Examples:
{
"resourceType": "Bundle",
"type": "history",
"entry": [
{
"fullUrl": "urn:uuid:c3a5d8f1-9b2e-4d67-8a4c-5e1f7b9d2a36",
"resource": {
"resourceType": "Parameters",
"parameter": [
{ "name": "subscription", "valueReference": { "reference": "https://sender.example/fhir/Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59" } },
{ "name": "topic", "valueCanonical": "https://example.org/fhir/SubscriptionTopic/task-status-change" },
{ "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": "https://sender.example/fhir/Task/5f2f9a4e-8c1d-4b6e-9d3a-7c0e2f4b8a1d" } }
]
}
]
},
"request": {
"method": "GET",
"url": "https://sender.example/fhir/Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59/$status"
},
"response": { "status": "200" }
},
{
"fullUrl": "https://sender.example/fhir/Task/5f2f9a4e-8c1d-4b6e-9d3a-7c0e2f4b8a1d",
"request": {
"method": "PUT",
"url": "Task/5f2f9a4e-8c1d-4b6e-9d3a-7c0e2f4b8a1d"
},
"response": { "status": "200" }
}
]
}
Two elements relate to the Task resource itself:
-
focus: the reference to the resource that triggered the event, using its logical id, which satisfies stability, opacity, and unpredictability. Its presence is what makes the notification id-only rather than empty. -
The second entry:
fullUrlcarries the same resource URL, and request records the interaction that triggered the event (here an update,PUT), as required forhistoryBundles. The entry carries no resource content. It is written by the Subscription Server as part of the notification; it is not a record of any retrieval by the receiver. A receiver that subsequently retrieves the resource does so by a direct read on this URL, which discloses exactly this one resource.
Additional Notes
Authorization of content access following a notification is governed by TA Pull and GF Authorization (see Authorization for Sender-Initiated Pulls).
Heartbeat Notification (Optional)
At pre-agreed intervals, the Subscription Server sends a heartbeat 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.
The Subscription Client MUST treat the heartbeat interval actually in effect as the value of backport-heartbeat-period on the Subscription resource as returned by the Subscription Server — whether from the 201 Created response to an in-band request, or from a subsequent read — not the value the Client itself requested. For out-of-band Subscriptions, the value the Subscription Server sets is authoritative from the start, since there was no prior Client request to compare it against.
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, is therefore settled entirely by the use-case-specific technical agreement (see Requirements on Use-Case-Specific Technical Agreements), and the Subscription Server sets the heartbeat interval on the Subscription it creates accordingly.
Heartbeats give the Subscription Client assurance it cannot otherwise obtain: that the channel is working, that the Subscription is still active at the Subscription Server, and, through events-since-subscription-start (see Resource Definitions → Notification), that no notification has been missed, including the most recent one. Without heartbeats, the Subscription Client detects a missed notification only when a later event-notification arrives, and does not detect a missed last notification at all. Retries do not substitute for this: they inform the Subscription Server of failed deliveries, not the Subscription Client.
This assurance applies equally to source initiated and receiver initiated notifications: in both, a silent outage at the Subscription Server is visible only to the Subscription Client. Heartbeats do not demonstrate that the Subscription Server correctly detects the events a topic defines; a server that fails to detect an event still sends its heartbeats.
Whether heartbeats are used, and at what interval, depends on how quickly a missed notification must be detected for the process concerned, and on how frequently events are expected. Where events are frequent, event-number continuity already reveals gaps quickly; where they are infrequent, or a missed last notification is consequential, heartbeats are the only means of timely detection. This choice is made in the use-case-specific technical agreement (see Requirements on Use-Case-Specific Technical Agreements).
Use Case Roles
|
Actor |
Role |
|---|---|
|
Subscription Server |
Sends heartbeat at the agreed interval, with retry |
|
Subscription Client |
Checks at agreed intervals whether an expected heartbeat was missed (see Subscription Client) |
Referenced Standards
Exchange — Request
Trigger: The pre-agreed heartbeat interval for an active Subscription elapses.
Description: This transaction follows the Backport IG's heartbeat flow (see Referenced Standards above); the TA-specific additions are the exponential-backoff retry strategy and the status transitions on delivery failure (see Implementation Obligations).
Technical Details:
|
Field |
Value / Description |
|---|---|
|
HTTP Method |
POST |
|
Endpoint |
Subscription Client's notification endpoint |
|
Headers |
Per |
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 |
|
429, 5xx, network errors |
Heartbeat delivery failed (transient); Subscription Server MUST retry with exponential backoff, with status |
|
Other 4xx |
Heartbeat rejected (permanent); Subscription Server MUST NOT retry and sets status to |
Payload: Typically empty (200 OK).
Example
A heartbeat Bundle for an active Subscription:
{
"resourceType": "Bundle",
"type": "history",
"entry": [
{
"fullUrl": "urn:uuid:0364d735-381d-4a15-89fd-597e557b0ce2",
"resource": {
"resourceType": "Parameters",
"parameter": [
{ "name": "subscription", "valueReference": { "reference": "https://sender.example/fhir/Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59" } },
{ "name": "topic", "valueCanonical": "https://example.org/fhir/SubscriptionTopic/task-status-change" },
{ "name": "status", "valueCode": "active" },
{ "name": "type", "valueCode": "heartbeat" },
{ "name": "events-since-subscription-start", "valueString": "42" }
]
},
"request": {
"method": "GET",
"url": "https://sender.example/fhir/Subscription/7f3e9a2c-5d18-4b6f-9c3a-8e2d4f6b1a59/$status"
},
"response": { "status": "200" }
}
]
}
Additional Notes
Heartbeat sending is optional; whether and at what interval are set by the use-case-specific technical agreement.
$status and $events Operations ($events Optional)
The receiver uses:
-
$statusto query the current state of a Subscription at the Subscription Server — typically after a missed heartbeat; -
$eventsto 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 |
|
Subscription Server |
Supports the |
Referenced Standards
-
HL7® FHIR® Subscriptions R5 Backport Implementation Guide 1.1.0 (R4) (
GET [base]/Subscription/[id]/$statusand$eventsoperations)
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 |
|
|
Headers |
Per the Subscription Client's choice; the Subscription Server supports both |
|
Parameters |
Per the Backport IG's |
Exchange — Response
Description: The Subscription Server returns the current status of the Subscription ($status), or replays the requested event-notification(s) ($events).
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: for $status, a Bundle of type searchset containing a Parameters resource conforming to backport-subscription-status-r4 (see OperationDefinition backport-subscription-status); for $events, a single Bundle of type history with the subscription status as its first entry, followed by the requested event-notifications (see OperationDefinition backport-subscription-events). On error: a FHIR OperationOutcome.
Additional Notes
-
Used for recovery only; not part of the regular operational flow.
-
The retention period for replayable events is set by the use-case-specific technical agreement (see Requirements on Use-Case-Specific Technical Agreements).
If a Subscription Server does not support the $events operation, a detected gap in the event-number sequence cannot be recovered through this TA's notification mechanism. Reconciliation instead falls to the applicable use-case-specific technical agreement or the underlying resource API, for example by querying the source system for resources of the monitored type changed since the last successfully processed notification. Such a query is subject to the same data-minimisation concern as the search that empty mode requires (see When a Reference Is Preferable to Empty). It also has two limitations. First, a search does not return deleted resources, so missed events for a topic triggered by delete cannot be reconciled this way; a history interaction with _since does return deletions, at the cost of disclosing every intermediate version. Second, notification-event.timestamp is the moment the event occurred, which need not coincide with the resource's meta.lastUpdated, so a query period based on it needs a margin, with any duplicates processed idempotently. This TA does not define such a reconciliation mechanism (see Requirements on Use-Case-Specific Technical Agreements). A Subscription Client SHOULD take a Subscription Server's non-support of $events into account when creating a Subscription, or accepting the handshake of an out-of-band Subscription, with payload mode id-only or full-resource: in empty mode the receiver retrieves changes by query after each notification anyway, whereas a missed id-only or full-resource notification is not compensated by the next one.
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 requires a use-case-specific technical agreement that meets the requirements below.
Requirements on Use-Case-Specific Technical Agreements
The requirements in this section apply to the authors of a use-case-specific technical agreement that applies this TA. They are assessed when such an agreement is drawn up or changed, not in the certification of implementations. A use-case-specific technical agreement that applies this TA:
-
SHALL define each SubscriptionTopic it uses, meeting the requirements in Resource Definitions → SubscriptionTopic, including how the patient an event concerns is resolved and the value form of each filter parameter. For events that by design concern no identified patient, it SHALL state why the data involved is not identifying, and on what basis it may be disclosed;
-
SHALL state, for each topic, whether it monitors a workflow resource or a data resource, and why (see Choosing a Resource Type to Monitor);
-
SHALL state, for each topic, which payload mode or modes are permitted (see Payload Mode Agreement and Enforcement). Where a topic is triggered by delete, empty mode SHALL NOT be permitted unless the agreement states how the receiver determines which resource was deleted, since a search does not return deleted resources;
-
SHALL state, for each topic, whether Subscriptions are created in-band, out-of-band, or both (see Subscription Server);
-
SHALL state, for each topic, whether heartbeats are used and at what interval; for out-of-band Subscriptions, this agreement is the only place where this is settled (see Heartbeat Notification);
-
SHALL state whether $events is required and, if so, the retention period for replayable events. Where $events is not required, it SHALL state the reconciliation route for missed notifications, or state that none applies. A reconciliation route based on search SHALL be limited to the monitored resource type, the Subscription's filter criteria, and the period of the gap, and SHALL state how missed deletions are reconciled where the topic is triggered by delete (see $status and $events Operations);
-
SHALL state the maximum retry duration for the delivery of handshake, heartbeat and event notifications, after which retries are exhausted and the Subscription is set to off (see Implementation Obligations);
-
SHALL decide, for each topic that monitors a broadly accessible resource, whether id-only with a shared id, id-only with per-recipient ids, or empty mode is used (see When a Reference Is Preferable to Empty);
-
SHALL identify the processing basis and authorization conditions that apply, per GF Authorization and GF Toestemming (and, where applicable, EHDS) (see Privacy, Consent, and Authorization).
Any routing information the receiver needs to determine which internal process a notification concerns is also defined there; this TA carries no such information in the notification itself.
Appendix A: Id Construction — Illustrative Examples
This appendix illustrates constructions that satisfy or fail the requirements in Requirements for Using Id-Only. It is informative: the requirements themselves, not this appendix, are what an id must be checked against.
Schemes That Fail
Several id constructions are known to fail the stability, opacity, or unpredictability requirements stated in Requirements for Using Id-Only, 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 id should be checked against the requirements themselves, not just against this list.
Ordered ids (sequential counters) — reveal creation order and volume, are guessable, and let a reader infer that a resource exists between two ids it has seen. Fails the opacity and unpredictability requirements.
Time-encoding ids (UUIDv1, UUIDv7) — reveal the moment of creation. Fails the opacity requirement.
Concatenated ids (e.g., department plus patient number plus date) — reveal content directly. Fails the opacity requirement.
Derived ids (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 ids — 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 ids (freshly generated per request) — opaque but not stable; they break lookup and deduplication for every receiver downstream. Fails the stability requirement.
A resource identified only by an id from a failing scheme should be exchanged under empty mode, not id-only.
Id 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 id from the Random example carried in an actual notification.
Any construction must also yield a valid FHIR id: at most 64 characters, drawn from A–Z, a–z, 0–9, "-" and "." (FHIR R4, id datatype). This excludes, for example, base64url encoding, which uses "_", and limits the length of the value that can be encoded.
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 such as HMAC (RFC 2104 / FIPS 198-1), with a hash function and key length that are, at the time of implementation, considered secure (e.g. HMAC-SHA-256 or stronger). The same resource always produces the same id (stability). Without the secret key, the id cannot be linked to the source's internal reference, nor computed or confirmed from it (opacity and unpredictability), provided the output is long enough to make guessing impractical.
These properties depend entirely on the secrecy of the key. The internal reference is typically low-entropy, such as a sequential database key, so anyone who obtains the key can compute the id of every resource. For the construction to hold, the source is required to keep the key secret. Changing the key changes every id and thus breaks stability; replacing a key requires a transition for existing ids, which is outside the scope of this TA.
A keyed hash cannot be reversed, so the source resolves an incoming id by storing or indexing the computed id with the resource, as with a random id. The advantage of this construction is that the id can be recomputed from the internal reference, rather than having to be generated and stored first.
Source value: Task/4711 Resulting id: j5xw6z3vnfxgk4ttmvwgc3dj
Constructing an Id: Per-Recipient
A variant of the keyed transformation above, inheriting the same stability, opacity, and unpredictability properties, and the same dependence on the secrecy of the key from which the per-receiver keys are derived. Each receiver ends up with a different id 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 ids 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
Per-recipient ids provide this protection only if they are applied consistently, which has consequences beyond the notification itself:
-
The resource returned on retrieval MUST carry the same per-recipient id in
Resource.id; otherwise the receiver learns the shared id and the protection is lost. -
References inside the returned resource (e.g.
Task.for,Task.focus) disclose the ids of other resources. Unless those are per-recipient too, receivers can still link through them. In practice, per-recipient ids therefore amount to a per-recipient view of every resource the receiver can retrieve. -
The source must resolve an incoming per-recipient id to its internal resource, both on retrieval and on any update by the receiver. Since a keyed hash cannot be reversed, this requires either a stored mapping per receiver, or a reversible keyed construction such as deterministic authenticated encryption (e.g. AES-SIV, RFC 5297).
-
An id that the receiver passes on to a third party, for instance when care is handed over, does not resolve for that third party.
Whether these consequences are acceptable for a given exchange is part of the decision on broadly accessible resources (see When a Reference Is Preferable to Empty).
Changes since 0.6
-
Title. Renamed from TTA Notifications to TA Notifications, as the TA is not intended for Twiin use only. (editorial)
-
Introduction. Scope narrowed to FHIR R4; R4B is no longer an implementation option. Informative block added on the differences in R4B and R5. The independence of the FHIR version of referenced resources also covers additional-context. (technical)
-
Introduction. Linguistic corrections; "doctors, patients or system users" replaced with "healthcare professionals, patients, or the systems they use"; the sentence on the exchange of notifications rephrased. (editorial)
-
Context. Short description of the BgZ added, including its English name (Common Clinical Dataset). (editorial)
-
Scope (In scope). Selection and coding of topics narrowed to the mechanism by which topics are scoped and narrowed. Consent broadened to processing basis. (technical)
-
Scope (Exclusions). Added: patterns that combine a notification with a subsequent retrieval, merged with the exclusion of the retrieval itself, and the definition of specific SubscriptionTopics. The cancellation exclusion was reworded: a sent notification cannot be recalled, and a notification relationship is ended by setting the Subscription to off. (technical)
-
Vocabulary. Subscription Server and Subscription Client added. id and identifier distinguished, and "identifier" replaced with "id" throughout the id-only sections. focus located in the subscription status Parameters resource and stated as absent in empty mode. "Literal reference" used consistently. zorgaanbieder and GTK added. (editorial)
-
Vocabulary. Notification, SubscriptionTopic and criteria redefined for R4; the topic canonical is carried directly in Subscription.criteria. Subscription defined as an agreement, covering in-band and out-of-band creation. Filter syntax per the Backport IG. (technical)
-
Notification Payload Model. The server may no longer modify a requested payload mode; it accepts or rejects the Subscription. (technical)
-
Notification Payload Model. Link to the Backport IG payload modes added. Description of empty mode corrected: the Subscription reference is present in every notification. (editorial)
-
Authorization and Processing Basis for the Push Pattern. Renamed; requirements replaced with a reference to Privacy, Consent, and Authorization. Full-resource mode described without reference to Notified Pull. (editorial)
-
Payload Selection when the Receiver Retrieves Content Afterwards. Renamed from Payload Selection for the Notified Pull Pattern. No fixed sequence between notification and access basis is implied; Notified Pull is given as an example. (editorial)
-
Data exposed by an id-only notification. Renamed from Parties Exposed by an Id-Only Notification. Stated that a compliant id still discloses recurrence, and that notification metadata is disclosed regardless of the id. (editorial)
-
Requirements for Using Id-Only. Stability qualified for per-recipient ids. (technical)
-
When a Reference Is Preferable to Empty. Overclaim on disclosure through search corrected: this is a data-minimisation concern, not an access-control concern. The reference is to be sent as an absolute URL. The choice for broadly accessible resources is delegated to the use-case-specific technical agreement. (editorial)
-
Empty Mode with a Leaked Id Is Pseudo Id-Only. Corrected: the defect lies in the undeclared channel, not necessarily in how the id is constructed. (editorial)
-
Payload Mode Agreement and Enforcement. Pre-agreement limited to the SubscriptionTopic and the payload mode; filter values need no pre-agreement. The payload mode is immutable, and a change requires a replacement Subscription. The notification format may be changed by the party that created the Subscription. The receiver may reject a handshake for a topic it has not agreed to, using the topic carried in the handshake. (technical)
-
Payload Mode Agreement and Enforcement. "Content field" replaced with the backport-payload-content extension. Links to in-band and out-of-band managed Subscriptions added. Clarified that a successful handshake does not constitute agreement on the payload mode. (editorial)
-
Notification Patterns. Opening sentence made independent of Notified Pull. Source initiated notifications require the receiver to have agreed to the topic. (technical)
-
Signal Fatigue and Specificity. Recommendation extended to Subscription-level filter criteria. (technical)
-
Privacy, Consent, and Authorization. Consent broadened to processing basis. The patient-specific check at activation was removed; patient-specific verification takes place per notification. For in-band creation, the Client's authorization for the topic is verified before acceptance. Repeated requirements replaced with references. For events that by design concern no identified patient, only authorization for the topic is verified; the use-case-specific technical agreement substantiates why the data is not identifying. (technical)
-
Preconditions. Added: verification of an in-band channel.endpoint against GF Addressing, and application-layer verification by the Subscription Client of the sending zorgaanbieder. The activation precondition replaced by topic authorization for in-band creation and verification before each notification. Verification of an in-band channel.endpoint made an obligation before acceptance; the Client's verification of the sending zorgaanbieder stated as an obligation. (technical)
-
Authorization for Sender-Initiated Pulls. New section: an authorization value may accompany a sender-initiated notification, with its meaning and use delegated to GF Authorization and TA Pull. (technical)
-
Conformance. Backport IG pinned to version 1.1.0 (STU 1.1), R4 package. (technical)
-
Sequence Diagram. Described as a generic notification mechanism rather than Notified Pull; caption aligned with the six steps. Step 1 corrected for the source initiated pattern. Step 3 no longer implies focus in empty mode. (editorial)
-
Sequence Diagram. In-band: the server endpoint is resolved via GF Addressing (payloadType Subscription) and topics are discoverable via the CapabilityStatement. Out-of-band: the notification endpoint is resolved via payloadType Notification instead of Subscription. Codes referenced to the GF Addressing code system; fhirVersion=4.0 required in payloadMimeType; Endpoint ownership via Organization.endpoint clarified. (technical)
-
Subscription Server. Described against the Backport IG Subscription Server CapabilityStatement, with additions by this TA marked. (editorial)
-
Subscription Server. In-band support made conditional on the use-case-specific technical agreement; where supported, Updating a Subscription is required. Registration of the FHIR base URL in GF Addressing (payloadType Subscription) required. Support for both JSON and XML required. Search parameters corrected to R4 and Backport IG codes. Advertising supported topics in the CapabilityStatement recommended. (technical)
-
Subscription Client. Minimum actions on a gap in event-number added: log the gap and query $status. Verification of the sending zorgaanbieder added. At least one of JSON or XML required. Heartbeat monitoring changed from MAY to SHOULD, including a comparison with events-since-subscription-start. In-band Subscriptions are retired or changed through Updating a Subscription. (technical)
-
Implementation Obligations. Authorization and processing-basis verification take place before each notification, including each retry and each replay through $events; for in-band creation, topic authorization is verified before acceptance. Retry extended to 429 and Retry-After, and assigned to the sending party of each transaction; the maximum retry duration is set by the use-case-specific technical agreement. New obligation on delivery failure: status error while retrying, off when retries are exhausted. Idempotency extended to replaced Subscriptions. (technical)
-
Implementation Obligations. Logging distinguished from NEN 7513. References to R4B replaced with the Backport IG. (editorial)
-
Resource Definitions → Notification. Profile corrected to backport-subscription-notification-r4. The subscription reference must be an absolute URL, whose base URL the Subscription Client verifies. topic required in every notification. Status values extended with requested and error. Type codes corrected to handshake and heartbeat, with query-status and query-event added. Request required on every entry. event-number increases by one per event notified; a withheld notification receives no event-number, and events-since-subscription-start counts accordingly. Timestamp required, and identical across Subscriptions. events-since-subscription-start required in heartbeats. Entry content per payload mode specified. (technical)
-
Resource Definitions → Notification. Authorization value added in the authorization-type and authorization-value parts, following the Backport IG 1.2.0 ballot: opaque, unpredictable, single-use or time-bounded, and only for sender-initiated Subscriptions. (technical)
-
Resource Definitions → SubscriptionTopic. Rewritten as a design-time definition in the use-case-specific technical agreement. The single resource type is stated as a choice of this TA. canFilterBy and queryCriteria replaced with filter parameters and trigger conditions. The topic definition states how the patient an event concerns is resolved, including events that by design concern no identified patient. New subsection Choosing a Resource Type to Monitor. Filter parameter definitions include the value form; the URA is recommended for organisation filters. (technical)
-
Resource Definitions → Subscription. Backport Subscription profile referenced; the topic canonical is carried in Subscription.criteria. Multiple filters allowed, in the filter syntax of the Backport IG. XML permitted, and the out-of-band format is set per the client's capability. Omission of backport-payload-content allowed for in-band only. Id requirements made subject to opacity and unpredictability. backport-heartbeat-period added. (technical)
-
Resource Definitions → Subscription. "When created in-band" qualifier removed. (editorial)
-
Transactions. Requirements beyond the Backport IG marked per transaction. Content-Type and Accept headers updated for JSON and XML. (editorial)
-
Creating a Subscription. Example corrected: canonical in criteria, filter in Backport IG syntax with a URA value. Out-of-band creation requires the receiver's agreement to the topic rather than an authorization check; in-band acceptance requires topic authorization. Retirement assigned per creation mode. Mismatch of the in-band channel.endpoint rejected with 422. (technical)
-
Updating a Subscription. New transaction: retirement and format change of in-band Subscriptions by the creating Client; other changes require replacement; status maintained by the server. (technical)
-
Replacing a Subscription. New section: overlap, deduplication by focus and timestamp, recovery on the replaced Subscription, zorgaanbieder association, and retirement of a replaced in-band Subscription through Updating a Subscription. (technical)
-
Handshake Notification. Status set to error on any handshake error, as required by the Backport IG; transient errors are retried, with active on success and off when retries are exhausted; a rejected handshake ends in off. Response table split into transient errors (429, 5xx, network) and permanent errors (other 4xx). Example corrected; topic added. (technical)
-
Event Notification. The 422 response for event-number out of sequence removed; receivers may not reject notifications on sequence grounds. Retry and error behaviour added: error while retrying, off when retries are exhausted; a rejected notification counts as notified. Example and its explanation corrected: the second entry records the triggering interaction, not a retrieval; topic added. (technical)
-
Heartbeat Notification. Rationale corrected: heartbeats serve the Subscription Client in both patterns. The interval in effect is the one returned by the server. Response table corrected and split, with error while retrying and off when retries are exhausted. Use and interval set by the use-case-specific technical agreement. Example: topic added. (technical)
-
$status and $events Operations. Search parameters corrected; reference to the operation parameters added; response payloads corrected to a searchset Bundle ($status) and a history Bundle ($events). The content parameter of $events is ignored; replays follow the payload mode and are subject to verification. $events marked as optional in the roles table. Retention period set by the use-case-specific technical agreement. Recovery route and limitations of search-based reconciliation described where $events is not supported. (technical)
-
Using This TA. Requirements on use-case-specific technical agreements consolidated into one subsection, assessed when such an agreement is drawn up rather than in certification. Requirements added for the value form of filter parameters and the maximum retry duration. (technical)
-
Appendix A: Id Construction. Schemes That Fail and Id Examples moved to an informative appendix. HMAC guidance, dependence on the key, id resolution, consequences of per-recipient ids, and FHIR id constraints added. (technical)