R4 Ballot #1 (Mixed Normative/Trial use)

This page is part of the FHIR Specification (v3.3.0: R4 Ballot 2). The current version which supercedes this version is 5.0.0. For a full list of available versions, see the Directory of published versions . Page versions: R5 R4B R4

FHIR Infrastructure Work GroupMaturity Level: 2Ballot Status: Trial Use

The FHIR Asynchronous API and the $export Operation are under active development.

All of the interactions defined in the RESTful API are described as synchronous operations - that is, the client makes a query, and waits for the server to respond with the outcome in the HTTP response. This pattern is not suitable once significant server side processing becomes necessary, or when substantial amounts of data must be returned. A good example of this is the $everything operation, though simple searches may result in large amounts of data. In order to cater for this use case, an asynchronous request pattern is defined.

This pattern is applicable for all the defined interactions, and for Operations, though for many of these interactions it brings no benefit. Servers may choose which interactions the pattern should be supported on (if at all), and servers may choose to only support some of the operations using the asynchronous pattern.

The asynchronous use pattern follows the pattern defined in rfc 7240 .

The client initiates the pattern using the Prefer header:

GET [base]/[request]?_outputFormat=[media-type]
Accept: application/fhir+json
Prefer: respond-async

The _outputFormat format specifies the format in which the final return is requested. This may be any of defined Serialization formats, including the bulk data formats. The accept header describes the format in which OperationOutcomes are returned if the request fails.

The request will have whatever URL and other parameters would normally apply. Typical requests that are made using the asynchronous pattern are for all data on many patients:

All Patients
GET [fhir base]/Patient/$export
Group of Patients
GET [fhir base]/Group/[id]/$export
  • HTTP Status Code of 202 Accepted
  • Content-Location header with a url for subsequent status requests
  • Optionally an OperationOutcome in the body

After a bulk data request has been kicked-off, clients can poll the url provided in the Content-Location header to obtain the status of the request.

Note: Clients SHOULD follow an exponential backoff approach when polling for status. Servers may supply a Retry-After header with a http date or a delay time in seconds. When provided, clients should use this information to inform the timing of future polling requests.

GET [content-location]
Accept: application/json
  • HTTP Status Code of 202 Accepted
  • Optionally an X-Progress header with a text description of the status of the request that's less than 100 characters. The format of this description is at the server's discretion and may be a percentage complete value or a more general status such as "in progress". Clients can try to parse this value, display it to the user, or log it.
  • Optionally an OperationOutcome in the body
  • HTTP status of 200 OK
  • Content-Type header of application/json
  • Optionally an Expires header indicating when the files listed will no longer be available
  • A body containing a json object providing metadata and links to the generated bulk data files

Required Fields:

  • transactionTime - an instant type that indicates the server's time when the query is run. No resources that have a modified data after this instant should be in the response.
  • request - the full url of the original bulk data kick-off request
  • secure - boolean value indicating whether downloading the generated files will require an authentication token. Note: This may be false in the case of signed S3 urls or an internal file server within an organization's firewall.
  • output - array of bulk data file items with one entry for each generated file. Note: If no data is returned from the kick-off request, the server should return an empty array.

Each file item should contain the following fields:

  • type - the FHIR resource type that is contained in the file. Note: Each file may only contain resources of one type, but a server may create more than one file for each resource type returned. The number of resources contained in a file is may vary between servers. If no data is found for a resource, the server should not return an output item for it in the response.
  • url - the path to the file. The format of the file should reflect that of the _outputFormat parameter of the initial kick-off request.

Note: no extensions in this json object.

Example response body:

 {
   "transactionTime": "[instant]",
   "request" : "[base]/Patient/$everything?_type=Patient,Observation", 
   "secure" : true,
   "output" : [{
     "type" : "Patient",
     "url" : "http://serverpath2/patient_file_1.ndjson"
   },{
     "type" : "Patient",
     "url" : "http://serverpath2/patient_file_2.ndjson"
   },{
     "type" : "Observation",
     "url" : "http://serverpath2/observation_file_1.ndjson"
   }]
 }

Once the client receives this response, it can retrieve the individual files listed in the response.


Using the urls supplied in the completed status request body, clients can download the generated files (one or more per resource type). Note: These files may be served by a file server rather than a FHIR specific server. Also, if the secure field in the status body is set to true the request must include a valid access token in the Authorization header in these requests.

GET [url from status request output field]

  • Accept (optional, but must match the original _outputFormat to application/fhir+ndjson): Specifies the format of the file being returned
  • HTTP status of 200 OK
  • Content-Type header of application/fhir+ndjson
  • Body - the requested content
  • HTTP Status Code of 4XX or 5XX

After a bulk data request has been kicked-off, clients can send a delete request to the url provided in the Content-Location header to cancel the request.

DELETE [polling content location]