Release 5 Preview #2

This page is part of the FHIR Specification (v4.4.0: R5 Preview #2). The current version which supercedes this version is 5.0.0. For a full list of available versions, see the Directory of published versions . Page versions: R5 R4B R4 R3 R2

2.47 Resource Subscription - Content

FHIR Infrastructure Work GroupMaturity Level: 0 Trial UseSecurity Category: Business Compartments: Not linked to any defined compartments

The subscription resource describes a particular client's request to be notified about a SubscriptionTopic.

The Subscription resource is used to establish proactive event notifications from a FHIR server to another system. Subscribers request event notifications within a predefined SubscriptionTopic that the server supports, and can further refine their notifications by supplying filters. Each SubscriptionTopic resource defines a set of allowed filters (SubscriptionTopic.canFilterBy), which a subscriber refer to within a Subscription resource (Subscription.filterBy). Once a subscription is created, any event matching a specified SubscriptionTopic that meets the filtering criteria will cause a notification to be sent using the provided channel. Notifications are Bundle resources, of type subscription-notification.

Subscriptions are active resources; a server can only accept a subscription if it will execute the specified channel for any resources subsequently received. The subscription is no longer active once it is deleted from the server.

By adjusting Subscription.content, subscribers can request event notifications that include full resource content; or just the ID of the triggering resource; or an empty notification body.

Several channels are defined in the core specification:

  • rest-hook: Notifications are sent via HTTPS POST to the Subscription.endpoint URL (e.g., https://...)
  • websocket: Notifications are sent via WS/S to a client connected via a WebSocket
  • email: Notifications are sent via SMTP/S, S/MIME, or Direct SMTP to the Subscription.endpoint email URI (e.g., mailto:...)
  • message: Notifications are sent via FHIR messaging to the application identified in the Subscription.endpoint URI

Additional channel types can be defined by external implementation guides. See below for further discussion of the various channels.

There is a close relationship between SubscriptionTopic and Subscription.

  • A SubscriptionTopic defines the data and change a Subscription uses to trigger notifications.
  • A Subscription describes a particular client's request to be notified about events defined in a SubscriptionTopic and how those notifications should be delivered.
  • A Subscription may define additional filters to be applied when detecting events for notifications, but only as defined and allowed in the relevant SubscriptionTopic.

The use of Subscriptions requires the use of SubscriptionTopics - without an underlying SubscriptionTopic, a Subscription has no meaning and will not trigger any client notifications.

In use, Subscription relies on both Bundle and SubscriptionStatus for communicating notifications.

As an alternative to subscriptions, the FHIR REST API describes a polling-based method for observing events using bundles and the history operation. This method of polling allows for a more straightforward implementation, but can cause delays in process (e.g., time between polling operations) and may result in higher computational costs on the server (e.g., processing queries when there are no state changes).

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.

FHIRcast is a framework for user-activity synchronization across applications. FHIRcast and Subscription are both conceptually based W3 WebSub , 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 intented to be long-lived resources

FHIR Messaging is a message-based protocol which can be used for communication. While it would be possible to mesh Subscription Notifications into Messaging, the consistency of Subscription notifications would be lost (a driving principle of Subscriptions is that the notification should remain the same regardless of channel). When combining Messaging and Subscriptions, complete notifications are wrapped into Messaging Bundles. More details are provided below.

This resource is referenced by SubscriptionStatus.

This resource does not implement any patterns.

Structure

NameFlagsCard.TypeDescription & Constraintsdoco
.. Subscription TUDomainResourceNotification about a SubscriptionTopic
Elements defined in Ancestors: id, meta, implicitRules, language, text, contained, extension, modifierExtension
... identifier Σ0..*IdentifierAdditional identifiers (business identifier)
... name Σ0..1stringHuman readable name for this subscription
... status ?!Σ1..1coderequested | active | error | off
Subscription State (Required)
... contact Σ0..*ContactPointContact details for source (e.g. troubleshooting)
... end Σ0..1instantWhen to automatically delete the subscription
... reason Σ0..1stringDescription of why this subscription was created
... filterBy Σ0..*BackboneElementCriteria for narrowing the subscription topic stream
.... searchParamName Σ1..1stringFilter label defined in SubscriptionTopic
.... searchModifier Σ0..1code= | eq | ne | gt | lt | ge | le | sa | eb | ap | above | below | in | not-in | of-type
Subscription Search Modifier (Required)
.... value Σ1..1stringLiteral value or resource path
... error Σ0..*CodeableConceptLatest error code or note
Subscription Error Codes (Example)
... channelType Σ1..1CodingChannel type for notifications
Subscription Channel Type (Extensible)
... endpoint Σ0..1urlWhere the channel points to
... header Σ0..*stringUsage depends on the channel type
... heartbeatPeriod Σ0..1unsignedIntInterval in seconds to send 'heartbeat' notification
... timeout Σ0..1unsignedIntTimeout in seconds to attempt notification delivery
... contentType Σ0..1codeMIME type to send, or omit for no payload
MimeType (Required)
... content Σ0..1codeempty | id-only | full-resource
SubscriptionPayloadContent (Required)

doco Documentation for this format

UML Diagram (Legend)

Subscription (DomainResource)A formal identifier that is used to identify this code system when it is represented in other formats, or referenced in a specification, model, design or an instanceidentifier : Identifier [0..*]A natural language name identifying the subscriptionname : string [0..1]The status of the subscription, which marks the server state for managing the subscription (this element modifies the meaning of other elements)status : code [1..1] « The status of a subscription. (Strength=Required)SubscriptionState! »The reference to the subscription topic to be notified abouttopic : Reference [1..1] « SubscriptionTopic »Contact details for a human to contact about the subscription. The primary use of this for system administrator troubleshootingcontact : ContactPoint [0..*]The time for the server to turn the subscription offend : instant [0..1]A description of why this subscription is definedreason : string [0..1]A record of the last error that occurred when the server processed a notificationerror : CodeableConcept [0..*] « Codes to represent subscription error details. (Strength=Example)SubscriptionErrorCodes?? »The type of channel to send notifications onchannelType : Coding [1..1] « The type of method used to execute a subscription. (Strength=Extensible)SubscriptionChannelType+ »The url that describes the actual end-point to send messages toendpoint : url [0..1]Additional headers / information to send as part of the notificationheader : string [0..*]If present, a 'hearbeat" notification (keepalive) is sent via this channel with an the interval period equal to this elements integer value in seconds. If not present, a heartbeat notification is not sentheartbeatPeriod : unsignedInt [0..1]If present, the maximum amount of time a server will allow before failing a notification attempttimeout : unsignedInt [0..1]The mime type to send the payload in - either application/fhir+xml, or application/fhir+json. The MIME types "text/plain" and "text/html" may also be used for Email subscriptionscontentType : code [0..1] « The mime type of an attachment. Any valid mime type is allowed. (Strength=Required)Mime Types! »How much of the resource content to deliver in the notification payload. The choices are an empty payload, only the resource id, or the full resource contentcontent : code [0..1] « Codes to represent how much resource content to send in the notification payload. (Strength=Required)SubscriptionPayloadContent! »FilterByThe filter label (=key) as defined in the `SubscriptionTopic.canfilterBy.searchParamName` elementsearchParamName : string [1..1]The operator to apply to the filter value when determining matches (Search modifiers)searchModifier : code [0..1] « Operator to apply to filter label. (Strength=Required)SubscriptionSearchModifier! »The literal value or resource path as is legal in search - for example, "Patient/123" or "le1950"value : string [1..1]The filter properties to be applied to narrow the subscription topic stream. When multiple filters are applied, evaluates to true if all the conditions are met; otherwise it returns false. (i.e., logical AND)filterBy[0..*]

XML Template

<Subscription xmlns="http://hl7.org/fhir"> doco
 <!-- from Resource: id, meta, implicitRules, and language -->
 <!-- from DomainResource: text, contained, extension, and modifierExtension -->
 <identifier><!-- 0..* Identifier Additional identifiers (business identifier) --></identifier>
 <name value="[string]"/><!-- 0..1 Human readable name for this subscription -->
 <status value="[code]"/><!-- 1..1 requested | active | error | off -->
 <topic><!-- 1..1 Reference(SubscriptionTopic) Reference to the subscription topic being subscribed to --></topic>
 <contact><!-- 0..* ContactPoint Contact details for source (e.g. troubleshooting) --></contact>
 <end value="[instant]"/><!-- 0..1 When to automatically delete the subscription -->
 <reason value="[string]"/><!-- 0..1 Description of why this subscription was created -->
 <filterBy>  <!-- 0..* Criteria for narrowing the subscription topic stream -->
  <searchParamName value="[string]"/><!-- 1..1 Filter label defined in SubscriptionTopic -->
  <searchModifier value="[code]"/><!-- 0..1 = | eq | ne | gt | lt | ge | le | sa | eb | ap | above | below | in | not-in | of-type -->
  <value value="[string]"/><!-- 1..1 Literal value or resource path -->
 </filterBy>
 <error><!-- 0..* CodeableConcept Latest error code or note --></error>
 <channelType><!-- 1..1 Coding Channel type for notifications --></channelType>
 <endpoint value="[url]"/><!-- 0..1 Where the channel points to -->
 <header value="[string]"/><!-- 0..* Usage depends on the channel type -->
 <heartbeatPeriod value="[unsignedInt]"/><!-- 0..1 Interval in seconds to send 'heartbeat' notification -->
 <timeout value="[unsignedInt]"/><!-- 0..1 Timeout in seconds to attempt notification delivery -->
 <contentType value="[code]"/><!-- 0..1 MIME type to send, or omit for no payload -->
 <content value="[code]"/><!-- 0..1 empty | id-only | full-resource -->
</Subscription>

JSON Template

{doco
  "resourceType" : "Subscription",
  // from Resource: id, meta, implicitRules, and language
  // from DomainResource: text, contained, extension, and modifierExtension
  "identifier" : [{ Identifier }], // Additional identifiers (business identifier)
  "name" : "<string>", // Human readable name for this subscription
  "status" : "<code>", // R!  requested | active | error | off
  "topic" : { Reference(SubscriptionTopic) }, // R!  Reference to the subscription topic being subscribed to
  "contact" : [{ ContactPoint }], // Contact details for source (e.g. troubleshooting)
  "end" : "<instant>", // When to automatically delete the subscription
  "reason" : "<string>", // Description of why this subscription was created
  "filterBy" : [{ // Criteria for narrowing the subscription topic stream
    "searchParamName" : "<string>", // R!  Filter label defined in SubscriptionTopic
    "searchModifier" : "<code>", // = | eq | ne | gt | lt | ge | le | sa | eb | ap | above | below | in | not-in | of-type
    "value" : "<string>" // R!  Literal value or resource path
  }],
  "error" : [{ CodeableConcept }], // Latest error code or note
  "channelType" : { Coding }, // R!  Channel type for notifications
  "endpoint" : "<url>", // Where the channel points to
  "header" : ["<string>"], // Usage depends on the channel type
  "heartbeatPeriod" : "<unsignedInt>", // Interval in seconds to send 'heartbeat' notification
  "timeout" : "<unsignedInt>", // Timeout in seconds to attempt notification delivery
  "contentType" : "<code>", // MIME type to send, or omit for no payload
  "content" : "<code>" // empty | id-only | full-resource
}

Turtle Template

@prefix fhir: <http://hl7.org/fhir/> .doco


[ a fhir:Subscription;
  fhir:nodeRole fhir:treeRoot; # if this is the parser root

  # from Resource: .id, .meta, .implicitRules, and .language
  # from DomainResource: .text, .contained, .extension, and .modifierExtension
  fhir:Subscription.identifier [ Identifier ], ... ; # 0..* Additional identifiers (business identifier)
  fhir:Subscription.name [ string ]; # 0..1 Human readable name for this subscription
  fhir:Subscription.status [ code ]; # 1..1 requested | active | error | off
  fhir:Subscription.topic [ Reference(SubscriptionTopic) ]; # 1..1 Reference to the subscription topic being subscribed to
  fhir:Subscription.contact [ ContactPoint ], ... ; # 0..* Contact details for source (e.g. troubleshooting)
  fhir:Subscription.end [ instant ]; # 0..1 When to automatically delete the subscription
  fhir:Subscription.reason [ string ]; # 0..1 Description of why this subscription was created
  fhir:Subscription.filterBy [ # 0..* Criteria for narrowing the subscription topic stream
    fhir:Subscription.filterBy.searchParamName [ string ]; # 1..1 Filter label defined in SubscriptionTopic
    fhir:Subscription.filterBy.searchModifier [ code ]; # 0..1 = | eq | ne | gt | lt | ge | le | sa | eb | ap | above | below | in | not-in | of-type
    fhir:Subscription.filterBy.value [ string ]; # 1..1 Literal value or resource path
  ], ...;
  fhir:Subscription.error [ CodeableConcept ], ... ; # 0..* Latest error code or note
  fhir:Subscription.channelType [ Coding ]; # 1..1 Channel type for notifications
  fhir:Subscription.endpoint [ url ]; # 0..1 Where the channel points to
  fhir:Subscription.header [ string ], ... ; # 0..* Usage depends on the channel type
  fhir:Subscription.heartbeatPeriod [ unsignedInt ]; # 0..1 Interval in seconds to send 'heartbeat' notification
  fhir:Subscription.timeout [ unsignedInt ]; # 0..1 Timeout in seconds to attempt notification delivery
  fhir:Subscription.contentType [ code ]; # 0..1 MIME type to send, or omit for no payload
  fhir:Subscription.content [ code ]; # 0..1 empty | id-only | full-resource
]

Changes since R3

Subscription
Subscription.identifier
  • Added Element
Subscription.name
  • Added Element
Subscription.status
  • Change value set from http://hl7.org/fhir/ValueSet/subscription-status|4.0.0 to http://hl7.org/fhir/ValueSet/subscription-state|4.4.0
Subscription.topic
  • Added Mandatory Element
Subscription.reason
  • Min Cardinality changed from 1 to 0
Subscription.filterBy
  • Added Element
Subscription.filterBy.searchParamName
  • Added Mandatory Element
Subscription.filterBy.searchModifier
  • Added Element
Subscription.filterBy.value
  • Added Mandatory Element
Subscription.error
  • Max Cardinality changed from 1 to *
  • Type changed from string to CodeableConcept
Subscription.channelType
  • Added Mandatory Element
Subscription.endpoint
  • Added Element
Subscription.header
  • Added Element
Subscription.heartbeatPeriod
  • Added Element
Subscription.timeout
  • Added Element
Subscription.contentType
  • Added Element
Subscription.content
  • Added Element
Subscription.criteria
  • deleted
Subscription.channel
  • deleted

See the Full Difference for further information

This analysis is available as XML or JSON.

See R3 <--> R4 Conversion Maps (status = 2 tests that all execute ok. 2 fail round-trip testing and all r3 resources are valid.)

Structure

NameFlagsCard.TypeDescription & Constraintsdoco
.. Subscription TUDomainResourceNotification about a SubscriptionTopic
Elements defined in Ancestors: id, meta, implicitRules, language, text, contained, extension, modifierExtension
... identifier Σ0..*IdentifierAdditional identifiers (business identifier)
... name Σ0..1stringHuman readable name for this subscription
... status ?!Σ1..1coderequested | active | error | off
Subscription State (Required)
... contact Σ0..*ContactPointContact details for source (e.g. troubleshooting)
... end Σ0..1instantWhen to automatically delete the subscription
... reason Σ0..1stringDescription of why this subscription was created
... filterBy Σ0..*BackboneElementCriteria for narrowing the subscription topic stream
.... searchParamName Σ1..1stringFilter label defined in SubscriptionTopic
.... searchModifier Σ0..1code= | eq | ne | gt | lt | ge | le | sa | eb | ap | above | below | in | not-in | of-type
Subscription Search Modifier (Required)
.... value Σ1..1stringLiteral value or resource path
... error Σ0..*CodeableConceptLatest error code or note
Subscription Error Codes (Example)
... channelType Σ1..1CodingChannel type for notifications
Subscription Channel Type (Extensible)
... endpoint Σ0..1urlWhere the channel points to
... header Σ0..*stringUsage depends on the channel type
... heartbeatPeriod Σ0..1unsignedIntInterval in seconds to send 'heartbeat' notification
... timeout Σ0..1unsignedIntTimeout in seconds to attempt notification delivery
... contentType Σ0..1codeMIME type to send, or omit for no payload
MimeType (Required)
... content Σ0..1codeempty | id-only | full-resource
SubscriptionPayloadContent (Required)

doco Documentation for this format

UML Diagram (Legend)

Subscription (DomainResource)A formal identifier that is used to identify this code system when it is represented in other formats, or referenced in a specification, model, design or an instanceidentifier : Identifier [0..*]A natural language name identifying the subscriptionname : string [0..1]The status of the subscription, which marks the server state for managing the subscription (this element modifies the meaning of other elements)status : code [1..1] « The status of a subscription. (Strength=Required)SubscriptionState! »The reference to the subscription topic to be notified abouttopic : Reference [1..1] « SubscriptionTopic »Contact details for a human to contact about the subscription. The primary use of this for system administrator troubleshootingcontact : ContactPoint [0..*]The time for the server to turn the subscription offend : instant [0..1]A description of why this subscription is definedreason : string [0..1]A record of the last error that occurred when the server processed a notificationerror : CodeableConcept [0..*] « Codes to represent subscription error details. (Strength=Example)SubscriptionErrorCodes?? »The type of channel to send notifications onchannelType : Coding [1..1] « The type of method used to execute a subscription. (Strength=Extensible)SubscriptionChannelType+ »The url that describes the actual end-point to send messages toendpoint : url [0..1]Additional headers / information to send as part of the notificationheader : string [0..*]If present, a 'hearbeat" notification (keepalive) is sent via this channel with an the interval period equal to this elements integer value in seconds. If not present, a heartbeat notification is not sentheartbeatPeriod : unsignedInt [0..1]If present, the maximum amount of time a server will allow before failing a notification attempttimeout : unsignedInt [0..1]The mime type to send the payload in - either application/fhir+xml, or application/fhir+json. The MIME types "text/plain" and "text/html" may also be used for Email subscriptionscontentType : code [0..1] « The mime type of an attachment. Any valid mime type is allowed. (Strength=Required)Mime Types! »How much of the resource content to deliver in the notification payload. The choices are an empty payload, only the resource id, or the full resource contentcontent : code [0..1] « Codes to represent how much resource content to send in the notification payload. (Strength=Required)SubscriptionPayloadContent! »FilterByThe filter label (=key) as defined in the `SubscriptionTopic.canfilterBy.searchParamName` elementsearchParamName : string [1..1]The operator to apply to the filter value when determining matches (Search modifiers)searchModifier : code [0..1] « Operator to apply to filter label. (Strength=Required)SubscriptionSearchModifier! »The literal value or resource path as is legal in search - for example, "Patient/123" or "le1950"value : string [1..1]The filter properties to be applied to narrow the subscription topic stream. When multiple filters are applied, evaluates to true if all the conditions are met; otherwise it returns false. (i.e., logical AND)filterBy[0..*]

XML Template

<Subscription xmlns="http://hl7.org/fhir"> doco
 <!-- from Resource: id, meta, implicitRules, and language -->
 <!-- from DomainResource: text, contained, extension, and modifierExtension -->
 <identifier><!-- 0..* Identifier Additional identifiers (business identifier) --></identifier>
 <name value="[string]"/><!-- 0..1 Human readable name for this subscription -->
 <status value="[code]"/><!-- 1..1 requested | active | error | off -->
 <topic><!-- 1..1 Reference(SubscriptionTopic) Reference to the subscription topic being subscribed to --></topic>
 <contact><!-- 0..* ContactPoint Contact details for source (e.g. troubleshooting) --></contact>
 <end value="[instant]"/><!-- 0..1 When to automatically delete the subscription -->
 <reason value="[string]"/><!-- 0..1 Description of why this subscription was created -->
 <filterBy>  <!-- 0..* Criteria for narrowing the subscription topic stream -->
  <searchParamName value="[string]"/><!-- 1..1 Filter label defined in SubscriptionTopic -->
  <searchModifier value="[code]"/><!-- 0..1 = | eq | ne | gt | lt | ge | le | sa | eb | ap | above | below | in | not-in | of-type -->
  <value value="[string]"/><!-- 1..1 Literal value or resource path -->
 </filterBy>
 <error><!-- 0..* CodeableConcept Latest error code or note --></error>
 <channelType><!-- 1..1 Coding Channel type for notifications --></channelType>
 <endpoint value="[url]"/><!-- 0..1 Where the channel points to -->
 <header value="[string]"/><!-- 0..* Usage depends on the channel type -->
 <heartbeatPeriod value="[unsignedInt]"/><!-- 0..1 Interval in seconds to send 'heartbeat' notification -->
 <timeout value="[unsignedInt]"/><!-- 0..1 Timeout in seconds to attempt notification delivery -->
 <contentType value="[code]"/><!-- 0..1 MIME type to send, or omit for no payload -->
 <content value="[code]"/><!-- 0..1 empty | id-only | full-resource -->
</Subscription>

JSON Template

{doco
  "resourceType" : "Subscription",
  // from Resource: id, meta, implicitRules, and language
  // from DomainResource: text, contained, extension, and modifierExtension
  "identifier" : [{ Identifier }], // Additional identifiers (business identifier)
  "name" : "<string>", // Human readable name for this subscription
  "status" : "<code>", // R!  requested | active | error | off
  "topic" : { Reference(SubscriptionTopic) }, // R!  Reference to the subscription topic being subscribed to
  "contact" : [{ ContactPoint }], // Contact details for source (e.g. troubleshooting)
  "end" : "<instant>", // When to automatically delete the subscription
  "reason" : "<string>", // Description of why this subscription was created
  "filterBy" : [{ // Criteria for narrowing the subscription topic stream
    "searchParamName" : "<string>", // R!  Filter label defined in SubscriptionTopic
    "searchModifier" : "<code>", // = | eq | ne | gt | lt | ge | le | sa | eb | ap | above | below | in | not-in | of-type
    "value" : "<string>" // R!  Literal value or resource path
  }],
  "error" : [{ CodeableConcept }], // Latest error code or note
  "channelType" : { Coding }, // R!  Channel type for notifications
  "endpoint" : "<url>", // Where the channel points to
  "header" : ["<string>"], // Usage depends on the channel type
  "heartbeatPeriod" : "<unsignedInt>", // Interval in seconds to send 'heartbeat' notification
  "timeout" : "<unsignedInt>", // Timeout in seconds to attempt notification delivery
  "contentType" : "<code>", // MIME type to send, or omit for no payload
  "content" : "<code>" // empty | id-only | full-resource
}

Turtle Template

@prefix fhir: <http://hl7.org/fhir/> .doco


[ a fhir:Subscription;
  fhir:nodeRole fhir:treeRoot; # if this is the parser root

  # from Resource: .id, .meta, .implicitRules, and .language
  # from DomainResource: .text, .contained, .extension, and .modifierExtension
  fhir:Subscription.identifier [ Identifier ], ... ; # 0..* Additional identifiers (business identifier)
  fhir:Subscription.name [ string ]; # 0..1 Human readable name for this subscription
  fhir:Subscription.status [ code ]; # 1..1 requested | active | error | off
  fhir:Subscription.topic [ Reference(SubscriptionTopic) ]; # 1..1 Reference to the subscription topic being subscribed to
  fhir:Subscription.contact [ ContactPoint ], ... ; # 0..* Contact details for source (e.g. troubleshooting)
  fhir:Subscription.end [ instant ]; # 0..1 When to automatically delete the subscription
  fhir:Subscription.reason [ string ]; # 0..1 Description of why this subscription was created
  fhir:Subscription.filterBy [ # 0..* Criteria for narrowing the subscription topic stream
    fhir:Subscription.filterBy.searchParamName [ string ]; # 1..1 Filter label defined in SubscriptionTopic
    fhir:Subscription.filterBy.searchModifier [ code ]; # 0..1 = | eq | ne | gt | lt | ge | le | sa | eb | ap | above | below | in | not-in | of-type
    fhir:Subscription.filterBy.value [ string ]; # 1..1 Literal value or resource path
  ], ...;
  fhir:Subscription.error [ CodeableConcept ], ... ; # 0..* Latest error code or note
  fhir:Subscription.channelType [ Coding ]; # 1..1 Channel type for notifications
  fhir:Subscription.endpoint [ url ]; # 0..1 Where the channel points to
  fhir:Subscription.header [ string ], ... ; # 0..* Usage depends on the channel type
  fhir:Subscription.heartbeatPeriod [ unsignedInt ]; # 0..1 Interval in seconds to send 'heartbeat' notification
  fhir:Subscription.timeout [ unsignedInt ]; # 0..1 Timeout in seconds to attempt notification delivery
  fhir:Subscription.contentType [ code ]; # 0..1 MIME type to send, or omit for no payload
  fhir:Subscription.content [ code ]; # 0..1 empty | id-only | full-resource
]

Changes since Release 3

Subscription
Subscription.identifier
  • Added Element
Subscription.name
  • Added Element
Subscription.status
  • Change value set from http://hl7.org/fhir/ValueSet/subscription-status|4.0.0 to http://hl7.org/fhir/ValueSet/subscription-state|4.4.0
Subscription.topic
  • Added Mandatory Element
Subscription.reason
  • Min Cardinality changed from 1 to 0
Subscription.filterBy
  • Added Element
Subscription.filterBy.searchParamName
  • Added Mandatory Element
Subscription.filterBy.searchModifier
  • Added Element
Subscription.filterBy.value
  • Added Mandatory Element
Subscription.error
  • Max Cardinality changed from 1 to *
  • Type changed from string to CodeableConcept
Subscription.channelType
  • Added Mandatory Element
Subscription.endpoint
  • Added Element
Subscription.header
  • Added Element
Subscription.heartbeatPeriod
  • Added Element
Subscription.timeout
  • Added Element
Subscription.contentType
  • Added Element
Subscription.content
  • Added Element
Subscription.criteria
  • deleted
Subscription.channel
  • deleted

See the Full Difference for further information

This analysis is available as XML or JSON.

See R3 <--> R4 Conversion Maps (status = 2 tests that all execute ok. 2 fail round-trip testing and all r3 resources are valid.)

 

See the Profiles & Extensions and the alternate definitions: Master Definition XML + JSON, XML Schema/Schematron + JSON Schema, ShEx (for Turtle) + see the extensions, the spreadsheet version & the dependency analysis a

PathDefinitionTypeReference
Subscription.status The status of a subscription.RequiredSubscriptionState
Subscription.filterBy.searchModifier Operator to apply to filter label.RequiredSubscriptionSearchModifier
Subscription.error Codes to represent subscription error details.ExampleSubscriptionErrorCodes
Subscription.channelType The type of method used to execute a subscription.ExtensibleSubscriptionChannelType
Subscription.contentType The mime type of an attachment. Any valid mime type is allowed.RequiredMime Types
Subscription.content Codes to represent how much resource content to send in the notification payload.RequiredSubscriptionPayloadContent

Trial-Use Note:

TODO

  1. Updates to "Managing Subscriptions and Errors"

    • Discuss error codes (Extensible Codeable Concept)
    • Define basic error codes here
    • Need to discuss eventCount and error detection (insert appropriate examples/workflows)
  2. Updates to "Tracking Subscription Notifications" SHOULD define what the AuditEvent looks like

Servers are responsible for following FHIR security guidance. Recommendations specific to subscriptions are provided below.

A subscription is a request for future event notifications. As with any client-initiated interaction, Subscriptions could request information that a client is not allowed to see, and servers SHALL enforce authorization in accordance with their policy requirements. Servers 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 at the time of each event notification.

When sending an event notification, servers 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).

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 Subscription.header to verify that a message is from the desired source).

