FHIR Release 3 (STU) Current Build
This page is part of FHIR STU 3 (v3.0.1) in it's permanent home (it will always be available at this URL). It has been superceded by R4 . For a full list of available versions, see the Directory of published versions .

2.46 Resource Subscription - Content

FHIR Infrastructure Work Group Maturity Level : 3 0   Trial Use Security Category : Business Compartments : Not linked to any defined compartments

The subscription resource is used to define a push based subscription from describes a server particular client's request to another system. Once a subscription is registered with the server, the server checks every resource that is created or updated, and if the resource matches the given criteria, it sends be notified about a message on the defined "channel" so that another system is able to take an appropriate action. Topic.

The subscription resource is used to define a push-based transaction from a server to another system. A suscriber subscribes to one or more predefined Topics which the server supports. Subscribers typically receive only a subset of the total event notifications for a given topic by filtering on the content. The filtering criteria are defined by the Topic resource. Once a subscription is created, any newly created or updated resources topics that meet the filtering criteria in the resource cause a notification to be sent using the provided channel. The criteria are Search strings that have the same interpretation as if they were appended to the base URL and submitted using the REST API. Note that the search criteria are applied to the new value of the resource. The consequence of this is that there is no notification when a resource is deleted, or when a resource is updated so that it no longer meets the criteria.

The server is able to send notifications without any information about the matching resource, or with the entire resource.

Several different types of channels are supported:

  • rest-hook : A post notification is made POSTed to the URL identified in the Subscription resource. If the subscription requests that the whole resource is included, the URL is interpreted as the service base
  • websocket : A PING message is sent to the designated URI
  • email/sms : A notification is sent to the nominated email address or SMS number
  • message : The resource is sent to the application identified in the URI as a message

See below for further discussion of the various channels. Note that sending the entire resource creates security concerns that must be managed by the server.

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.

As an alternative to subscriptions, the RESTful API describes a polling-based subscription method using bundles and the history operation . This method of polling allows for a much tighter relationship between the client and the server that doesn't involve missing updates and/or deletes.

When using the Subscription resource, the FHIR server combines the roles of publisher and information distributer. Other arrangements of the publish and subscribe pattern describe separate agents for the two roles. Implementers may implement the Subscription resource using an architecture with separate agents, or using any other pub/sub architectire (e.g. see FHIRCast , or, more generally, W3C Pub/Sub ).

No resources refer to this resource directly.

This resource does not implement any patterns.

Structure

