Open Health Hub FHIR Implementation Guide
0.1.0 - v0.1.0
Open Health Hub FHIR Implementation Guide - Local Development build (v0.1.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
| Official URL: https://api.openhealthhub.com/OpenHealthhub/fhir/4/StructureDefinition/ohh-subscription | Version: 0.1.0 | |||
| Active as of 2025-12-03 | Computable Name: OhhSubscription | |||
Subscriptions are used to trigger a webhook request when a resource that matches the criteria has been created or updated.
Subscription can be used to get notified about changes to resources. Currently only subscription on these resources can be created:
Usages:
You can also check for usages in the FHIR IG Statistics
Description of Profiles, Differentials, Snapshots and how the different presentations work.
This structure is derived from Subscription
| Name | Flags | Card. | Type | Description & Constraints Filter: ![]() ![]() |
|---|---|---|---|---|
![]() |
0..* | Subscription | Server push subscription criteria | |
![]() ![]() |
C | 1..1 | string | Rule for server push Constraints: ohh-subscription-criteria |
![]() ![]() |
||||
![]() ![]() ![]() |
1..1 | code | rest-hook | websocket | email | sms | message Fixed Value: rest-hook | |
Documentation for this format | ||||
| Id | Grade | Path(s) | Description | Expression |
| ohh-subscription-criteria | error | Subscription.criteria | Criteria can only be on QuestionnaireResponse, PlanDefinition, or CarePlan |
matches('^(QuestionnaireResponse|PlanDefinition|CarePlan).*')
|
| Name | Flags | Card. | Type | Description & Constraints Filter: ![]() ![]() |
|---|---|---|---|---|
![]() |
0..* | Subscription | Server push subscription criteria | |
![]() ![]() |
?!Σ | 0..1 | uri | A set of rules under which this content was created |
![]() ![]() |
?! | 0..* | Extension | Extensions that cannot be ignored |
![]() ![]() |
?!Σ | 1..1 | code | requested | active | error | off Binding: SubscriptionStatus (required): The status of a subscription. |
![]() ![]() |
Σ | 1..1 | string | Description of why this subscription was created |
![]() ![]() |
ΣC | 1..1 | string | Rule for server push Constraints: ohh-subscription-criteria |
![]() ![]() |
Σ | 1..1 | BackboneElement | The channel on which to report matches to the criteria |
![]() ![]() ![]() |
?!Σ | 0..* | Extension | Extensions that cannot be ignored even if unrecognized |
![]() ![]() ![]() |
Σ | 1..1 | code | rest-hook | websocket | email | sms | message Binding: SubscriptionChannelType (required): The type of method used to execute a subscription. Fixed Value: rest-hook |
Documentation for this format | ||||
| Path | Status | Usage | ValueSet | Version | Source |
| Subscription.status | Base | required | SubscriptionStatus | 📍4.0.1 | FHIR Std. |
| Subscription.channel.type | Base | required | SubscriptionChannelType | 📍4.0.1 | FHIR Std. |
| Id | Grade | Path(s) | Description | Expression |
| dom-2 | error | Subscription | If the resource is contained in another resource, it SHALL NOT contain nested Resources |
contained.contained.empty()
|
| dom-3 | error | Subscription | If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource or SHALL refer to the containing resource |
contained.where((('#'+id in (%resource.descendants().reference | %resource.descendants().as(canonical) | %resource.descendants().as(uri) | %resource.descendants().as(url))) or descendants().where(reference = '#').exists() or descendants().where(as(canonical) = '#').exists() or descendants().where(as(canonical) = '#').exists()).not()).trace('unmatched', id).empty()
|
| dom-4 | error | Subscription | If a resource is contained in another resource, it SHALL NOT have a meta.versionId or a meta.lastUpdated |
contained.meta.versionId.empty() and contained.meta.lastUpdated.empty()
|
| dom-5 | error | Subscription | If a resource is contained in another resource, it SHALL NOT have a security label |
contained.meta.security.empty()
|
| dom-6 | best practice | Subscription | A resource should have narrative for robust management |
text.`div`.exists()
|
| ele-1 | error | **ALL** elements | All FHIR elements must have a @value or children |
hasValue() or (children().count() > id.count())
|
| ext-1 | error | **ALL** extensions | Must have either extensions or value[x], not both |
extension.exists() != value.exists()
|
| ohh-subscription-criteria | error | Subscription.criteria | Criteria can only be on QuestionnaireResponse, PlanDefinition, or CarePlan |
matches('^(QuestionnaireResponse|PlanDefinition|CarePlan).*')
|
| Name | Flags | Card. | Type | Description & Constraints Filter: ![]() ![]() | ||||
|---|---|---|---|---|---|---|---|---|
![]() |
0..* | Subscription | Server push subscription criteria | |||||
![]() ![]() |
Σ | 0..1 | id | Logical id of this artifact | ||||
![]() ![]() |
Σ | 0..1 | Meta | Metadata about the resource | ||||
![]() ![]() |
?!Σ | 0..1 | uri | A set of rules under which this content was created | ||||
![]() ![]() |
0..1 | code | Language of the resource content Binding: CommonLanguages (preferred): A human language.
| |||||
![]() ![]() |
0..1 | Narrative | Text summary of the resource, for human interpretation This profile does not constrain the narrative in regard to content, language, or traceability to data elements | |||||
![]() ![]() |
0..* | Resource | Contained, inline Resources | |||||
![]() ![]() |
0..* | Extension | Additional content defined by implementations | |||||
![]() ![]() |
?! | 0..* | Extension | Extensions that cannot be ignored | ||||
![]() ![]() |
?!Σ | 1..1 | code | requested | active | error | off Binding: SubscriptionStatus (required): The status of a subscription. | ||||
![]() ![]() |
Σ | 0..* | ContactPoint | Contact details for source (e.g. troubleshooting) | ||||
![]() ![]() |
Σ | 0..1 | instant | When to automatically delete the subscription | ||||
![]() ![]() |
Σ | 1..1 | string | Description of why this subscription was created | ||||
![]() ![]() |
ΣC | 1..1 | string | Rule for server push Constraints: ohh-subscription-criteria | ||||
![]() ![]() |
Σ | 0..1 | string | Latest error note | ||||
![]() ![]() |
Σ | 1..1 | BackboneElement | The channel on which to report matches to the criteria | ||||
![]() ![]() ![]() |
0..1 | string | Unique id for inter-element referencing | |||||
![]() ![]() ![]() |
0..* | Extension | Additional content defined by implementations | |||||
![]() ![]() ![]() |
?!Σ | 0..* | Extension | Extensions that cannot be ignored even if unrecognized | ||||
![]() ![]() ![]() |
Σ | 1..1 | code | rest-hook | websocket | email | sms | message Binding: SubscriptionChannelType (required): The type of method used to execute a subscription. Fixed Value: rest-hook | ||||
![]() ![]() ![]() |
Σ | 0..1 | url | Where the channel points to | ||||
![]() ![]() ![]() |
Σ | 0..1 | code | MIME type to send, or omit for no payload Binding: Mime Types (required): The mime type of an attachment. Any valid mime type is allowed. | ||||
![]() ![]() ![]() |
Σ | 0..* | string | Usage depends on the channel type | ||||
Documentation for this format | ||||||||
| Path | Status | Usage | ValueSet | Version | Source |
| Subscription.language | Base | preferred | Common Languages | 📍4.0.1 | FHIR Std. |
| Subscription.status | Base | required | SubscriptionStatus | 📍4.0.1 | FHIR Std. |
| Subscription.channel.type | Base | required | SubscriptionChannelType | 📍4.0.1 | FHIR Std. |
| Subscription.channel.payload | Base | required | MimeType | 📍4.0.1 | FHIR Std. |
| Id | Grade | Path(s) | Description | Expression |
| dom-2 | error | Subscription | If the resource is contained in another resource, it SHALL NOT contain nested Resources |
contained.contained.empty()
|
| dom-3 | error | Subscription | If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource or SHALL refer to the containing resource |
contained.where((('#'+id in (%resource.descendants().reference | %resource.descendants().as(canonical) | %resource.descendants().as(uri) | %resource.descendants().as(url))) or descendants().where(reference = '#').exists() or descendants().where(as(canonical) = '#').exists() or descendants().where(as(canonical) = '#').exists()).not()).trace('unmatched', id).empty()
|
| dom-4 | error | Subscription | If a resource is contained in another resource, it SHALL NOT have a meta.versionId or a meta.lastUpdated |
contained.meta.versionId.empty() and contained.meta.lastUpdated.empty()
|
| dom-5 | error | Subscription | If a resource is contained in another resource, it SHALL NOT have a security label |
contained.meta.security.empty()
|
| dom-6 | best practice | Subscription | A resource should have narrative for robust management |
text.`div`.exists()
|
| ele-1 | error | **ALL** elements | All FHIR elements must have a @value or children |
hasValue() or (children().count() > id.count())
|
| ext-1 | error | **ALL** extensions | Must have either extensions or value[x], not both |
extension.exists() != value.exists()
|
| ohh-subscription-criteria | error | Subscription.criteria | Criteria can only be on QuestionnaireResponse, PlanDefinition, or CarePlan |
matches('^(QuestionnaireResponse|PlanDefinition|CarePlan).*')
|
This structure is derived from Subscription
Differential View
This structure is derived from Subscription
| Name | Flags | Card. | Type | Description & Constraints Filter: ![]() ![]() |
|---|---|---|---|---|
![]() |
0..* | Subscription | Server push subscription criteria | |
![]() ![]() |
C | 1..1 | string | Rule for server push Constraints: ohh-subscription-criteria |
![]() ![]() |
||||
![]() ![]() ![]() |
1..1 | code | rest-hook | websocket | email | sms | message Fixed Value: rest-hook | |
Documentation for this format | ||||
| Id | Grade | Path(s) | Description | Expression |
| ohh-subscription-criteria | error | Subscription.criteria | Criteria can only be on QuestionnaireResponse, PlanDefinition, or CarePlan |
matches('^(QuestionnaireResponse|PlanDefinition|CarePlan).*')
|
Key Elements View
| Name | Flags | Card. | Type | Description & Constraints Filter: ![]() ![]() |
|---|---|---|---|---|
![]() |
0..* | Subscription | Server push subscription criteria | |
![]() ![]() |
?!Σ | 0..1 | uri | A set of rules under which this content was created |
![]() ![]() |
?! | 0..* | Extension | Extensions that cannot be ignored |
![]() ![]() |
?!Σ | 1..1 | code | requested | active | error | off Binding: SubscriptionStatus (required): The status of a subscription. |
![]() ![]() |
Σ | 1..1 | string | Description of why this subscription was created |
![]() ![]() |
ΣC | 1..1 | string | Rule for server push Constraints: ohh-subscription-criteria |
![]() ![]() |
Σ | 1..1 | BackboneElement | The channel on which to report matches to the criteria |
![]() ![]() ![]() |
?!Σ | 0..* | Extension | Extensions that cannot be ignored even if unrecognized |
![]() ![]() ![]() |
Σ | 1..1 | code | rest-hook | websocket | email | sms | message Binding: SubscriptionChannelType (required): The type of method used to execute a subscription. Fixed Value: rest-hook |
Documentation for this format | ||||
| Path | Status | Usage | ValueSet | Version | Source |
| Subscription.status | Base | required | SubscriptionStatus | 📍4.0.1 | FHIR Std. |
| Subscription.channel.type | Base | required | SubscriptionChannelType | 📍4.0.1 | FHIR Std. |
| Id | Grade | Path(s) | Description | Expression |
| dom-2 | error | Subscription | If the resource is contained in another resource, it SHALL NOT contain nested Resources |
contained.contained.empty()
|
| dom-3 | error | Subscription | If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource or SHALL refer to the containing resource |
contained.where((('#'+id in (%resource.descendants().reference | %resource.descendants().as(canonical) | %resource.descendants().as(uri) | %resource.descendants().as(url))) or descendants().where(reference = '#').exists() or descendants().where(as(canonical) = '#').exists() or descendants().where(as(canonical) = '#').exists()).not()).trace('unmatched', id).empty()
|
| dom-4 | error | Subscription | If a resource is contained in another resource, it SHALL NOT have a meta.versionId or a meta.lastUpdated |
contained.meta.versionId.empty() and contained.meta.lastUpdated.empty()
|
| dom-5 | error | Subscription | If a resource is contained in another resource, it SHALL NOT have a security label |
contained.meta.security.empty()
|
| dom-6 | best practice | Subscription | A resource should have narrative for robust management |
text.`div`.exists()
|
| ele-1 | error | **ALL** elements | All FHIR elements must have a @value or children |
hasValue() or (children().count() > id.count())
|
| ext-1 | error | **ALL** extensions | Must have either extensions or value[x], not both |
extension.exists() != value.exists()
|
| ohh-subscription-criteria | error | Subscription.criteria | Criteria can only be on QuestionnaireResponse, PlanDefinition, or CarePlan |
matches('^(QuestionnaireResponse|PlanDefinition|CarePlan).*')
|
Snapshot View
| Name | Flags | Card. | Type | Description & Constraints Filter: ![]() ![]() | ||||
|---|---|---|---|---|---|---|---|---|
![]() |
0..* | Subscription | Server push subscription criteria | |||||
![]() ![]() |
Σ | 0..1 | id | Logical id of this artifact | ||||
![]() ![]() |
Σ | 0..1 | Meta | Metadata about the resource | ||||
![]() ![]() |
?!Σ | 0..1 | uri | A set of rules under which this content was created | ||||
![]() ![]() |
0..1 | code | Language of the resource content Binding: CommonLanguages (preferred): A human language.
| |||||
![]() ![]() |
0..1 | Narrative | Text summary of the resource, for human interpretation This profile does not constrain the narrative in regard to content, language, or traceability to data elements | |||||
![]() ![]() |
0..* | Resource | Contained, inline Resources | |||||
![]() ![]() |
0..* | Extension | Additional content defined by implementations | |||||
![]() ![]() |
?! | 0..* | Extension | Extensions that cannot be ignored | ||||
![]() ![]() |
?!Σ | 1..1 | code | requested | active | error | off Binding: SubscriptionStatus (required): The status of a subscription. | ||||
![]() ![]() |
Σ | 0..* | ContactPoint | Contact details for source (e.g. troubleshooting) | ||||
![]() ![]() |
Σ | 0..1 | instant | When to automatically delete the subscription | ||||
![]() ![]() |
Σ | 1..1 | string | Description of why this subscription was created | ||||
![]() ![]() |
ΣC | 1..1 | string | Rule for server push Constraints: ohh-subscription-criteria | ||||
![]() ![]() |
Σ | 0..1 | string | Latest error note | ||||
![]() ![]() |
Σ | 1..1 | BackboneElement | The channel on which to report matches to the criteria | ||||
![]() ![]() ![]() |
0..1 | string | Unique id for inter-element referencing | |||||
![]() ![]() ![]() |
0..* | Extension | Additional content defined by implementations | |||||
![]() ![]() ![]() |
?!Σ | 0..* | Extension | Extensions that cannot be ignored even if unrecognized | ||||
![]() ![]() ![]() |
Σ | 1..1 | code | rest-hook | websocket | email | sms | message Binding: SubscriptionChannelType (required): The type of method used to execute a subscription. Fixed Value: rest-hook | ||||
![]() ![]() ![]() |
Σ | 0..1 | url | Where the channel points to | ||||
![]() ![]() ![]() |
Σ | 0..1 | code | MIME type to send, or omit for no payload Binding: Mime Types (required): The mime type of an attachment. Any valid mime type is allowed. | ||||
![]() ![]() ![]() |
Σ | 0..* | string | Usage depends on the channel type | ||||
Documentation for this format | ||||||||
| Path | Status | Usage | ValueSet | Version | Source |
| Subscription.language | Base | preferred | Common Languages | 📍4.0.1 | FHIR Std. |
| Subscription.status | Base | required | SubscriptionStatus | 📍4.0.1 | FHIR Std. |
| Subscription.channel.type | Base | required | SubscriptionChannelType | 📍4.0.1 | FHIR Std. |
| Subscription.channel.payload | Base | required | MimeType | 📍4.0.1 | FHIR Std. |
| Id | Grade | Path(s) | Description | Expression |
| dom-2 | error | Subscription | If the resource is contained in another resource, it SHALL NOT contain nested Resources |
contained.contained.empty()
|
| dom-3 | error | Subscription | If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource or SHALL refer to the containing resource |
contained.where((('#'+id in (%resource.descendants().reference | %resource.descendants().as(canonical) | %resource.descendants().as(uri) | %resource.descendants().as(url))) or descendants().where(reference = '#').exists() or descendants().where(as(canonical) = '#').exists() or descendants().where(as(canonical) = '#').exists()).not()).trace('unmatched', id).empty()
|
| dom-4 | error | Subscription | If a resource is contained in another resource, it SHALL NOT have a meta.versionId or a meta.lastUpdated |
contained.meta.versionId.empty() and contained.meta.lastUpdated.empty()
|
| dom-5 | error | Subscription | If a resource is contained in another resource, it SHALL NOT have a security label |
contained.meta.security.empty()
|
| dom-6 | best practice | Subscription | A resource should have narrative for robust management |
text.`div`.exists()
|
| ele-1 | error | **ALL** elements | All FHIR elements must have a @value or children |
hasValue() or (children().count() > id.count())
|
| ext-1 | error | **ALL** extensions | Must have either extensions or value[x], not both |
extension.exists() != value.exists()
|
| ohh-subscription-criteria | error | Subscription.criteria | Criteria can only be on QuestionnaireResponse, PlanDefinition, or CarePlan |
matches('^(QuestionnaireResponse|PlanDefinition|CarePlan).*')
|
This structure is derived from Subscription
Other representations of profile: CSV, Excel, Schematron
To create a Subscription to get notified about changes you’ll need to have an endpoint/URL available that can handle the notification requests.
If you want subscriptions to only be valid until a specific time, you can specify the end value of a subscription. This can be helpful if
you specify an authorization token that has a limited lifetime in the headers. Note that you should keep track of expired subscriptions
yourself. We won’t create new subscriptions if they expire. No notifications will be sent for this subscription after the specified
timestamp. The status of the subscription will then also change to off.
When creating a Subscription, you can choose to also retrieve the content with the notification by setting the payload to one of the 2 allowed values [application/fhir+json, application/fhir+xml]. If you don’t want to receive the content, you’ll need to execute the request defined in the criteria to retrieve the items.
If you have set the payload to one of the allowed values, we’ll send the notifications with the (related) content of the subscribed resource in a Bundle of type history.
If your server endpoint needs specific headers in the HTTP Post request, you can add them in the channel.header field. This can, for
example, be used when the endpoint is secured with authentication. You can, for example, add an Authorization: Bearer <jwttoken> value to
the headers. When the notification is posted, these headers will be added to the request.
We currently support subscriptions on PlanDefinition, QuestionnaireResponse and CarePlan:
You can register a Subscription on PlanDefinitions to receive notification when new programs for your client are published or if changes occur to a specific program by adding an _id query parameter to the criteria.
When the payload property has been set, the posted Bundle will contain the PlanDefinition that was changed/created.
You can register a Subscription on QuestionnaireResponse to receive notification when new answers for a questionnaire have become available.
Currently, you can register for notifications on all responses or on responses for a specific program/PlanDefinition. To listen for
responses for a specific program, you’ll need to add the based-on.instantiates-canonical query parameter to your criteria and set the
value
to the UUID of the program you want to receive notifications for.
When the payload property has been set, the posted Bundle will contain the QuestionnaireResponse (with encrypted values) and the
Questionnaire that corresponds to this QuestionnaireResponse. If you created the Subscription via the FHIR Viewer Gateway, the gateway will
handle decryption of the QuestionnaireReponse
You can register a Subscription on CarePlan to receive notification when a CarePlan is created or updated, or when a questionnaire that is
part of the CarePlan has been filled out. Currently, you can register for notifications on all CarePlans, CarePlans for a specific
program/PlanDefinition, or for a specific CarePlan. To listen for CarePlans for a specific program, you’ll need to add the
instantiates-canonical query parameter to your criteria and set the value to the UUID of the program you want to receive notifications for.
When you want to receive notifications for a specific CarePlan, you can use the _id query parameter with the ID of the CarePlan as value.
When the payload property has been set, the posted Bundle will contain the CarePlan that was updated/created.