This page is part of the Da Vinci Unsolicited Notifications (v1.0.0: STU1) based on FHIR R4. This is the current published version in it's permanent home (it will always be available at this URL). For a full list of available versions, see the Directory of published versions
FHIR resources can be used to transport patient information relevant to a specific event (e.g. admission, transfer, discharge, change in treatment, new diagnosis) to another provider or the health plan. These resources can communicate the details of who, when, what and where care was delivered and help to ensure timely follow-up as needed. To reiterate, the intent of this guide is to provide a framework to create notifications that can provide enough information to Recipient and/or Intermediary for them to be able understand what the notification is about and complete enough to enable them to determine if and what additional steps they need to take in response to the notification.
This guide follows a simplified FHIR messaging paradigm for notifications employing both the FHIR Messaging Bundle and RESTful interaction using the $process-message
operation for exchanging data. Note that Da Vinci Notifications allow implementers to use only these FHIR messaging components in the same manner as a FHIR RESTful operation without having to fully implement the FHIR messaging framework. But it is also compatible with FHIR messaging as implemented.
The following framework documents how to use FHIR messaging to define the contents of the notification and how to “push” these unrequested notification messages using the $process-message
operation directly to Recipients and Intermediaries. The Admit/Transfer/Discharge Use case demonstrates how to implement an unsolicited notification scenario using the framework.
This project recognizes the existing FHIR (R2-R4) subscriptions framework as well as revisions to the Subscription resource for FHIR R5 for event based subscriptions using SubscriptionTopic and SubscriptionStatus and Bundles of type subscription-notification
. It is anticipated that an equivalent subscription based notification paradigm can be implemented as an alternate to the unsolicited messaging based approach documented here. After FHIR R5 subscription resources are finalized and an implementation guide to enable the implementation of R5-style subscription in FHIR F4 is completed, a future version of this guide will add subscriptions as an alternative workflow.
Preconditions
Assumptions
$process-message
operation endpoint.For every notification, the object that is exchanged is a FHIR message Bundle. It consists of a Bundle identified by the type “message”, with the first resource in the bundle being a MessageHeader resource. The MessageHeader resource has a code - the message event - that identifies the reason for the notification. The Recipient/Intermediary may determine how to process the Notification based this event code. The MessageHeader also carries additional notification metadata. The other resources in the bundle depend on the notification scenario and form a network through their relationships with each other - either through a direct reference to another resource or through a chain of intermediate references.
The message event codes identify the purpose for the notification. For this framework a set of concepts describing the purpose of the Da Vinci unsolicited notification has been created.
These concepts represent a ‘starter set’ and will be supplemented with additional concepts in the future. Note that there is no HL7 v2 messaging equivalent to these codes. However when available, a relationship between concepts in the notification event codes and concepts used in the notification “focus” resource is documented. For example concepts that correspond to the admission transfer and discharge events.
For all Da Vinci Notification Message Bundles, the following resources are mandatory (i.e., data MUST be present) or must be supported if the data is present in the source system (see Must Support definition below). These requirements are illustrated in Figure 3 below. See the Admit/Transfer/Discharge Use Case for an example of the required resources for a particular scenario.
Each Bundle must have:
MessageHeader.focus
Each Bundle must support:
MessageHeader.sender
MessageHeader.responsible
MessageHeader.author
All resources directly referenced by the MessageHeader.focus
resource. Implementers should carefully consider what information they are willing to share and only include those reference elements for the use case in the focus resources. This can be formally defined by profiling the focus resource. For example the Admit/Transfer/Discharge use case focal resource is the Da Vinci Admit/Transfer/Discharge Notification Encounter Profile.
Implementers that use FHIR as their persistence layer may need to modify those resources before assembling the message bundle to avoid sending sensitive or unnecessary data.
MessageHeader.focus
resource. These requirements are use case specific and need to be determined by the implementation community based on their data requirements.The set of resources within the message and their relationship to each other can be represented as an interconnected graph of resources as Figure 3 below illustrates (Note that this is a simplified and incomplete representation of the possible resources in notification message bundle. See Figure 9 for an example of a resource graph for the admission/transfer/discharge scenarios):
The Da Vinci Notification Message can be formally defined in FHIR using a set of FHIR Profiles that constrain links to the message Bundle. The base Da Vinci Notifications MessageHeader Profile and Da Vinci Notifications Bundle Profile are used to define the base constraints for all notification scenarios.
All the profiles that populate the Bundle get enforced by their references and the aggregation element which is constrained to ‘bundled’. This means these references can only point to resources within the same bundle. Therefore, starting with the MessageHeader profile, the profiled resources within the bundle form a chain of links that define the bundle.
A use case specific Notification Bundle is defined by starting with base constraints in the Da Vinci Notifications MessageHeader Profile and Da Vinci Notifications Bundle Profile and creating a more tightly constrained MessageHeader Profile. Resources that are referenced within the Bundle are profiled to complete the Bundle definition. Depending on the use case, existing profiles may be used or new profiles defined.
See the Admit/Transfer/Discharge use case for an example of using FHIR Profiles to define the Bundle.
MessageBundles and GraphDefinition resource are alternative to using profiles to define the message bundles contents. However, at the time of this publication, the implementation community, reference implementations, and validation tooling does not fully support them. FHIR profiling is more mature mechanism and broadly supported by the implementation community, reference implementations, and validation tooling. However, there is no mechanism to enforce profiles in a message on a reverse link because “reverse links” cannot be traversed forward from the MessageHeader. It may also require more artifacts than using MessageDefintion/GraphDefinition.
As shown in Figure 4, when an event or request triggers a notification, the Sender creates a Da Vinci Notification Message Bundle and notifies the Recipient or Intermediary using the $process-message
operation.
$process-message
operation, the Recipient/Intermediary is treated as a “black box” and simply accepts and processes the submitted data and there are no further expectations beyond the http level response as defined in the FHIR specification.
MessageHeader.event
codes. For example, notification-admit
can be used to filter for patient admission notifications.As illustrated in steps 5-8 in the sequence diagram (Figure 4), the Intermediary or Receiver MAY fetch additional data from the Sender after it successfully receives and processes the notification optionally searches and processes the search results. Refer to the US Core Implementation Guide for provider access to patient data.
This guide does not specify a standard discovery process for obtaining the Sender’s FHIR endpoint. Once a suitable approach has been agreed upon and published, it will be referenced in a future version of this guide
After the Intermediary successfully receives and processes the notification and optionally searches and processes the search results, it redistributes the data to the end users. It MAY use this framework (in other words, FHIR messaging and the $process-message
operation) or some other messaging protocol such as Direct, SMS or V2 messaging to forward the notification. Note that the Intermediary MAY customize the content based on the end user (for example, withholding data that a particular care team member does not need).
The sequence diagram in Figure 5 illustrates the steps when forwarding the notification using the Da Vinci Notifications framework.
Forwarding notifications using the Da Vinci Unsolicited Notifications framework is a point to point FHIR RESTful transaction. The intermediary SHALL always modify the MessageHeader as described below and MAY change the other contents of the bundle per agreement between the Intermediary and Sender or Receiver. When forwarding the notification, the Intermediary SHALL:
Bundle.id
and newMessageHeader.id
MessageHeader.sender
to reflect the Intermediary as the new SenderMessageHeader.sender
element.MessageHeader.destination
to reflect the new Recipient/Intermediary.The Provenance resource is required to record changes to the Vinci Notification message bundle when forwarding the notification. The Intermediary SHALL add a [US Core Provenance Profile]((https://www.hl7.org/fhir/us/core/StructureDefinition-us-core-provenance.html) to the message bundle. The Provenance.target
references the MessageHeader and following the guidance provided in Basic Provenance for HIE Redistribution and Transformation:
Provenance.agent.type
= “author” set to the SenderProvenance.agent.type
= “transmitter” set to the IntermediaryIf changes to the bundle contents:
Provenance.agent.type
= “assembler” set to the Intermediary
Examples:
Bundle Content Unchanged
{
"id": "adt-notification-provenance-01",
"resourceType": "Provenance",
"meta": {
"profile": [
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-provenance"
]
},
"target": [
{
"reference": "MessageHeader/messageheader-no-change-scenario-01"
}
],
"recorded": "2020-07-31T16:56:43-07:00",
"agent": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type",
"code": "author",
"display": "Author"
}
]
},
"who": {
"reference": "Organization/dv-notification-sender-01"
}
},
{
"type": {
"coding": [
{
"system": "http://hl7.org/fhir/us/core/CodeSystem/us-core-provenance-participant-type",
"code": "transmitter",
"display": "Transmitter"
}
]
},
"who": {
"reference": "Organization/dv-notification-intermediary-01"
}
}
]
}
See the Admit Notification Intermediate Transmit Bundle for a complete example of this use case.
Bundle Content Changed
{
"id": "adt-notification-provenance-02",
"resourceType": "Provenance",
"meta": {
"profile": [
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-provenance"
]
},
"target": [
{
"reference": "MessageHeader/messageheader-change-scenario-02"
}
],
"recorded": "2020-07-31T16:56:43-07:00",
"activity": {
"text": "Message removed content from original"
},
"agent": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type",
"code": "author",
"display": "Author"
}
]
},
"who": {
"reference": "Organization/dv-notification-sender-01"
}
},
{
"type": {
"coding": [
{
"system": "http://hl7.org/fhir/us/core/CodeSystem/us-core-provenance-participant-type",
"code": "assembler",
"display": "Assembler"
}
]
},
"who": {
"reference": "Organization/dv-notification-intermediary-01"
}
}
]
}
See the Admit Notification Intermediate Translate Bundle for a complete example of this use case.
$process-message
OperationThe $process-message
operation is invoked by the Sender using the POST
syntax:
POST [base]/$process-message
The body of the operation is the Da Vinci Notification Message Bundle containing:
An HTTP Status success code is returned on successful submission.
See the Admit/Transfer/Discharge scenario [Example Transactions] for an example of using the $process-message
operation to send a Da Vinci Notification Message Bundle.
Upon receiving a message, the Receiver/Intermediary may return one of several status codes which is documented in $process-message
definition. For successful transactions 200
, 202
, or 204
SHALL be used. Using a 200
or 204
response to indicate the message is received and processable is preferred over 202
indicating the message is simply received. If an error occurs, an OperationOutcome SHOULD be returned with details documenting the error. Parties should consider impact of failure to send and decide what additional steps to undertake. The following table defines the Sender behavior in response to the following error codes:
Error Code | Sender Behavior |
---|---|
401 ,404 +/- OperationOutcome |
do not attempt to resend the message without addressing the error |
429 +/- OperationOutcome |
resend message but slow down traffic |
500+ +/- OperationOutcome |
may retry resending the message one or more times |
Note that any mechanism of communicating an error after the Receiver/Intermediary has already responded to the Sender will be “out of band”. IF the message cannot be processed and thus the sender address cannot be obtained from the MessageHeader, the sender address could be discovered by inspection of other layers of transport such as is described by the FHIR at Scale Taskforce (FAST) authentication piece for server authorization. See the messaging documentation in FHIR Specification for additional guidance on reliable delivery.
All elements in the Da Vinci Notification profiles have a MustSupport flag. Systems claiming to conform to a profile must “support” the element as defined below:
Must Support on any data element SHALL be interpreted as follows:
As part of the notification message as specified by the Notification Sender CapabilityStatement, the Sender SHALL be capable of including the data elements defined in the Da Vinci Notification profiles that have a MustSupport flag.
The Recipient/Intermediary SHALL be capable of processing resource instances containing the data elements without generating an error or causing the application to fail. In other words Recipient/Intermediary SHOULD be capable of processing the data elements (display, store, etc).
When receiving a notification from the Sender, the Recipient/Intermediary SHALL interpret missing data elements within resource instances as data not present in the Sender’s systems.
If a particular data element is missing and the Sender knows the precise reason for the absence of data, then the Sender SHALL provide the reason for the missing information using “null” values from the value set where they exist or using the dataAbsentReason extension (The assumption is that system implementers will, wherever possible, automate the population of missing values with “null” values without requiring - but providing the option for - manual entry).
Notification Recipient/Intermediary SHALL be able to process resource instances containing data elements asserting missing information without generating an error or causing the application to fail.
Must Support on any data element SHALL be interpreted as follows:
When the Intermediary is sending Da Vinci Notifications, its capabilities are specified by the Notification Forwarder CapabilityStatement. The Intermediary SHALL be capable of including the data elements defined in the Da Vinci Notification profiles that have a MustSupport flag.
The Recipient SHALL be capable of processing resource instances containing the data elements defined in the Da Vinci Notification profiles that have a MustSupport flag without generating an error or causing the application to fail. In other words, the Recipient SHOULD be capable of processing the data elements (displaying, storing, etc).
If a particular data element is missing and the Sender knows the precise reason for the absence of data, then the Sender MAY remove the data elements in the resource instance when distributing the alert notification. The Intermediary SHOULD provide the reason for the missing information using “null” values from the value set where they exist or using the dataAbsentReason extension (The assumption is that system implementers will, wherever possible, automate the population of missing values with “null” values without requiring - but providing the option for - manual entry).
The Recipient SHALL be able to process resource instances containing missing data elements and data elements asserting missing information without generating an error or causing the application to fail.
Refer to the US Core Must Support rules for data query transactions to fetch additional data.