FHIR CI-Build

This is the Continuous Integration Build of FHIR (will be incorrect/inconsistent at times).
See the Directory of published versions icon

3.9 Topic-Based Subscriptions Framework

FHIR Infrastructure icon Work GroupMaturity Level: 0Standards Status: Draft

Subscriptions are used to establish proactive event notifications from a FHIR server to another system. Servers which have implemented support for Subscriptions will advertise their use via the resources Subscription and SubscriptionTopic. Interactions and operations allowed on these resources may be discovered via the FHIR Application's CapabilityStatement.

Any FHIR application may support the use of Subscriptions. In this documentation:

  • Server refers to the FHIR application or applications acting as the subscription provider. This includes the responsibilities of implementing one or more SubscriptionTopics, managing Subscriptions, and sending notifications.
  • Client or Subscriber refers to the application or applications requesting topic-based notifications. This includes the responsibilities of acting as a FHIR client (to create a Subscription) and receiving notifications on a supported channel.
  • Endpoint refers to the portion of the client which is responsible for receiving notifications, if applicable. For example, when using the rest-hook channel type the endpoint is the HTTP server listening for notifications. While part of the client, it is often useful to refer to the endpoint separately for clarity.
Note: either role may be implemented by one or more applications across one or more systems.

The Subscriptions Framework in FHIR is a mechanism used to send notifications from a server to a client based on activity occurring in the server.

The Subscription mechanism is composed of three parts:

  • SubscriptionTopic resources
    • Define the data and change or event used to trigger notifications
    • Define the filters allowed to clients
    • Are always referenced by canonical URL
  • Subscription resources
    • Describe a client's request to be notified about events defined by a SubscriptionTopic
    • Set actual filters, as defined in the referenced SubscriptionTopic
    • Describe the channel and endpoint used to send notifications
    • Describe the payload included in notifications (MIME type, content level, etc.)
  • subscription-notification Bundles
    • Describe a notification, using a SubscriptionStatus
    • Contain zero or more notification payloads

Definitionally, a Subscription requires a SubscriptionTopic - without a resource describing an event or change of interest, a Subscription would have no meaning.

While active, a Subscription relies on both Bundle and SubscriptionStatus for sending notifications.

When using the Subscription resource, the FHIR server combines the roles of publisher and information distributer. Some arrangements of the 'publish and subscribe' pattern describe separate agents for the two roles. This specification makes no recommendations towards the internal architecture of server implementations.

While the FHIR REST API describes a polling-based method for observing events using bundles and the history operation, polling can cause processing delays (e.g., time between polling operations) and incur costs in:

  • computation - e.g., processing queries when there are no state changes;
  • connectivity - e.g., many clients connecting regularly when there are no state changes; and
  • energy - e.g., mobile devices needing to 'wake up' and poll regularly.

Note that topic-based subscription capabilities have been added to the core specification as of FHIR R5. In order to facilitate adoption, a Backport Implementation Guide icon is available to provide the equivalent functionality in some earlier versions of FHIR. When using earlier versions of FHIR supported by the IG, cross version extensions SHOULD NOT be used on Subscription resources to describe any elements described by that guide.

FHIRcast icon is a framework for user-activity synchronization across applications. FHIRcast and Subscription are both conceptually based W3 WebSub icon, and while the mechanics of two projects look similar, they are fundamentally different projects used to address different use cases. In particular:

  • FHIRcast is designed to be used by multiple applications perhaps with the same user and typically on the same device

    Subscriptions are designed to be used by multiple distinct systems, often outside of a user workflow

  • FHIRcast sends only single-event notifications

    Subscriptions allow servers to batch multiple notifications in high-frequency scenarios

  • FHIRcast is designed around short-lived sessions

    Subscriptions are intended to be long-lived resources

FHIR Messaging is a message-based protocol which can be used for communication. When combining Messaging and Subscriptions, complete notifications are wrapped into Messaging Bundles. More details are provided below.

This section gives an overview of the workflow for both Servers and Clients to work with Subscriptions. Each channel MAY vary slightly from this general overview - specifically around interactions involving the Endpoint (e.g., when using a rest-hook the client must pre-configure an HTTP endpoint which the server validates, but when using a websocket the client simply connects to the server).