Name Flags Card. Type Description & Constraints doco
. . Subscription Σ TU DomainResource A server push subscription criteria Notification about a Topic
Elements defined in Ancestors: id , meta , implicitRules , language , text , contained , extension , modifierExtension
. . . identifier Σ 0..* Identifier Additional identifiers (business identifier)
. . . name Σ 0..1 string Human-readable name for this subscription
... status ?! Σ 1..1 code requested | active | error | off
SubscriptionStatus ( Required )
. . . topic Σ 1..1 Reference ( Topic ) Reference to the topic being subscribed to
... contact Σ 0..* ContactPoint Contact details for source (e.g. troubleshooting)
. . . end Σ 0..1 instant When to automatically delete the subscription
. . . reason Σ 1..1 string Description of why this subscription was created
. . criteria . filterBy Σ 1..1 0..* BackboneElement Criteria for narrowing the topic stream
.... name Σ 1..1 string Filter label defined in Topic
.... matchType Rule for server push criteria Σ 0..1 code = | in | not-in | above | below
SubscriptionFilterByMatchType ( Required )
.... value Σ 1..1 string Literal value or resource path
. . . error Σ 0..1 0..* string CodeableConcept Latest error code or note
Subscription Error Codes ( Example )
. . . eventCount Σ 0..1 unsignedInt Notification event counter
.. . channel Σ 1..1 BackboneElement The channel on which to report matches to the criteria
. . . . type Σ 1..1 code CodeableConcept rest-hook | websocket | email | sms | message
SubscriptionChannelType SubscriptionChannel Type Codes ( Required Extensible )
. . . . endpoint Σ 0..1 uri url Where the channel points to
. . . . header Σ 0..* string Usage depends on the channel type
. . . . payload heartbeatPeriod Σ 0..1 string unsignedInt Mimetype Interval in seconds to send, or omit for no send 'heartbeat' notification
.... payload Σ 0..1 BackboneElement Payload definition
. . . . . header contentType Σ 0..* 0..1 string code Usage depends on the channel MIME type to send, or omit for no payload
MimeType ( Required )
. . . . tag . content Σ 0..* 0..1 Coding code A tag to add to matching resources empty | id-only | full-resource
SubscriptionTag SubscriptionPayloadContent ( Example 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 instance identifier : Identifier [0..*] A natural language name identifying the subscription name : 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) SubscriptionStatus ! » The reference to the topic to be notified about topic : Reference [1..1] « Topic » Contact details for a human to contact about the subscription. The primary use of this for system administrator troubleshooting contact : ContactPoint [0..*] The time for the server to turn the subscription off end : instant [0..1] A description of why this subscription is defined reason : string [1..1] The rules A record of the last error that occurred when the server should use to determine when to generate notifications for this subscription processed a notification criteria error : string CodeableConcept [1..1] [0..*] « Codes to represent subscription error details. (Strength=Example) SubscriptionErrorCodes ?? » A record of the last error number of events for which the server has attempted delivery on this subscription (i.e., the number of events that occurred when while the server processed subscription is in an "active" or "error" state -- not "requested" or "off"). Server Initializes to 0 for a new subscription. Repeated attempts at delivery of the *same* event notification do not increment this counter error eventCount : string unsignedInt [0..1] FilterBy A tag The filter label (=key) as defined in the `Topic.canFilterBy.name` element name : string [1..1] The operator to add apply to any resource that matches the criteria, after the subscription is processed filter value when determining matches (Search modifiers) tag matchType : Coding code [0..*] [0..1] « Tags Operator to put on a apply to filter label. (Strength=Required) SubscriptionFilterByMatchType ! » The literal value or resource after subscriptions have been sent. (Strength=Example) path as is legal in search - for example, "Patient/123" or "le1950" SubscriptionTag value ?? : string [1..1] Channel The type of channel to send notifications on type : code CodeableConcept [1..1] « The type of method used to execute a subscription. (Strength=Required) (Strength=Extensible) SubscriptionChannelType ! SubscriptionChannelTypeCodes + » The uri url that describes the actual end-point to send messages to endpoint : uri url [0..1] Additional headers / information to send as part of the notification header : 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 sent heartbeatPeriod : unsignedInt [0..1] Payload The mime type to send the payload in - either application/fhir+xml, or application/fhir+json. The mime type "text/plain" may also be used for Email and SMS subscriptions contentType : 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 content content : code [0..1] « Codes to represent how much resource content to send in the notification payload. (Strength=Required) SubscriptionPayloadContent ! » The filter properties to be applied to narrow the 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..*] The payload mimetype and content. If the payload is not present, then there is no payload in the notification, just a notification payload : string [0..1] Additional headers / information to send as part of the notification header : string [0..*] [0..1] Details where to send notifications when resources are received that meet the criteria channel [1..1]

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(Topic) Reference to the 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]"/><!-- 1..1 Description of why this subscription was created -->
 <
 <

 <filterBy>  <!-- 0..* Criteria for narrowing the topic stream -->
  <name value="[string]"/><!-- 1..1 Filter label defined in Topic -->
  <matchType value="[code]"/><!-- 0..1 = | in | not-in | above | below -->
  <value value="[string]"/><!-- 1..1 Literal value or resource path -->
 </filterBy>
 <error><!-- 0..* CodeableConcept Latest error code or note --></error>
 <eventCount value="[unsignedInt]"/><!-- 0..1 Notification event counter -->

 <channel>  <!-- 1..1 The channel on which to report matches to the criteria -->
  <
  <
  <

  <type><!-- 1..1 CodeableConcept rest-hook | websocket | email | sms | message --></type>
  <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 -->
  <payload>  <!-- 0..1 Payload definition -->
   <contentType value="[code]"/><!-- 0..1 MIME type to send, or omit for no payload -->
   <content value="[code]"/><!-- 0..1 empty | id-only | full-resource -->
  </payload>

 </channel>
 <</tag>

</Subscription>

JSON Template

