Ontario Health eForms Implementation Guide
0.1.0 - ci-build
CA-ON
Ontario Health eForms 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: http://ontario.ca/fhir/eforms/StructureDefinition/EFormSubscription | Version: 0.1.0 | |||
Active as of 2025-07-16 | Computable Name: EFormsSubscription |
Subscription Profile for OH eForms, based on the R4 version.
A Subscription is a publish-subscribe (pub/sub) mechanism built into the FHIR specification. Subscriptions are defined using the Subscription resource, which specifies what type of data is being subscribed to and how the recipient should be notified.
status
- When a Subscription is created by a client, it should have a status of requested. Smile CDR will process this Subscription, and if it is valid, the status will automatically be changed to active, meaning that the Subscription is now being processed.
criteria
- This is a FHIR search query URL that will be used to determine which resources apply to the Subscription. These resources will trigger a notification when they change. See Criteria below for more information.
channel.type - This is the mechanism for delivery, such as rest-hook, websocket, email, sms, or message. See Channel Types for more information.
channel.endpoint - For channel types that require the server to initiate a connection to the client, this is the URL of the endpoint to which the server should connect.
channel.payload - This is the MIME type encoding to use (e.g. application/fhir+json for JSON data).
channel.extension` - Providing an extension allows finer control of subscription handling. Some extensions are channel specific, while others are used to define retry handling.
With Subscriptions enabled, Smile creates a Matching Queue and sends all created/updated QuestionnaireResponse or Communication resources to that queue. This queue is drained by a Subscription Matching module. The Subscription Matcher module uses its FHIR Storage module to retrieve two resource types required for subscription matching: Subscription and SearchParameter. The Subscription Matcher module maintains in-memory caches of both of these resources that it updates from its FHIR Storage module every 60 seconds.
In the requirements, eForms is required to send email notifications whenever a QuestionnaireResponse or Communication Resource is submitted by the form filler to the FHIR Repository. While Smile does offer the ability to trigger email notifications via smtp, OH has a requirement that their AWS Simple Email Service (SES) must be used in order to send notifications. In addition to notifications, Subscriptions will also be utilized to trigger the integration with the OH ObjectStore
AWS SES Delivery - When an QuestionnaireResponse or Communication resource is submitted and the subscription is triggered in the FHIR Server, Smile will trigger a RESTful API call to the AWS SES API.
Object Store Delivery - This Subscription class will automatically invoke an SDC extraction by invoking the QuestionnaireResponse/$extraction operation which will convert the matched QuestionnaireResponse resource into a MessageBundle as defined by the ObjectStore Implementation Guide (IG).
A custom Subscription Delivery class is invoked whenever the matching criteria defined in the Subscription Resource for Object Store integration.
This profile supports all standard Subscription search parameters:
Name | Type | Description |
---|---|---|
contact |
token | Contact details for the subscription |
criteria |
string | The search rules used to determine when to send a notification |
payload |
token | The mime-type of the notification payload |
status |
token | The current state of the subscription |
type |
token | The type of channel for the sent notifications |
url |
uri | The uri that will receive the notifications |
GET [base]/Subscription?status=active
GET [base]/Subscription?type=rest-hook
GET [base]/Subscription?criteria=Task?status=completed
GET [base]/Subscription?contact=System/notification-service
Usages:
Description of Profiles, Differentials, Snapshots and how the different presentations work.
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 |
![]() ![]() ![]() |
Σ | 1..1 | string | Rule for server push |
![]() ![]() ![]() |
Σ | 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. |
![]() |
Path | Conformance | ValueSet | URI |
Subscription.status | required | SubscriptionStatushttp://hl7.org/fhir/ValueSet/subscription-status|4.0.1 From the FHIR Standard | |
Subscription.channel.type | required | SubscriptionChannelTypehttp://hl7.org/fhir/ValueSet/subscription-channel-type|4.0.1 From the FHIR Standard |
Id | Grade | Path(s) | Details | Requirements |
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() |
This structure is derived from Subscription
Name | Flags | Card. | Type | Description & Constraints Filter: ![]() ![]() |
---|---|---|---|---|
![]() ![]() |
0..* | Subscription | Server push subscription criteria | |
![]() |
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 | ||||
![]() ![]() ![]() |
Σ | 1..1 | string | Rule for server push | ||||
![]() ![]() ![]() |
Σ | 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. | ||||
![]() ![]() ![]() ![]() |
Σ | 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 | ||||
![]() |
Path | Conformance | ValueSet | URI | |||
Subscription.language | preferred | CommonLanguageshttp://hl7.org/fhir/ValueSet/languages From the FHIR Standard
| ||||
Subscription.status | required | SubscriptionStatushttp://hl7.org/fhir/ValueSet/subscription-status|4.0.1 From the FHIR Standard | ||||
Subscription.channel.type | required | SubscriptionChannelTypehttp://hl7.org/fhir/ValueSet/subscription-channel-type|4.0.1 From the FHIR Standard | ||||
Subscription.channel.payload | required | Mime Types(a valid code from urn:ietf:bcp:13 )http://hl7.org/fhir/ValueSet/mimetypes|4.0.1 From the FHIR Standard |
Id | Grade | Path(s) | Details | Requirements |
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() |
This structure is derived from Subscription
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 |
![]() ![]() ![]() |
Σ | 1..1 | string | Rule for server push |
![]() ![]() ![]() |
Σ | 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. |
![]() |
Path | Conformance | ValueSet | URI |
Subscription.status | required | SubscriptionStatushttp://hl7.org/fhir/ValueSet/subscription-status|4.0.1 From the FHIR Standard | |
Subscription.channel.type | required | SubscriptionChannelTypehttp://hl7.org/fhir/ValueSet/subscription-channel-type|4.0.1 From the FHIR Standard |
Id | Grade | Path(s) | Details | Requirements |
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() |
Differential View
This structure is derived from Subscription
Name | Flags | Card. | Type | Description & Constraints Filter: ![]() ![]() |
---|---|---|---|---|
![]() ![]() |
0..* | Subscription | Server push subscription criteria | |
![]() |
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 | ||||
![]() ![]() ![]() |
Σ | 1..1 | string | Rule for server push | ||||
![]() ![]() ![]() |
Σ | 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. | ||||
![]() ![]() ![]() ![]() |
Σ | 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 | ||||
![]() |
Path | Conformance | ValueSet | URI | |||
Subscription.language | preferred | CommonLanguageshttp://hl7.org/fhir/ValueSet/languages From the FHIR Standard
| ||||
Subscription.status | required | SubscriptionStatushttp://hl7.org/fhir/ValueSet/subscription-status|4.0.1 From the FHIR Standard | ||||
Subscription.channel.type | required | SubscriptionChannelTypehttp://hl7.org/fhir/ValueSet/subscription-channel-type|4.0.1 From the FHIR Standard | ||||
Subscription.channel.payload | required | Mime Types(a valid code from urn:ietf:bcp:13 )http://hl7.org/fhir/ValueSet/mimetypes|4.0.1 From the FHIR Standard |
Id | Grade | Path(s) | Details | Requirements |
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() |
This structure is derived from Subscription
Other representations of profile: CSV, Excel, Schematron