Each channel type involves the server sending a communication that could reveal information about the client and server relationship, as well as sensitive administrative or clinical information. Servers are responsible for ensuring appropriate security is employed for each channel. The Subscription resource does not address these concerns directly; it is assumed that these are administered by other configuration processes. For instance, a server might maintain a whitelist of acceptable endpoints or trusted certificate authorities for rest-hook channels.

This specification describes three distinct outbound notification types: Event, Handshake and Heartbeat. For each, the notification body is a subscription-notification Bundle with a SubscriptionStatus resource used to convey Subscription and notification details.

The primary notification is a notification about an event.

The client expectations upon receipt of a Handshake notification are defined separately for each channel type (e.g., for the rest-hook channel type, a client endpoint responds to event notifications with standard HTTP response codes).

When a connection to an Endpoint is established, a server MAY send a Handshake notification to the endpoint. A Handshake notification is a subscription-notification Bundle sent without incrementing the subscription event count.

The client is not expected to take any special action in receipt of a Handshake notification beyond the channel-specific requirement for receiving an event notification.

Servers MAY periodically send notifications across a channel to ensure that the connection is still alive and valid (e.g., in accordance with a client's requested heartbeat interval). The Heartbeat notification is an empty subscription-notification Bundle sent without incrementing the subscription event count.

The client is not expected to take any special action in receipt of a Heartbeat notification beyond the channel-specific requirement for receiving an event notification.

  • The SubscriptionStatus.eventsSinceSubscriptionStart element indicates the number of unique events that have triggered notification attempts on this Subscription PRIOR to the current notification being sent.

    • In the case of a handshake, this count will always be zero (0).

    • In the case of a heartbeat notification, this count will be the same as the last notification and will not be incremented due to the heartbeat notification.

    • In the case of event notifications, the event count will be incremented by the number of notifications contained within this bundle (often a single notification, though servers may choose to batch notifications within a short time interval).

    • In the case of an event notification that cannot be delivered (e.g., because a client endpoint is offline), the server MAY retry delivery but does not increment the event count; the count represents unique events, not unique delivery attempts.

  • The SubscriptionStatus.eventsInNotification element represents the number of event notifications conveyed by the Bundle. This helps clients:

    • Determine if a notification requires further processing (e.g., a client might discard handshake and heartbeat notifications)

    • Determine the number of events it should expeect to find in follow-on queries when the in empty payload type is used

    • Handle batched results (e.g., a server sending at max one notification per second)

    For handshake and heartbeat notifications, eventsInNotification will be zero if present.

  • The SubscriptionStatus.status element represents the Subscription status values at the time the notification is sent. Note that the status might change between the time the notification is sent and the time it is received/processed, and therefore this status recorded in the extension is not guaranteed to represent status at the time of receipt. The field is useful as a hint to inform the client if the server has encountered errors in notifications immediately preceding this notification.

  • The SubscriptionStatus.topic element references the SubscriptionTopic resource relevant to this notification, as an absolute URL for the SubscriptionTopic resource on the server that generated the notification (NOT a reference to a canonical SubscriptionTopic URL.)

  • The SubscriptionStatus.subscription element references the Subscription resource that triggered this notification, as an absolute URL for the Subscription resource on the server that generated the notification.

There are three options available when specifying the contents of a Notification: empty, id-only, and full-resource. These options change the level of detail conveyed in the notification Bundle entries.

When deciding which payload type to request, systems SHOULD consider both ease of processing and security of PHI. To mitigate the risk of information leakage, systems SHOULD use the minimum level of detail consistent with the use case. In practice, id-only provides a good balance for many real-world scenarios.

If a server will not honor a payload type (e.g., will not send full-resource over HTTP), the server should reject the Subscription request, but may accept it and report back to the subscriber that it was modified.

An example notification with an empty payload can be found here.

With the content type of empty, the resources involved in triggering the notification are only available through the REST API, which helps consolidate authorization and authentication logic. When the subscriber receives a notification of this type, it may query the server to fetch all the relevant resources based on the SubscriptionTopic and applicable filters. The client might include a &_since= query parameter, supplying its last query timestamp to retrieve only the most recent resources. For example, if the notification is for a topic about patient admission, the subscriber might query for the most recent Encounters for a patient or group of patients.

An example notification with an id-only payload can be found here.

With the content type of id-only, the resources involved in triggering the notification are only available through the REST API, which (as in the empty payload example) helps consolidate authorization and authentication logic. When the subscriber receives a notification of this type, it may directly fetch all the relevant resources using the supplied resource ids. For example, the if the notification is for a topic about patient admission, the subscriber might fetch the Encounter(s) for a patient or group of patients.

An example notification with a full-resource payload can be found here.

With the content type of full-resource, the resources involved in triggering the notification are included in the notification bundle. When the subscriber receives a notification of this type, some resources are already present in the bundle, but it may need to fetch additional resources from the server. For example, the if the notification is for a topic about patient admission, the subscriber might fetch Observations related to the Encounters in the notification.

In subscriptions with payloads of id-only or full-resource, the notification bundle will include data in the Bundle.entry appropriate to the requested type (e.g., fullURL or resource).

TODO: Each entry must be annotated to indicate whether it was gather before or after the event which caused the notification. For example, if the triggering event is a resource deletion, the before-object would be defined while the after-object would not. Conversely, during resource creation the before-object is not defined while the after-object is. Finally, during update operations, either the before or after object may meet the criteria, and this must be conveyed to the subscriber.

TODO: Issue: how do you handle security for these - e.g., a resource moves from permissable to not-permissable? You could trigger a notification with the before-object filled and the after-object not, but that indicates to the subscriber that a change has happened.

When a Subscription is created for a REST Hook channel type, the server SHALL set initial status to requested, pending verification of the nominated endpoint URL. After a successful handshake notification has been sent and accepted, the server SHALL update the status to active. Any errors in the initial handshake SHALL result in the status being changed to error.

To receive notifications via HTTP/S POST, a client should request a subscription with the channel type (Subscription.channelType) of rest-hook (from the subscription-channel-type Code System) and set the endpoint (Subscription.endpoint) to the appropriate client URL. Note that this URL must be accessible by the hosting server.

To convey an event notification, the server POSTs a Bundle to the client's nominated endpoint URL per the format requests in the Subscription. The content-type of the POST SHALL match the contentType (channel.contentType) requested during creation of the Subscription. Each Subscription.header value SHALL be conveyed as an HTTP request header.

Note that HTTP is not a secure or encrypted channel. It is strongly recommended that implementations refuse requests to send notifications to URLs using the HTTP protocol (use HTTPS instead). Note that HTTP does not provide endpoint verification. It is strongly recommended that implementations refuse requests to send notifications to URLs using the HTTP protocol (use HTTPS instead).

While the primary interface for FHIR servers is the FHIR REST API, notifications need not occur via REST. Indeed, some subscribers may be unable to expose an outward-facing HTTP server to receive triggered notifications. For example, a pure client-side Web app or mobile app may want to subscribe to a data feed without polling using the /history operation. This can be accomplished using a websocket notification channel.

A client can declare its intention to receive notifications via Web Sockets by requesting a subscription with the channel type (Subscription.channelType) of websocket (from the subscription-channel-type Code System).

The subscriber then initiates a Web Socket connection to the server, at a URL advertised in the FHIR server's Capability statement (subscriptions/webSocketUrl (todo)). A simple protocol is used to listen for notifications:

  • Client connects a secure Web Socket to the server's webSocketUrl (see websocket extension in the server's CapabilityStatement).
  • Client authenticates to server using a server-specified Web socket protocol (e.g. OAuth bearer token presentation).
  • Client sends a bind :id message over the socket (using the logical id of the subscription). For example, the client might issue: bind 123).
  • Server responds with a "bound :id" message to acknowledge.
  • Server sends a "ping :id" message to notify the client each time a new result is available