{doco
  "resourceType" : "",

  "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(Topic) }, // R!  Reference to the topic being subscribed to

  "contact" : [{ ContactPoint }], // Contact details for source (e.g. troubleshooting)
  "end" : "<instant>", // When to automatically delete the subscription
  "reason" : "<string>", // R!  Description of why this subscription was created
  "
  "

  "filterBy" : [{ // Criteria for narrowing the topic stream
    "name" : "<string>", // R!  Filter label defined in Topic
    "matchType" : "<code>", // = | in | not-in | above | below
    "value" : "<string>" // R!  Literal value or resource path
  }],
  "error" : [{ CodeableConcept }], // Latest error code or note
  "eventCount" : "<unsignedInt>", // Notification event counter

  "channel" : { // R!  The channel on which to report matches to the criteria
    "
    "
    "
    "
  },
  "

    "type" : { CodeableConcept }, // R!  rest-hook | websocket | email | sms | message
    "endpoint" : "<url>", // Where the channel points to
    "header" : ["<string>"], // Usage depends on the channel type
    "heartbeatPeriod" : "<unsignedInt>", // Interval in seconds to send 'heartbeat' notification
    "payload" : { // Payload definition
      "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:;

[ 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(Topic) ]; # 1..1 Reference to the 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 ]; # 1..1 Description of why this subscription was created
  fhir:
  fhir:

  fhir:Subscription.filterBy [ # 0..* Criteria for narrowing the topic stream
    fhir:Subscription.filterBy.name [ string ]; # 1..1 Filter label defined in Topic
    fhir:Subscription.filterBy.matchType [ code ]; # 0..1 = | in | not-in | above | below
    fhir:Subscription.filterBy.value [ string ]; # 1..1 Literal value or resource path
  ], ...;
  fhir:Subscription.error [ CodeableConcept ], ... ; # 0..* Latest error code or note
  fhir:Subscription.eventCount [ unsignedInt ]; # 0..1 Notification event counter

  fhir:Subscription.channel [ # 1..1 The channel on which to report matches to the criteria
    fhir:
    fhir:
    fhir:

    fhir:Subscription.channel.type [ CodeableConcept ]; # 1..1 rest-hook | websocket | email | sms | message
    fhir:Subscription.channel.endpoint [ url ]; # 0..1 Where the channel points to

    fhir:Subscription.channel.header [ string ], ... ; # 0..* Usage depends on the channel type
    fhir:Subscription.channel.heartbeatPeriod [ unsignedInt ]; # 0..1 Interval in seconds to send 'heartbeat' notification
    fhir:Subscription.channel.payload [ # 0..1 Payload definition
      fhir:Subscription.channel.payload.contentType [ code ]; # 0..1 MIME type to send, or omit for no payload
      fhir:Subscription.channel.payload.content [ code ]; # 0..1 empty | id-only | full-resource
    ];

  ];
  fhir:

]

Changes since DSTU2 R3

Subscription
Subscription.identifier
  • Added Element
Subscription.name
  • Added Element
Subscription.channel.payload Subscription.status
  • Min Cardinality changed Change value set from 1 http://hl7.org/fhir/ValueSet/subscription-status|4.0.0 to 0 http://hl7.org/fhir/ValueSet/subscription-status|4.1.0
Subscription.topic
  • Added Mandatory Element
Subscription.filterBy
  • Added Element
Subscription.filterBy.name
  • Added Mandatory Element
Subscription.filterBy.matchType
  • Added Element
Subscription.filterBy.value
  • Added Mandatory Element
Subscription.channel.header Subscription.error
  • Max Cardinality changed from 1 to *
  • Type changed from string to CodeableConcept
Subscription.eventCount
  • Added Element
Subscription.channel.type
  • Type changed from code to CodeableConcept
  • Change binding strength from required to extensible
  • Change value set from http://hl7.org/fhir/ValueSet/subscription-channel-type|4.0.0 to http://hl7.org/fhir/ValueSet/subscription-channel-type
Subscription.channel.heartbeatPeriod
  • Added Element
Subscription.channel.payload
  • Type changed from code to BackboneElement
  • Remove Binding http://hl7.org/fhir/ValueSet/mimetypes|4.0.0 (required)
Subscription.channel.payload.contentType
  • Added Element
Subscription.channel.payload.content
  • Added Element
Subscription.criteria
  • deleted

See the Full Difference for further information

This analysis is available as XML or JSON .

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

Structure

Name Flags Card. Type Description & Constraints doco
. . Subscription Σ TU DomainResource A server push subscription criteria Notification about a Topic
Elements defined in Ancestors: id , meta , implicitRules , language , text , contained , extension , modifierExtension
. . . identifier Σ 0..* Identifier Additional identifiers (business identifier)
. . . name Σ 0..1 string Human-readable name for this subscription
... status ?! Σ 1..1 code requested | active | error | off
SubscriptionStatus ( Required )
. . . topic Σ 1..1 Reference ( Topic ) Reference to the topic being subscribed to
... contact Σ 0..* ContactPoint Contact details for source (e.g. troubleshooting)
. . . end Σ 0..1 instant When to automatically delete the subscription
. . . reason Σ 1..1 string Description of why this subscription was created
. . criteria . filterBy Σ 1..1 0..* BackboneElement Criteria for narrowing the topic stream
.... name Σ 1..1 string Filter label defined in Topic
.... matchType Rule for server push criteria Σ 0..1 code = | in | not-in | above | below
SubscriptionFilterByMatchType ( Required )
.... value Σ 1..1 string Literal value or resource path
. . . error Σ 0..1 0..* string CodeableConcept Latest error code or note
Subscription Error Codes ( Example )
. . . eventCount Σ 0..1 unsignedInt Notification event counter
.. . channel Σ 1..1 BackboneElement The channel on which to report matches to the criteria
. . . . type Σ 1..1 code CodeableConcept rest-hook | websocket | email | sms | message
SubscriptionChannelType SubscriptionChannel Type Codes ( Required Extensible )
. . . . endpoint Σ 0..1 uri url Where the channel points to
. . . . header Σ 0..* string Usage depends on the channel type
. . . . payload heartbeatPeriod Σ 0..1 string unsignedInt Mimetype Interval in seconds to send, or omit for no send 'heartbeat' notification
.... payload Σ 0..1 BackboneElement Payload definition
. . . . . header contentType Σ 0..* 0..1 string code Usage depends on the channel MIME type to send, or omit for no payload
MimeType ( Required )
. . . . tag . content Σ 0..* 0..1 Coding code A tag to add to matching resources empty | id-only | full-resource
SubscriptionTag SubscriptionPayloadContent ( Example 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 instance identifier : Identifier [0..*] A natural language name identifying the subscription name : 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) SubscriptionStatus ! » The reference to the topic to be notified about topic : Reference [1..1] « Topic » Contact details for a human to contact about the subscription. The primary use of this for system administrator troubleshooting contact : ContactPoint [0..*] The time for the server to turn the subscription off end : instant [0..1] A description of why this subscription is defined reason : string [1..1] The rules A record of the last error that occurred when the server should use to determine when to generate notifications for this subscription processed a notification criteria error : string CodeableConcept [1..1] [0..*] « Codes to represent subscription error details. (Strength=Example) SubscriptionErrorCodes ?? » A record of the last error number of events for which the server has attempted delivery on this subscription (i.e., the number of events that occurred when while the server processed subscription is in an "active" or "error" state -- not "requested" or "off"). Server Initializes to 0 for a new subscription. Repeated attempts at delivery of the *same* event notification do not increment this counter error eventCount : string unsignedInt [0..1] FilterBy A tag The filter label (=key) as defined in the `Topic.canFilterBy.name` element name : string [1..1] The operator to add apply to any resource that matches the criteria, after the subscription is processed filter value when determining matches (Search modifiers) tag matchType : Coding code [0..*] [0..1] « Tags Operator to put on a apply to filter label. (Strength=Required) SubscriptionFilterByMatchType ! » The literal value or resource after subscriptions have been sent. (Strength=Example) path as is legal in search - for example, "Patient/123" or "le1950" SubscriptionTag value ?? : string [1..1] Channel The type of channel to send notifications on type : code CodeableConcept [1..1] « The type of method used to execute a subscription. (Strength=Required) (Strength=Extensible) SubscriptionChannelType ! SubscriptionChannelTypeCodes + » The uri url that describes the actual end-point to send messages to endpoint : uri url [0..1] Additional headers / information to send as part of the notification header : 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 sent heartbeatPeriod : unsignedInt [0..1] Payload The mime type to send the payload in - either application/fhir+xml, or application/fhir+json. The mime type "text/plain" may also be used for Email and SMS subscriptions contentType : 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 content content : code [0..1] « Codes to represent how much resource content to send in the notification payload. (Strength=Required) SubscriptionPayloadContent ! » The filter properties to be applied to narrow the 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..*] The payload mimetype and content. If the payload is not present, then there is no payload in the notification, just a notification payload : string [0..1] Additional headers / information to send as part of the notification header : string [0..*] [0..1] Details where to send notifications when resources are received that meet the criteria channel [1..1]

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(Topic) Reference to the 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]"/><!-- 1..1 Description of why this subscription was created -->
 <
 <

 <filterBy>  <!-- 0..* Criteria for narrowing the topic stream -->
  <name value="[string]"/><!-- 1..1 Filter label defined in Topic -->
  <matchType value="[code]"/><!-- 0..1 = | in | not-in | above | below -->
  <value value="[string]"/><!-- 1..1 Literal value or resource path -->
 </filterBy>
 <error><!-- 0..* CodeableConcept Latest error code or note --></error>
 <eventCount value="[unsignedInt]"/><!-- 0..1 Notification event counter -->

 <channel>  <!-- 1..1 The channel on which to report matches to the criteria -->
  <
  <
  <

  <type><!-- 1..1 CodeableConcept rest-hook | websocket | email | sms | message --></type>
  <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 -->
  <payload>  <!-- 0..1 Payload definition -->
   <contentType value="[code]"/><!-- 0..1 MIME type to send, or omit for no payload -->
   <content value="[code]"/><!-- 0..1 empty | id-only | full-resource -->
  </payload>

 </channel>
 <</tag>

