Da Vinci Health Record Exchange (HRex)
0.2.0 - STU R1 - 2nd ballot

This page is part of the Da Vinci Health Record Exchange (v0.2.0: STU1 Ballot 1) based on FHIR R4. The current version which supercedes this version is 1.0.0. For a full list of available versions, see the Directory of published versions

Exchanging with human intervention

This page covers the mechanisms for requesting data when there is a potential for humans to be involved in the process of finding, organizing, filtering, and/or reviewing the data shared prior to exchange. Guidance on whether these 'request' mechanisms are appropriate is found here and guidance for choosing between the CommunicationRequest and Task approaches can be found here.

Note: This page focuses on the use of standard RESTful mechanisms to drive fulfillment of a CommunicationRequest or Task. It is also possible to use asynchronous custom operations or asynchronous messaging. Either of these mechanisms would need to be invoked in asynchronous mode. Both approaches require more negotiation/custom development than a pure REST solution, though they may align better with traditional application architectures and in some environments may be simpler overall. Guidance on choosing between messaging and operations can be found here.

Requesting exchange using CommunicationRequest

The basics of this mechanism are that a formal CommunicationRequest - generally with a focus of 'order' - is created that defines the data to be shared and who it is to be shared with. For the purposes of this documentation, the focus is on the system requesting the data and receiving the data being the same (the data consumer), however it is possible - and in fact common - for this mechanism to be used when the data is to flow to a different party. I.e. party A (the requester) authorizes the data source to transmit a specified set of data to a third-party data consumer.

In FHIR, a request resources represent plans, proposals or orders (authorizations) for actions to occur. However, they do not, by themselves, directly solicit action. Some sort of process must occur that triggers a solicitation for the 'request' to be fulfilled. There are numerous mechanisms in FHIR for seeking such fulfillment - all described in the FHIR core specification section on workflow communication patterns. The following diagrams and descriptions summarize the key steps in each flow and some of the considerations associated with each of the options.

Direct POST, both ways

In this approach, the CommunicationRequest soliciting data is posted directly to the data source's system and the resulting data is POSTed directly back to the data consumer's system. While lighter-weight than some of the alternatives below, it requires that records be created on the RESTful endpoints of both data source and data consumer that might not actually be desired and does not give the data consumer much choice as to what happens to the data when received - it must either be stored as a record on the respective endpoint or it must be thrown away. (This also means that the data consumer must have an endpoint for the desired data to be stored on.) This mechanism provides no mechanism to track status of work in progress. A refusal is represented by a Communication instance indicating that no Communication happened.

Balloter feedback requested: Given the downsides associated with this approach to exchange, should it be listed as one of the options in this document?

This approach corresponds to Option A in the FHIR core workflow communication patterns.

Data ConsumerData Sourceopt1.POST 'placer order'CommunicationRequest [cr1]2.POST 'filler order'CommunicationRequest3.POST [requested data]opt4.POST Communication (referencing [cr1] and [requested data])

Step 1: When creating an order, the authoritative copy of it *should* be kept on the system responsible for creating it, as that is the system that has authority to make decisions about status changes, etc. The CommunicationRequest sent to the data source should be a copy with intent of 'filler-order' that references the original data consumer-maintained original 'placer-order'.

Step 2: A copy of the CommunicationRequest (or possibly the only electronic record of the order) is created on the data source's system with a 'tag' indicating that the recipient is being asked to fulfill the order. This tag is essential to differentiate a CommunicationRequest to be acted upon from one provided as a 'for your information'.

Step 3: In this option, the data is POSTed directly back to the data consumer. This may not be appropriate in all cases as it may not make sense for the data consumer to expose a RESTful endpoint and it may not want to persist the full set of data sent.