Trial-Use Note: Warning: The WebSocket channel type is being examined to provide functional parity with other channel types. In particular, the current system fails to address authentication and a desire for multiple subscriptions to be available to a single WebSocket connection. More work is required.

WebSocket security for FHIR Subscriptions is not yet well understood. Implementers should be aware (at minimum) of the following areas:

  • Authentication of WebSockets is not generically interoperable with JWT or other 'Authentication header' protocols - WS and WSS do NOT allow for the required headers.
  • Given client limitations on concurrent WebSocket connections (commonly 6), it is recommended that a single connection be able to authenticate to multiple Subscription resources.
  • Unlike HTTP/S requests, WebSockets can be long-lived. Because of this, the case of revoking access of an active connection must be considered.

While the primary interface for FHIR servers is the FHIR REST API, notifications need not occur via REST. Indeed, some subscribers may be unable to maintain an outward-facing HTTP server to receive triggered notifications. For example, a public health organization may want to be notified of outbreaks of various illnesses. This can be accomplished using an email notification channel.

A client can declare its intention to receive notifications via Email by requesting a subscription with the channel type (Subscription.channelType) of email (from the subscription-channel-type Code System) and setting the endpoint (Subscription.endpoint) to the appropriate email URI (e.g., mailto:public_health_notifications@example.org).