</Subscription>

JSON Template

{doco
  "resourceType" : "",

  "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(Topic) }, // R!  Reference to the topic being subscribed to

  "contact" : [{ ContactPoint }], // Contact details for source (e.g. troubleshooting)
  "end" : "<instant>", // When to automatically delete the subscription
  "reason" : "<string>", // R!  Description of why this subscription was created
  "
  "

  "filterBy" : [{ // Criteria for narrowing the topic stream
    "name" : "<string>", // R!  Filter label defined in Topic
    "matchType" : "<code>", // = | in | not-in | above | below
    "value" : "<string>" // R!  Literal value or resource path
  }],
  "error" : [{ CodeableConcept }], // Latest error code or note
  "eventCount" : "<unsignedInt>", // Notification event counter

  "channel" : { // R!  The channel on which to report matches to the criteria
    "
    "
    "
    "
  },
  "

    "type" : { CodeableConcept }, // R!  rest-hook | websocket | email | sms | message
    "endpoint" : "<url>", // Where the channel points to
    "header" : ["<string>"], // Usage depends on the channel type
    "heartbeatPeriod" : "<unsignedInt>", // Interval in seconds to send 'heartbeat' notification
    "payload" : { // Payload definition
      "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:;

[ 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(Topic) ]; # 1..1 Reference to the 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 ]; # 1..1 Description of why this subscription was created
  fhir:
  fhir:

  fhir:Subscription.filterBy [ # 0..* Criteria for narrowing the topic stream
    fhir:Subscription.filterBy.name [ string ]; # 1..1 Filter label defined in Topic
    fhir:Subscription.filterBy.matchType [ code ]; # 0..1 = | in | not-in | above | below
    fhir:Subscription.filterBy.value [ string ]; # 1..1 Literal value or resource path
  ], ...;
  fhir:Subscription.error [ CodeableConcept ], ... ; # 0..* Latest error code or note
  fhir:Subscription.eventCount [ unsignedInt ]; # 0..1 Notification event counter

  fhir:Subscription.channel [ # 1..1 The channel on which to report matches to the criteria
    fhir:
    fhir:
    fhir:

    fhir:Subscription.channel.type [ CodeableConcept ]; # 1..1 rest-hook | websocket | email | sms | message
    fhir:Subscription.channel.endpoint [ url ]; # 0..1 Where the channel points to

    fhir:Subscription.channel.header [ string ], ... ; # 0..* Usage depends on the channel type
    fhir:Subscription.channel.heartbeatPeriod [ unsignedInt ]; # 0..1 Interval in seconds to send 'heartbeat' notification
    fhir:Subscription.channel.payload [ # 0..1 Payload definition
      fhir:Subscription.channel.payload.contentType [ code ]; # 0..1 MIME type to send, or omit for no payload
      fhir:Subscription.channel.payload.content [ code ]; # 0..1 empty | id-only | full-resource
    ];

  ];
  fhir:

]

Changes since DSTU2 Release 3

Subscription
Subscription.identifier
  • Added Element
Subscription.name
  • Added Element
Subscription.channel.payload Subscription.status
  • Min Cardinality changed Change value set from 1 http://hl7.org/fhir/ValueSet/subscription-status|4.0.0 to 0 http://hl7.org/fhir/ValueSet/subscription-status|4.1.0
Subscription.topic
  • Added Mandatory Element
Subscription.filterBy
  • Added Element
Subscription.filterBy.name
  • Added Mandatory Element
Subscription.filterBy.matchType
  • Added Element
Subscription.filterBy.value
  • Added Mandatory Element
Subscription.channel.header Subscription.error
  • Max Cardinality changed from 1 to *
  • Type changed from string to CodeableConcept
Subscription.eventCount
  • Added Element
Subscription.channel.type
  • Type changed from code to CodeableConcept
  • Change binding strength from required to extensible
  • Change value set from http://hl7.org/fhir/ValueSet/subscription-channel-type|4.0.0 to http://hl7.org/fhir/ValueSet/subscription-channel-type
Subscription.channel.heartbeatPeriod
  • Added Element
Subscription.channel.payload
  • Type changed from code to BackboneElement
  • Remove Binding http://hl7.org/fhir/ValueSet/mimetypes|4.0.0 (required)
Subscription.channel.payload.contentType
  • Added Element
Subscription.channel.payload.content
  • Added Element
Subscription.criteria
  • deleted

See the Full Difference for further information

This analysis is available as XML or JSON .

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

 

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

Subscription.tag
Path Definition Type Reference
Subscription.status The status of a subscription. Required SubscriptionStatus
Subscription.filterBy.matchType Operator to apply to filter label. Required SubscriptionFilterByMatchType
Subscription.error Codes to represent subscription error details. Example SubscriptionErrorCodes
Subscription.channel.type The type of method used to execute a subscription. Extensible SubscriptionChannelTypeCodes
Subscription.channel.payload.contentType The mime type of an attachment. Any valid mime type is allowed. Required SubscriptionChannelType Mime Types
Subscription.channel.payload.content Tags Codes to put on a represent how much resource after subscriptions have been sent. content to send in the notification payload. Example Required SubscriptionTag SubscriptionPayloadContent

Executing each The three types of the channels documented below involves the notifications which a server sending is able to send to a communication that will reveal information about the client are the Event , Handshake and server relationship, and, if Heartbeat notification. All of the entire resource is sent, administrative or clinical information that may be quite sensitive and/or protected under law. Servers notification types are responsible for ensuring appropriate security is employed history Bundles with added extensions on the Bundle.meta element to define Subscription notification specific details.

TODO: In the following sections provide specific guidance for each channel. channel types this including for REST Hooks + Web Sockets

The subscription resource does not address these concerns directly - it primary notification is assumed that these a notification about an event.

The client expectations upon receipt of receipt of a Handshake notification are administered defined by other configuration. For instance, each implementation.

When a server might maintain connection to an Endpoint is established, the Server will send an empty History Bundle as a whitelist of acceptable servers for Handshake notification to the rest-create/rest-update methods. client.

Emails should generally be secured using some technique such as Direct The client is not expected to take any special action in receipt of a Handshake notification beyond the channel requirements.

.

Servers may periodically send notifications across a channel to ensure that the connection is still alive and valid. The Heartbeat notification is an empty History 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 requirements.

  • A subscription The subscription-event-count extension is defined by creating used to indicate the Subscription resource number of times a notification has been attempted on this Subscription PRIOR to this notification being sent.

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

    • In the subscription is created by case of a heartbeat notification, this count will be the client, it sets same as the status last notification and will not be incremented due to "requested". After POSTing the subscription, heartbeat notification.

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

  • The bundle-event-count extension represents the number of events ( event-notifications, notifications ??) within the Bundle. This is of particular interest in several ways:

    • Determining if a notification requires further processing (e.g., discarding handshake and saves heartbeat)

    • Determining the new Subscription's logical id for use number of events in subsequent operations. empty payload scenarios

    • Server batching (e.g., a server sending at max one notification per second)

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

  • The criteria are subject subscription-status extension is used to represent the same limitations as Subscription status values at the client that created it, such as access to patient compartments etc. time the notification is sent. Note that the subscription remains active after status might change between the client access tokens expire. Once time the server has activated notification is sent and the subscription, time it sets the is received/processed, and therefore this status recorded in the extension is not guaranteed to "active" (note: represent status of the server can do Subscription at any time prior-to or after this notification is sent. The field is useful primarily as it accepts a hint to inform the resource client if it wants). the server has encountered errors in notifications immediately preceding this notification.

  • An appropriately authorized client can use search and/or history operations to see what subscriptions are currently active on the server. Once The subscription-topic-url extension references the subscription Topic resource relevant to this notification. The URL is no longer desired, an absolute references to the client deletes resource on the subscription from server that generated the server. notification and NOT a reference its canonical URL.

  • The server may retry subscription-url extension references the notification a fixed number of times and/or refer errors Subscription resource which triggered this notification. The URL is an absolute references to its own alert logs. If the notification fails, resource on the server should set that generated the status to 'error', notification.

There are three options available when specifying the contents of a Notification: empty , id-only , and mark full-resource . These options change the error amount of information conveyed in the resource. If the notification succeeds, bundle itself.

When deciding which payload type to request, the server client should update the status to "active again. consider both ease in processing and security of PHI. If a subscription fails consistently a server may choose set the subscription status any untrusted hosts are included in processing notifications, it is STRONGLY recommended to off, and stop trying use an empty payload to send notifications. protect confidential health information.

If a subscription nominates a fixed end date, the server automatically deletes it at the specified time. Examples:

When a topic meets the criteria, the server `POST`s an event notification to the nominated URL as shown in the following examples. Note that the server must append the headers, if any are given, to the POST request that it makes to the client.

:

This example uses an event notification with an empty POST message payload to alert the subscriber that new results are available - available:

Request:

POST to [base]/Subscription: [base]/Subscription

Request Payload

{ "resourceType": "Subscription", "criteria": "Observation?name=http://loinc.org|1975-2&_format=json", "channel": { "type": "rest-hook", "endpoint": "https://biliwatch.com/customers/mount-auburn-miu/on-result", "header": "Authorization: Bearer secret-token-abc-123"
  {
    "resourceType": "Bundle",
    "id": "notification-empty",
    "meta": {
      "extension": [
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-event-count",
          "valueUnsignedInt": 1
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/bundle-event-count",
          "valueUnsignedInt": 1
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-status",
          "valueCode": "active"
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-topic-url",
          "valueUrl": "https://example.org/baseR4/Topic/admission"
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-url",
          "valueUrl": "https://example.org/Subscription/cb2dce51-a1f5-40b4-a98b-c934eae368e8"
        }
      ]
    },
    "type": "history",
    "timestamp": "2019-08-07T10:24:13.1882432-05:00"

  }
}

When a resource Since the content element is created or updated that meets set to empty , the criteria, data in the server sends a POST request with no body to resources is only available through the nominated URL. REST API which helps consolidate authorization and authentication logic. When the subscriber receives a POST to https://biliwatch.com/customers/mount-auburn-miu/on-result , its nominated endpoint it re-issues may queries the criteria as a query server to fetch all the server, appending relevant resources based on the Topic. The parameter &_since=:last (where :last is replaced by the time at which the client last checked). In checked) may be appended to the query fetch the most recent resources. For example, in this way it can example the topic is patient admission, and the subscriber may fetch all new relevant Observations . the most recent Encounters for a patient or group of patients.

In this example, the event notification contains the only the ids for resource. This provide the subscriber with the id for fetching the data.

Request:

POST to [base]/Subscription

Request Payload

  {
    "resourceType": "Bundle",
    "id": "notification-id-only",
    "meta": {
      "extension": [
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-event-count",
          "valueUnsignedInt": 2
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/bundle-event-count",
          "valueUnsignedInt": 1
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-status",
          "valueCode": "active"
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-topic-url",
          "valueUrl": "https://example.org/baseR4/Topic/admission"
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-url",
          "valueUrl": "https://example.org/Subscription/cb2dce51-a1f5-40b4-a98b-c934eae368e8"
        }
      ]
    },
    "type": "history",
    "timestamp": "2019-08-07T10:24:13.1882432-05:00",
    "entry": [
      {
        "fullUrl": "https://example.org/baseR4/Encounter/2",
        "request": {
          "method": "PUT",
          "url": "Encounter/2"
        },
        "response": {
          "status": "201"
        }
      }
    ]
  }