A workflow for creating a subscription is below:

Sequence diagram of creating a FHIR Subscription
Sequence diagram of creating a FHIR Subscription
  1. Server implements the core functionality required for topic-based subscriptions.
  2. Server implements one or more SubscriptionTopic resources. Implementation is specific to each topic, and will vary between servers.
  3. Client asks the server for the list of supported SubscriptionTopic resources, via querying the resource.
  4. Server responds with a searchset Bundle.
  5. Client ensures that the endpoint is prepared (if applicable - see channels).
  6. Client requests a Subscription (e.g., via HTTP POST, HTTP PUT, etc.).
  7. Server MAY accept the Subscription request (e.g., supported channel and payload). Note that the server MAY modify the request to be suitable (e.g., changing heartbeat timeouts, etc.). Clients SHALL check the returned resource or query for the accepted version if not returned to ensure an accepted request conforms with their expectations.
  8. Server MAY reject the Subscription request (e.g., unsupported channel type).
  9. If applicable, the server MAY send a handshake to the endpoint.
  10. If the Server sends a handshake, the endpoint SHALL respond appropriately, or the Server MAY deactivate the subscription.

Once the subscription is active, notifications will be sent according to the channel. Note that error states may occur, see Managing Subscriptions and Errors for more information.

The SubscriptionTopic resource is used to define conceptual or computable events for Subscription resources. Conceptually, subscription topics specify:

  • What causes a notification, either by referencing an event definition in an event trigger (e.g., http://example.com/fhir/events#something-interesting-happened) or by describing a resource state change in a resource trigger (e.g., an Encounter is created or updated to have an Encounter.state of active).
  • What filters a client is allowed to request. For example, a topic that allows clients to restrict notifications to a particular patient id or group, a specific procedure, etc., relevant to that particular topic.
  • What related resources the server MAY include in notifications. For example, while a discharge notification would likely be focused on the Encounter resource, since that is the resource that is updated, it is likely desireable to include the patient information, observations, diagnosed conditions, location information, etc.

Subscription Topics are intended to be discoverable, reusable, and extensible. Definitions should be defined in a computable way whenever possible, but the conceptual definition is the arbiter between any discrepancies. For example, a query-based and a FHIRPath-based definition may differ slightly because of what is expressible in each language. In such cases, the goal is correct implementation of the concept - not literal translations between computable definitions.

More details about defining and deriving subscriptions topics can be found on the SubscriptionTopic resource page, specifically in the sections Defining Subscription Topics and Deriving from Existing Subscription Topics.

Example and Canonical Subscription Topics can be found at registry.fhir.org icon. It is strongly suggested that implementers reuse existing topics and submit new topics whenever possible for better compatibility.

Subscription Topics can be defined across multiple resource types. For example, a single topic could be defined to trigger when a Patient has a new Observation, Condition, or Procedure. Alternatively, a system could be interested in notifications based on any Resource being deleted. In either case, it is desireable to be able to trigger notifications across more than one resource type. If all of the resource have a logical grouping in the FHIR hierarchy, the lower-level resource type can be used. For example, for notifications across all resources, the value Resource can be used directly. If there is no lower-level grouping, each resource must be listed individually in the appropriate elements of the topic (e.g., multiple SubscriptionTopic.resourceTrigger elements, each with the correct resource).

The Subscription resource is used to request notifications for a specific client about a specific topic (as defined by a SubscriptionTopic). Conceptually, a subscription specifies: a topic (SubscriptionTopic), the notification channel (e.g., REST, websockets, email, etc.), and the notification payload (e.g., MIME type, amount of detail, etc.). Detailed information about channel-types and payload configuration can be found on the Subscription resource page.

When a FHIR Server accepts a request to create a Subscription, the server is indicating to the client that the server:

  • is capable of detecting when events covered by the requested SubscriptionTopic occur, and
  • is willing to make a simple best effort icon attempt at delivering a notification for each occurrence of a matching event.

When processing a request for a subscription, following are some checks that a server SHOULD validate:

  • that the SubscriptionTopic is valid and implemented by the server
  • that all requested filters are defined in the requested topic and are implemented in the server
  • that the channel type is known and implemented by the server
  • that the channel endpoint is valid for the channel provided (e.g., is it a valid URL of the expected type)
  • that the payload configuration is known and implemented by the server
  • that the payload configuration is valid for the channel type requested (e.g., complies with the server's security policy)

If allowed by a topic, notifications for a single subscription can be triggered on multiple resource types. A topic can also define filters that apply to some or all triggering resource types. Note that if the resourceType is not specified, the server MAY either reject the request, determine at the time of creation which resources the parameter is applied to, or test each resource at runtime.

For example, if a topic is defined for both Observation and Condition resources, the patient search parameter is defined across both types and the same value will apply to either. However, if the code search parameter is used, receivers will likely want to specify the filters independently with different values for observations vs. conditions. Filters only apply to the resources they are listed by. For example, a filter for the Condition.onset-age parameter is not used when a topic triggers on an Observation. Note that this is true even if links exist between resources.

The same behavior applies to lower-level resources, e.g., Resource. If a topic allows for filtering on common search parameters such as _language, _source, or _tag, it is logical to apply each of those parameters to every resource. If a non-generic search parameter is allowed (e.g., patient) and a resourceType is unspecified or too broad, the server could choose to reject the request, determine subsets at the time of creation, or test each possible notification individually.

When multiple filters are specified, all filters that apply to a resource must match in order for the resource to be considered a match. For example, if a subscription allows for filters for both the Patient.address-state and Patient.birthdate search parameters, a subscription specifying both address-state=WI and birthdate=ge2000 would only match resources that identify a person born in the year 2000 or later and currently living in Wisconsin.

The SubscriptionStatus resource is used to encapsulate information about a subscription and meta-information about the notification itself (e.g., how many events are included, etc.). There are currently two areas where the resource is used: in subscription-notification Bundles and as the return type for the $status operation.

Unless otherwise specified by a server implementation and channel, the Subscriptions Framework does not involve guaranteed icon delivery of notifications; channels are assumed to be simple best-effort icon unless otherwise specified. While the Subscriptions Framework is able to support such mechanisms, defining channels using them is beyond the scope of the standard at this time.

Subscribers should be aware of some limitations regarding delivery. In particular:

  • Some notifications might not be delivered.
  • Some notifications might be delivered multiple times.

In order to mitigate the impact from the above issues, the Subscriptions Framework includes mechanisms to detect both scenarios. More information can be found below.

In order to claim conformance with this guide, a server:

  • SHALL support the Subscription resource
    • read support is required
    • write support is required
    • search support is recommended
  • SHALL support the $status operation on the Subscription resource.
  • SHALL support the SubscriptionTopic
    • read support is required
    • search support is required
  • SHALL support at least one channel type, and SHOULD include one from the core-defined channel types
  • SHALL support at least one Payload Type

Some options of the Subscriptions Framework are not easily expressed in a CapabilityStatement. In addition to the basic support in the CapabilityStatement (e.g., resources, interactions, and operations), a conformant server SHALL support at least one Payload Type and SHOULD support one Channel Type defined in the core specification. While channel information is not currently discoverable via capabilities, server implementers are expected to document their support out-of-band so that developers can understand support. Client developers (subscribers) are unlikely to implement more than a few channel types, so it is unlikely that a client is able to "try and error" too many times. Note that a future publication of FHIR may include more functionality regarding capabilities; this guidance will evolve with any changes.

Applications are responsible for following FHIR security guidance. Some recommendations specific to subscriptions are provided below.

A subscription is a request for future event notifications. As with any client-initiated interaction, a Subscription could request information a client is not allowed to see. Applications SHALL enforce authorization in accordance with their policy requirements. Applications SHOULD take a subscription's SubscriptionTopic and filters into account when authorizing the creation of a Subscription, and SHOULD ensure that authorization is (still) in place when sending any event notifications.

When sending an event notification, applications can adopt various strategies to ensure that authorization is still in place. Some strategies may provide imperfect assurance (e.g., a server might rely on signed tokens with some pre-specified lifetime as evidence of authorization). In addition to these strategies, servers can mitigate the risk of disclosing sensitive information by limiting the payload types it supports (e.g., by prohibiting certain clients from requesting full-resource notification payloads and relying instead on id-only payloads).

When implementing channels, implementers should be aware of security best-practices for those protocols. For example, when implementing the REST-hook channel type, it is strongly recommended to use HTTPS instead of HTTP. In general, use of protocols that transmit data unencrypted is strongly discouraged.

Implementors should note that security and privacy considerations can also prohibit notifications from being generated, in addition to considerations about sending notifications. For example, if a resource is deleted because it was "Entered in Error", a server may choose to not send a notification or could include special handling for those cases (e.g., sending a predefined notification message indicating that a patient should disregard a prior notification). Similarly, if a patient has decided that a category of lab results are confidential, practitioners without appropriate consent for disclosure should not receive any indication of those results (e.g., a server cannot generate a notification event for them).

Subscription resources are not intended to be secure storage for secrets (e.g., OAuth Client ID or Tokens, etc.). Implementers MAY use their judgement on including limited-use secrets (e.g., a token supplied in a Subscription.parameter to verify that a message is from the desired source). Server implementations SHOULD be aware that data contained in a Subscription can be sensitive (e.g., privileged endpoint URLs) and take appropriate steps to prevent unauthorized access.

Each notification sent by the application could reveal information about the application and subscriber relationship, as well as sensitive administrative or clinical information. Applications are responsible for ensuring appropriate security is employed for each channel they support. The Subscription resource does not address these concerns directly; it is assumed that these are administered by another configuration processes. For instance, an application might maintain a whitelist of acceptable endpoints or trusted certificate authorities for rest-hook channels.

Some topic and server implementation combinations may trigger internal notification workflows when notifications SHOULD NOT be sent. For example, if a topic is designed around Observation resources being removed (e.g., deleted), an implementation may be triggered if an Observation is moved to a higher security level and is no longer available to a user. These types of situations are implementation-specific, so this note is to raise awareness of potential pitfalls when implementing subscriptions.

Subscribers should ensure an appropriate process to validate incoming messages. For example, if the full-resource content type is used, clients should provide a header or some other secret to the server so that messages can be verified prior to being used for health decisions. Using content types of empty or id-only can mitigate this risk, as resources must be retrieved from a trusted location prior to use. Additionally, subscriber implementations should be defensive about the processes spawned when receiving a notification. For example, if data-receipt always directly triggers a query to a FHIR server, bad actors could generate fake notifications across several clients in order to overload a destination server (denial of service).

Subscribers should be aware of, and protect against, the possibility of being used as part of an attack on a FHIR server. For example, a malicious client may send a large volume of fake notifications with empty notifications, which would cause the subscriber to send many (potentially expensive) queries to a server.

Servers implementing Subscriptions are responsible for complying with their policies on information logging. Servers are encouraged to track all sent notifications, for example with the use of AuditEvent or Communication resources.

Unless otherwise specified by a server implementation and channel, the Subscriptions Framework does not involve guaranteed delivery of notifications. While the Subscriptions Framework is able to support such mechanisms, defining them are beyond the scope of this specification.

Servers SHOULD detect errors and take appropriate action where possible. In general, this boundary is when the notification is delivered. For example, during a REST-hook notification, the subscription server can detect errors up until the REST endpoint returns a HTTP status code (e.g., 200). This does not imply that a client successfully processed (or even received) a notification - simply that the server has sent the notification successfully.

Clients SHOULD be aware of some limitations regarding delivery. In particular:

  • some notifications might not be delivered, and
  • some notifications might be delivered multiple times.

In order to mitigate the impact from the above issues, the Subscriptions Framework includes mechanisms to detect both scenarios.

The subscription resource is authored by the client with an initial status of requested. A new subscription is created on the server using the RESTful create or update interaction. After a successful "create" interaction, the client parses the Location header of the HTTP response and saves the new Subscription's logical id for use in subsequent operations.

When the server receives a subscription, it SHOULD check that it is prepared to accept/process the subscription. If it is, it sets the subscription to requested and processes it like a normal create. If it isn't, it SHOULD return an error with an OperationOutcome instead of processing the create.

The criteria are subject to the same limitations as the client that created it, such as access to patient compartments etc. Note that the subscription MAY remain active after the client access tokens expire (e.g., if the client's authorization period outlasts the access token lifetime).

Once the server has activated the subscription, it sets the status to active. Note that the server MAY choose to activate a subscription immediately on creation (without any additional processing).

An appropriately authorized client can use search and/or history operations to see what subscriptions are currently active on the server. Once the subscription is no longer desired, the client deletes the subscription from the server.

The server may retry the notification a fixed number of times and/or refer errors to its own alert logs. If the notification fails, the server SHOULD set the status to error and mark the error in the resource. If the notification succeeds, the server SHOULD update the status to active and may remove any error codes. If a subscription fails consistently a server may choose set the subscription status to off and stop trying to send notifications.

Errors a server wishes to make accessible to clients are communicated via SubscriptionStatus.error. Clients MAY receive these errors in notifications sent by the server or detect them by running the $status operation on a subscription. Servers should provide a mechanism for clearing errors (e.g., when resetting a Subscription.status back to requested after an error).

As mentioned in the Notifications Overview, channels for FHIR subscriptions can provide either guaranteed icon (reliable) or simple best-effort icon (unreliable) delivery. While this is a classification of the delivery channel, it can impact the contents of notifications. Note that channels are assumed to be best-effort unless otherwise specified.

The channels defined by this specification (e.g., REST-Hook, Email, etc.) are all categorized as simple best-effort delivery channels; they do not guarantee that a subscribing application has successfully received a notification that has been sent. The simplest case to illustrate is with the Email channel - once a server has sent a message, there is no determination for if a client has received the message.

The Detecting Delivery Errors section of this document describes the mechanisms used to discover and mitigate issues cause by unreliable delivery mechanisms.

Channels can be defined using guaranteed-delivery mechanisms (e.g., message queues). When a channel is defined with this capability, a notification must be processed by the subscribing application before it is considered delivered. In these cases, the server can choose to exclude some of the tracking information from notifications, see the Event Numbering section of the SubscriptionStatus resource for details.

There are several mechanisms available to subscribers in order to understand the current state of notification delivery. Below are some example error scenarios with details about how a subscriber can detect some problem states.

The diagram below shows how a subscriber can use the SubscriptionStatus.eventsSinceSubscriptionStart parameter on received notifications to determine that an event has been missed.

Diagram showing a missed-event detection and recovery workflow
Diagram showing a missed-event detection and recovery workflow

In the above sequence, the subscriber tracks the eventsSinceSubscriptionStart of each received notification (per Subscription). When the subscriber received event 23, the subscriber was aware that the last notification it received was a single notification for event 21. The subscriber then waited an amount of time to ensure that event 22 was indeed missing (and not, for example, still being processed) and started a recovery process. The recovery process itself will vary by subscriber, but should be a well-understood method for recovering in the event of errors.

The diagram below show how a subscriber can use the Subscription.heartbeatPeriod to determine errors which prevent notifications from reaching the endpoint.

Diagram showing broken communication detection and recovery workflow
Diagram showing broken communication detection and recovery workflow

In the above sequence, the subscriber is aware that the heartbeatPeriod has elapsed for a subscription without receiving any notifications. The subscriber then asks the server for the $status of the subscription, and seeing an error, begins a recovery process. As in the previous scenario, the recovery process itself will vary by subscriber, but should be a well-understood method for recovering in the event of errors.

Clients are responsible for devising an appropriate method for recovering from errors. Often, this process will include a series or batch of requests that allow a client to know the current state or a request to the $events operation when available. For example, an application may need to query all relevant resources for a patient in order to ensure nothing has been missed. Once an application has returned to a functional state, it should request the subscription is reactivated by updating the status to either requested or active as appropriate.

Servers MAY choose to support the $events operation, as defined on the Subscription resource. The $events operation allows clients to request events which have occurred in the past. Servers which implement the operation MAY use implementation-specific criteria to restrict availability of events (e.g., most recent 10 events, events within the past 30 days, etc.).

During a recovery process, clients MAY try to retrieve missing events via the $events operation, which should allow processing to continue as normal.