The server will send a new message for each matching resource. The server will create a message based on the values present in the Subscription.contentType and Subscription.content fields. If a server cannot honor the requested combination, the server should reject the Subscription request rather than send unexpected email messages.

The email channel sets two guidelines about content:

  • Message Body content MUST be human readable
  • Message Attachments CAN be machine readable

Due to these guidelines, the Subscription.contentType refers to the content of the body of the message. Attachment type information can be appended as a MIME parameter, for example:

  • text/plain: a plain-text body with no attachment
  • text/html: an HTML body with no attachment
  • text/plain;attach=application/fhir+json: a plain-text body with a FHIR JSON bundle attached
  • text/html;attach=application/fhir+xml: an HTML body with a FHIR XML bundle attached

The Subscription.content field must be applied to any attachments, and may be applied to body contents (depending on server implementation). However, a server must not include a body which exceeds the specified content level. For example, a server may choose to always include a standard message in the body of the message containing no PHI and vary the attachment, but cannot include PHI in the body of an email when the content is set to empty.

Trial-Use Note: Warning: The Email channel type is still being actively tested and might not be consistently supported by servers. More work is required.

Email (SMTP) is not a secure channel. Implementers must ensure that any messages containing PHI have been secured according to their policy requirements (e.g., use of a system such as Direct ).