Since payload the content element is missing, set to id-only , like in the first scenario, the data in the resources is only available through the REST API, API which helps consolidate authorization and authentication logic. The server must append the headers, if any are given, to When the subscriber receives a POST request that to its nominated endpoint it makes may queries the server to fetch all the client. relevant resources using the supplied resource ids. For example, in this example the topic is patient admission, and the subscriber may fetch the Encounter(s) for a patient or group of patients.

Alternatively, In this example, the event notification contains the server can be asked to send the entire resource to a nominated FHIR end-point. resource. This is usually appropriate for defining routing rules within a managed eco-system such as a healthcare institution.

{ "channel": { "type": "rest-hook", "endpoint": "https://internal.acme.com/research/saturn", "payload": "application/fhir+json"

Request:

POST to [base]/Subscription

Request Payload

{
    "resourceType": "Bundle",
    "id": "notification-full-resource",
    "meta": {
      "extension": [
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-event-count",
          "valueUnsignedInt": 3
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/bundle-event-count",
          "valueUnsignedInt": 1
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-status",
          "valueCode": "active"
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-topic-url",
          "valueUrl": "https://example.org/baseR4/Topic/admission"
        },
        {
          "url": "http://hl7.org/fhir/StructureDefinition/subscription-url",
          "valueUrl": "https://example.org/Subscription/cb2dce51-a1f5-40b4-a98b-c934eae368e8"
        }
      ]
    },
    "type": "history",
    "timestamp": "2019-08-07T10:24:13.1882432-05:00",
    "entry": [
      {
        "fullUrl": "https://example.org/baseR4/Encounter/3",
        "resource": {
          "resourceType": "Encounter",
          "id": "3",
          "meta": {
            "versionId": "1",
            "lastUpdated": "2019-08-07T10:49:22Z"
          },
          "status": "in-progress",
          "class": {
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
            "code": "VR",
            "display": "virtual"
          },
          "subject": {
            "reference": "Patient/123"
          }
        },
        "request": {
          "method": "PUT",
          "url": "Encounter/3"
        },
        "response": {
          "status": "201"
        }
      }
    ]

  }
}