Step 4: While the data has been delivered, nothing indicates to data consumer that the request is complete. As well, it is possible there is no data available or that the request has been refused. Posting the Communication resource allows closing this loop. However, closing the loop by formally creating a Communication instance as part of the patient record necessarily always appropriate. (Such resources will rarely be created for data shared by the data consumer directly querying the data source's system.

Direct POST with Communication

In this approach the CommunicationRequest soliciting data is posted directly to the data source's system, however the data is stored on the data source's system rather than being directly POSTed back to the data consumer. The data consumer is triggered to query the relevant data via a POST of a Communication instance that references the relevant data.

The benefit of this approach is that there is no formal 'create' of the data on the data consumer's system. The data consumer does not need to expose endpoints for each type of record it might receive and there is no expectation that the whole resources be stored. When the data consumer queries the data, it is free to do with it as it wishes. However, the price of this approach is the additional complexity of the POSTing of the Communication being mandatory and needing to query for referenced the data once the Communication is received.

Balloter feedback requested: Given the downsides associated with this approach to exchange, should it be listed as one of the options in this document?

As with CommunicationRequest POST both-ways approach, the data consumer is left with a Communication instance and the data source is left with a CommunicationRequest resource - neither of which are likely of interest as part of the patient record once the transaction is complete. As well, there is still no support for tracking status information between the initiation of the request and completion.

This approach is a variant on Option A in the FHIR core workflow communication patterns.

Data ConsumerData Sourceopt1.POST 'placer order'CommunicationRequest [cr1]2.POST 'filler order'CommunicationRequest [cr2] (based on [cr1])opt3.POST [requested data]4.POST Communication [c1] (based on [cr2] and [requested data])5a.Query to retrieve [requested data] based on reference from [c1]5b.Query response containing [requested data]

Step 1, 2: Steps 1 and 2 are the same as for step 1 and step 2 above. The CommunicationRequest is created and communicated from data consumer to data source

Step 3: In this option, instead of being directly POSTed directly back to the data consumer, the requested data record(s) are instead stored on the data source's system. This step is marked as 'optional' because in some cases the requested data might already exist on the source system and there will be no need to create it. As for step 3 above, multiple resource instances may need to exist to satisfy the communication request. It is possible that some may need to be created, while others may be pre-existing. In principle, any resources created due to the CommunicationRequest could potentially be available for subsequent query by other systems. Also, it is also possible that the created records might exist on a system other than the data source.

Step 4: In this approach, the creation of the Communication resource is mandatory rather than optional. Merely having the relevant records existing on the data source system sufficient to satisfy the original CommunicationRequest because the data consumer would have no way of knowing which records are pertinent to their request. Posting the Communication resource allows closing this loop. However, closing the loop by formally creating a Communication instance as part of the patient record necessarily always appropriate. (Such resources will rarely be created for data shared by the data consumer directly querying the data source's system.

In this step, a Communication is created on the data consumer system pointing back to the data present on the data source, allowing that data to be subsequently queried.

Step 5: Once the data source has the Communication and knows what data is deemed to satisfy the request, it can then directly query that information - either as individual reads, as a query by resource id(s) or by a batch of queries or reads.

Direct POST with polling

This is the same as the preceding approach, except that rather than the Communication being posted to the data consumer, the Communication is stored on the data source and it is retrieved by the data consumer using polling or subscription. The benefit of this change is that the data consumer does not need to expose any RESTful endpoints at all (though it means that the data source needs to expose one more). The cost of this is the introduction of polling or subscription.

Other pros and cons are the same as above. Similarly, this approach is also a variant on Option A in the FHIR core workflow communication patterns.

Balloter feedback requested: Given the downsides associated with this approach to exchange, should it be listed as one of the options in this document?

Data ConsumerData Sourceopt1.POST 'placer order'CommunicationRequest [cr1]2.POST 'filler order'CommunicationRequest [cr2] (based-on [cr1])opt3.POST [requested data]4.POST Communication [c1] (referencing [cr2] and [requested data])5.Poll/Subscribe to see [c1]opt6a.Query to retrieve [requested data] based on reference from [c1]6b.Query response containing [requested data]

Step 1, 2: Steps 1 and 2 are the same as for step 1 and step 2 for the previous two approaches. The CommunicationRequest is created and communicated from data consumer to data source

Step 3: This is the same as step 3 of the previous approach. The necessary records are either created or identified on the data source.

Step 4: Unlike of what's done in the previous approach, the Communication is created on the data source rather than the data consumer.

Step 5: Because of the change to step 4, the data consumer must either poll or subscribe in order to learn about the creation of the Communication resource. This step could also return the data referenced by the Communication if the polling is done using a query with _include on the Communication.payload.contentReference or the Subscription process is set up to provide that information. (Note that there is currently no standard search parameter to support such an _include.)

Step 6: Step 6 is the same as step 5 from the preceding approach where the records referenced by the Communication are retrieved by the data consumer from the data source. However, in this approach the step optional because the referenced resources could potentially be returned in Step 5 using _includes.

CommunicationRequest plus Task

This approach uses Task to seek fulfillment of the CommunicationRequest. It eliminates the need for Communication to link together the data returned. It also allows explicit monitoring of the state (e.g. acceptance/refusal, progress) prior to completion. Note that this flow is similar to the Task-only flow described below, with the primary difference being that it uses a formal CommunicationRequest 'order' to define the data requested rather than just using the Task itself.

This approach aligns with Option G in the FHIR core workflow communication patterns, where the Task is posted directly to the filler's system (data source). Alternate workflows using Task where the Task lives on the placer's system (data consumer) - Option F or on an intermediary system Option H, however those require either polling or subscription by the data source. In general these alternatives would only make sense if the request for information wasn't directed to a specific data source (which would be unusual) or if the data consumer did not have authority to post a Task directly to the data source's system.

Data ConsumerData Source1.POST 'placer order' CommunicationRequest [cr1]2.POST Task [t1] with focus [cr1]3a.GET (read) [cr1] based on reference from Task [t1]3b.Return [cr1] (instructing on what data to retrieve)opt4.PUT Task [t1]update status5.Poll/Subscribe to see [t1] status6.POST [requested data]7.PUT Task [t1]link to [requested data]8.Poll/Subscribe to see [t1] statusopt9a.Query to retrieve [requested data] based on reference from [t1]9b.Query response containing [requested data]

Step 1: The authoritative CommunicationRequest is created on the data consumer's system. (It is possible later, after receiving the Task, that the data source might create a 'filler' CommunicationRequest, but there would be no need to exchange it and it would have no impact on the workflow.)

Step 2: The Task is posted directly to the data source by the data consumer, initiating fulfillment of the CommunicationRequest. The CommunicationRequest is the 'focus' of the Task.

Step 3: The data source reads the CommunicationRequest (that was referenced by the Task) from the data consumer to determine what data is needed.

Step 4: The data source may optionally update the Task to change the status (e.g. from requested to accepted or refused and eventually to in-progress or on-hold. The data source might also update the Task.businessStatus element to convey additional information around progress, such as reasons for delay or expected timeframe for delivery.

Step 5: In order for the data consumer to receive information about changes to the Task status, it would either need to poll the Task by periodically performing a read on the Task instance or create a Subscription on the data source so that it is notified when the Task is updated. (Note that it will have to use one of these approaches even if not interested in status changes as polling must be used in Step 7 to see that the Task is complete.

Step 6: As with the Communication-based delivery approach, the data source creates and/or locates the desired records on its system.

Step 7: The data source updates the Task to reference the resources created and/or identified in step 5 as Task.output values and sets the Task status to completed. (It is possible that outputs may be added over time through multiple updates before the Task is marked as complete. If this happens, it is up to the data consumer whether to retrieve outputs as they are added or to wait until the Task is complete.)

Step 8: The data consumer retrieves the completed Task from the data source using either polling or a previously created Subscription. Note that this can be combined with Step 9 below if the polling or subscription mechanism makes use of _include to retrieve the Task.output references at the same time as the Task is returned. (Note that there is currently no standard search parameter to support such an _include.)

Steps 9: These work the same as Step 5 and 6 of the Communication-based exchange, except that instead of retrieving resources referenced by a Communication instance, the instances retrieved are pointed to by Task.output. This step can be omitted if the outputs are retrieved as part of the polling/subscription in Step 8.

Requesting exchange using Task

In this approach, no CommunicationRequest is used at all - as there is no need for a formal order. Instead, the Task itself describes the data to be retrieved. The workflow is identical to that used in CommunicationRequest plus Task, except that the first step (the creation of the CommunicationRequest) and the third step (read of the CommunicationRequest) are skipped and the Task transmitted in the initial step does not specify a Task.focus.

Data ConsumerData Source1.POST Task [t1] (self-describing desired data)opt2.PUT Task [t1]update status3.Poll/Subscribe to see [t1] status4.POST [requested data]5.PUT Task [t1]link to [requested data]6.Poll/Subscribe to see [t1] statusopt7a.Query to retrieve [requested data] based on reference from [t1]7b.Query response containing [requested data]

Step 1: The Task is posted directly to the data source by the data consumer. The Task describes the data to be provided directly.

Step 2: The data source may optionally update the Task to change the status (e.g. from requested to accepted or refused and eventually to in-progress or on-hold. The data source might also update the Task.businessStatus element to convey additional information around progress, such as reasons for delay or expected timeframe for delivery.

Step 3: In order for the data consumer to receive information about changes to the Task status, it would either need to poll the Task by periodically performing a read on the Task instance or create a Subscription on the data source so that it is notified when the Task is updated. (Note that it will have to use one of these approaches even if not interested in status changes as polling must be used in Step 7 to see that the Task is complete.

Step 4: The data source creates and/or locates the desired records on its system.

Step 5: The data source updates the Task to reference the resources created and/or identified in step 5 as Task.output values and sets the Task status to completed. (It is possible that outputs may be added over time through multiple updates before the Task is marked as complete. If this happens, it is up to the data consumer whether to retrieve outputs as they are added or to wait until the Task is complete.)

Step 6: The data consumer retrieves the completed Task from the data source using either polling or a previously created Subscription. Note that this can be combined with Step 7 below if the polling or subscription mechanism makes use of _include to retrieve the Task.output references at the same time as the Task is returned. (Note that there is currently no standard search parameter to support such an _include.)

Steps 7: The data consumer then retrieves the resources referenced by Task.output. This step can be omitted if the outputs are retrieved as part of the polling/subscription in Step 6.


This IG defines a specific profile for use in HRex using this mode of human-mediated information request. It also includes a number of examples, showing different phases of the workflow for a Task soliciting execution of a specific query:

There's also an an example showing a completed Task that was soliciting documents of a particular type here.