There are times when it is desireable to use Subscriptions as a communication channel between FHIR servers. This can be accomplished using the message notification channel.

To receive notifications via messaging, a client should request a subscription with the channel type (Subscription.channelType) of message (from the subscription-channel-type Code System) and set the endpoint (Subscription.endpoint) to the FHIR server base URL. Note that this URL must be accessible by the hosting server.

For each matching resource, a server will send a message to the nominated end-point. Most servers will require that the end-point is white-listed prior to allowing these kinds of subscriptions.

Trial-Use Note: Warning: The Messaging channel type is not yet defined in a highly standardized way, and might not be consistently supported by servers. More work is required.

Defining a new channel type requires clear communication to implementers of both clients and servers around requirements and expectations. Below are some areas which should be considered when creating a channel. Anyone defining a channel type is encouraged to publish their definition at registry.fhir.org .

Trial-Use Note: Warning: This section is still in early drafting.

At a minimum, the following items should be defined:

  • A generally useful name for Subscription.channelType (e.g., 'secure-mq' isntead of 'channel0012')
  • The type of data required in Subscription.endpoint (e.g., URI, etc.)
  • The meaning of the Subscription.header field values (e.g., REST-hook defines as Auth headers included in a POST)
  • Any variations on MIME types for Subscription.contentType (e.g., email defines this as the email body, with allowable attachments.)
  • Whether heartbeat notifications are used (and guidance on timings if they are)
  • Defining a channel has security implications.
  • If the channel CANNOT be secured, that should be stated with a warning not to transfer PHI.
  • If the channel is/can be scured, guidance should be given on how configurations relate to PHI safety:
    • Does the channel determine the legitimacy of both endpoints?
    • Is the channel secure for third-party monitoring?
    • ...

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 transaction, the client parses the Location header 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 process 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.

Once the server has activated the subscription, it sets the status to active (note: the server may do this as it accepts the resource if it wants).

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 stored in Subscription.error. Servers should provide a mechanism for clearing errors (e.g., when resetting a Subscription.status back to requested after an error). Since Subscription.error represents server errors, a server SHOULD NOT allow clients to add errors.

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.

Search parameters for this resource. The common parameters also apply. See Searching for more information about searching in REST, messaging, and services.

NameTypeDescriptionExpressionIn Common
contacttokenContact details for the subscriptionSubscription.contact
payloadtokenThe mime-type of the notification payload
status NtokenThe current state of the subscriptionSubscription.status
typetokenThe type of channel for the sent notifications
urluriThe uri that will receive the notifications