This requests that a server forward a copy of any matching resource in JSON format to the nominated server as an Update operation (i.e PUT) using the nominated URL as the service base . In order to execute this channel, the server must know how to authenticate appropriately with the destination server. This can be done by the subscription resource providing an authentication header for the server to use, or alternatively, the server may be specifically configured to be able to use the nominated server.

Subscriptions are created exclusively via the FHIR REST API. But 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 listen via Web Sockets:

{
{
  "channel": {
    "type": "websocket"

  "type": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/subscription-channel-type",
        "code": "websocket"
        }
      ]
    }

  }
}

The subscriber would then initiate 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 servers's 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

A client can register for its user to receive notifications by email:

{ "channel": { "type": "email", "endpoint": "mailto:mt-auburn-results@direct.biliwatch.com", "header": "A new bilirubin result has arrived!"
  {
     "channel":{
     "type": {
        "coding":[
           {
              "system":"http://terminology.hl7.org/CodeSystem/subscription-channel-type",
              "code":"email"
           }
        ]
     },
     "endpoint":"mailto:mt-auburn-results@direct.biliwatch.com",
     "header":"A new bilirubin result has arrived!"
  }

  }
}

The server would send a new message for each matching resource. The body of the email may be empty, or it may contain a reference to the search or the matching resource. It is at the discretion of the server as to how much information to provide. Subscription.channel.header sets the subject of the email. The email should be secured appropriately, such as using Direct, as specified by the rules of the applicable jurisdictions.

SMS works very similarly:

{ "channel": { "type": "sms", "endpoint": "tel:+1555-345-5555"
  {
     "channel":{
     "type": {
        "coding":[
           {
              "system":"http://terminology.hl7.org/CodeSystem/subscription-channel-type",
              "code":"sms"
           }
        ]
     },
     "endpoint":"tel:+1555-345-5555"
  }

  }
}

Note: SMS messages are extremely limited in size, so payload should channel.payload will usually be set omitted (signifying that no payload is to false be sent). The recipient may be human, but this is not always the case. Irrespective of size, most servers will refuse to send payloads in SMS for security reasons. reasons, and may refuse to send emails unless encrypted.

A mime/type of text/plain can be useful for email and sms along with some extension describing how to convert resources to a text representation. This specification may provide supporting infrastructure for this in the future.

STU Note: Warning: The Email/SMS channel types are not yet defined in a highly standardized way, and may not be consistently support by servers. More work is required.

A client can register for its user to receive notifications by messaging :

{ "channel": { "type": "message", "endpoint": "http://ehr.example.org/fhir/$process-message"
  {
     "channel":{
     "type": {
        "coding":[
           {
              "system":"http://terminology.hl7.org/CodeSystem/subscription-channel-type",
              "code":"sms"
           }
        ]
     },
     "endpoint":"tel:+1555-345-5555"
  }

  }
}

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.

STU Note: Warning: The details Messaging channel type is not yet defined in a highly standardized way, and may not be consistently support by servers. More work is required.

Executing each of the message - mainly channels documented below involves the event code server sending a communication that will reveal information about the client and server relationship, and, if the entire resource is sent, administrative or clinical information that may be quite sensitive and/or protected under law. 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 still to administered by other configuration processes. For instance, a server might maintain a whitelist of acceptable servers for the rest-create/rest-update methods.

Emails should generally be resolved during secured using some technique such as Direct .

The subscription resource is authored by the trial 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 period. in subsequent operations.

Feedback When the server receives a subscription, it SHOULD check that it is welcome here prepared to accept/process the subscription. If it is, it sets the subscription to active , and then 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 remains active after the client access tokens expire.

Once the server has activated the subscription, it sets the status to "active" (note: the server can 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 again. If a subscription fails consistently a server may choose set the subscription status to off and stop trying to send notifications.

If a subscription nominates a fixed end date, the server automatically deletes it at the specified time.

Applications that wish to track whether notifications have been sent for particular resources (or versions of resources) can look at the AuditEvent resources. For example:

GET [base]/AuditEvent?entity=Patient/103

This search will return all the AuditEvent resources that are about Patient 103 . At this time there is no deterministic way to tell say which of those AuditEvent resources come from the subscription sub-system that actually handles notifications. This is planned to be resolved in a future version of this specification. In the mean time, servers are encouraged to create AuditEvent records when performing notifications and document how clients can identify the relevant records when searching.

In addition, servers might also create Communication resources for some of the notifications that are sent in response to a subscription, such as when sending emails.

GET [base]/Communication?based-on=Subscription/103

This returns a list of communications sent by a subscription. TODO: search on payload....

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

Name Type Description Expression In Common
add-tag token A tag to be added to the resource matching the criteria Subscription.tag contact token Contact details for the subscription Subscription.contact
criteria string The search rules used to determine when to send a notification Subscription.criteria payload string token The mime-type of the notification payload Subscription.channel.payload Subscription.channel.payload.contentType
status token The current state of the subscription Subscription.status
type token The type of channel for the sent notifications Subscription.channel.type
url uri The uri that will receive the notifications Subscription.channel.endpoint