Bulk Data Access API
The Bulk Data Application Programming Interface (API) in Health Level Seven® (HL7®) Fast Healthcare Interoperability Resources® (FHIR®) provides a compatible FHIR® system application access to potentially large volumes of information on a group of patients. Examples of where this is useful include research, quality measure calculations, and population health applications.
The traditional, interactive FHIR® API is excellent for retrieving small amounts of data in near real time. The use cases mentioned above may require many thousands of such queries to be satisfied, which is not practical. The FHIR® Bulk Data Access API was designed to address these scenarios.
Summary
Client applications that interact with the Soarian Clinicals® Bulk Data API operate under the system persona, implying that no human is assumed to be directly interacting with it. The API secures the client application using Transport Layer Security (TLS) 1.2 and OAuth 2.
The client application must be registered with Cerner and enabled for the healthcare organization, as well as capable of maintaining a client secret to ensure its authenticity. See Authorization for more information.
The client application requests bulk data from Soarian Clinicals® by issuing an HTTP GET request, specifying the $export operation, to one of two endpoints:
- GET [fhir base]/Patient/$export: Retrieve bulk data for all patients in the system.
- GET [fhir base]/Group/[id]/$export: Retrieve bulk data for a predefined group of patients.
In response, Soarian Clinicals® acknowledges the request in near real time. The acknowledgment of a successful request includes a Content-Location header that contains the absolute URL of an endpoint for status requests.
After the export request has been accepted, Soarian Clinicals® begins to generate one or more files in NDJSON format that contain the bulk data matching the request. The time that this process takes ranges from very short to very long, depending upon the amount of data that qualifies for inclusion based on the request.
Once it has received the initial acknowledgement, the client application may poll Soarian Clinicals® for the status of the file build using the polling location URL provided in the Content-Location header:
- GET [polling content location] to retrieve the status of the bulk data request
Soarian Clinicals® then returns one of the following responses:
- 202 Accepted: The export operation is in progress.
- 200 OK: The export operation is complete.
The body of the 200 OK status response contains links to the NDJSON formatted files that contain the requested bulk data. The client application can download these files.
At any time after the initial bulk data request has been acknowledged, the client application can request that it be deleted:
- DELETE [polling content location]: Delete content generated by the request.
If the above DELETE request is sent before the bulk request has completed, the in-flight request is canceled, and any associated content is marked for deletion from the server.
Cerner recommends that client applications always explicitly delete requests after they have finished downloading bulk data. Healthcare organizations have the option of configuring their systems to reject what seem to be duplicate requests. Deleting a request ensures that a subsequent request with the same parameters is not rejected as a duplicate.
Registering Client Applications
Before a client application can interact with the Soarian Clinicals® Bulk API, it must obtain an asymmetric key pair and register its public key set with Cerner. Once a client application is registered, the Soarian Clinicals® Bulk API treats it as preauthorized. This enables the client application to obtain access tokens at runtime after authenticating itself. See Authorization for details on registering client applications and obtaining access tokens.
Population Data—Kickoff Request
Soarian Clinicals® supports two endpoints for bulk data requests: one for All Patients, and another for a specific Group of Patients.
To retrieve information related to all patients in the Electronic Health Record (EHR), access the following endpoint:
GET [fhir base]/Patient/$export?:parameters
To retrieve information related to a specific group of patients in the EHR, access the following endpoint:
GET [fhir base]/Group/[id]/$export?:parameters
Implementation Notes
Be aware that a request for all patients’ data has the potential to consume a significant amount of system resources for a long time. Cerner strongly recommends that implementers retrieve information for specific groups of patients, rather than all patients. If you access the All Patients endpoint, consider using parameters to limit the amount of data returned.
Depending upon the hospital’s policies and configuration, the ability to return data on all patients may be limited or disallowed. The availability of system resources (for example, file space) may also limit responses to requests for all patients (or any query that is too broad).
Authorization Types
Parameters
Name | Required? | Type | Description |
---|---|---|---|
_outputFormat |
No | string |
The format for the requested bulk data files to be generated as per FHIR Asynchronous Request Pattern. Defaults to application/fhir+ndjson. Soarian Clinicals® accepts application/fhir+ndjson as well as the abbreviated representations application/ndjson and ndjson. |
_since |
No | FHIR® instant | The response includes resources if their state changed after the supplied time (for example, if Resource.meta.lastUpdated is later than the supplied_since time). |
_type |
No | String of comma-delimited FHIR® resource types | Only resources of the specified resource types are included in the response. If this parameter is omitted, Soarian Clinicals® returns all supported resources in the scope of the client application authorization. |
Notes
-
_type
valid parameters areAllergyIntolerance
,CarePlan
,CareTeam
,Condition
,Device
,DiagnosticReport
,DocumentReference
,Encounter
,Goal
,Immunization
,Location
,MedicationRequest
,Patient
,Procedure
,Observation
,Organization
,Practitioner
,Provenance
- When the
_type
parameter contains a reference resource (Location
,Organization
,Practitioner
,Provenance
), at least one of the following clinical resources must also be provided:AllergyIntolerance
,CarePlan
,CareTeam
,Condition
,Device
,DiagnosticReport
,DocumentReference
,Encounter
,Goal
,Immunization
,MedicationRequest
,Observation
,Patient
,Procedure
-
_type
parameter defaults to the scopes provided in the provided authorization token when not provided -
_outputFormat
valid parameters areapplication/fhir+ndjson
,application/ndjson
,ndjson
-
_outputFormat
defaults toapplication/fhir+ndjson
Headers
Accept: application/fhir+json
Prefer: respond-async
Authorization: <OAuth2 Bearer Token>
Example
Request
GET https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/Group/All_Patients/$export?_outputFormat=ndjson&_since=2020-05-10T07:12:33.058Z&_type=Patient
Response A successful response includes:
- HTTP Status Code 202 Accepted
- Content-Location header with the absolute URL of an endpoint for subsequent status requests (polling location)
- FHIR® OperationOutcome resource in the body
Status: 202 Accepted
{
"resourceType": "OperationOutcome",
"id": "3f6bd10f-8fa4-4606-aa4e-a408844fa965",
"issue": [
{
"severity": "information",
"code": "STRUCTURE",
"details": {
"text": "Request accepted, but resource(s) {Binary} in _type parameter is\n\t\t\t\t\tsupported as contained and will not generate resource specific output file(s)"
}
}
]
}
Note: The examples provided here are non-normative and replaying them in the public sandbox is not guaranteed to yield the results shown on the site.
Errors
The following common errors and OperationOutcomes may be returned in response to the export request:
HTTP Status | Cause | Severity | Code |
---|---|---|---|
400 | Badly formed URL | error | structure |
400 | The _outputFormat parameter or _since parameter contains an Invalid or unsupported value. | error | invalid |
400 | The resources in _type parameter are not supported standalone. | error | not-supported |
403 | The expected scope does not match the URL. | error | Security |
404 | The Population Application or Population Group is not defined or not active. | error | not-found |
404 | The Population Group is not assigned to a Population Application. | error | not-found |
404 | The Stored Procedure assigned to the Population Group with group ID was not found. | error | not-found |
404 | The resources in the _type parameter are not supported. | error | not-supported |
404 | The Population Application is not configured to use the Bulk Data Patient Export. | error | not-found |
406 | The Bulk Data Server rejected an export operation with an invalid Accept or Prefer header. | error | Structure |
409 | The Population Application sent a duplicate request that uses the same values in the _since and in _type parameters. | error | duplicate |
501 | The FHIR® operation for Patient Export is not currently enabled in this server environment due to volume and traffic considerations. Contact the institution with inquiries or modify your request to perform a Group Export. | error | not-found |
Population Data—Delete Request
Soarian Clinicals® supports bulk data delete requests initiated by client applications.
If the delete request specifies a bulk data export request that is in progress, the export request is canceled, and any files associated with the export request are marked for deletion.
If the bulk data export request completed previously, any files associated with the export request are deleted.
Headers
Accept: application/fhir+json
Prefer: respond-async
Authorization: <OAuth2 Bearer Token>
Example
Request
GET https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/request/6d7210a3-9c6d-4b4a-ad15-013515b524ba
In this scenario, the polling content location matches the value returned in the response to the initial bulk data request.
Response A successful response includes:
- HTTP Status Code 202 Accepted
- FHIR OperationOutcome resource in the body
Status: 202 Accepted
{
"resourceType": "OperationOutcome",
"id": "3f6bd10f-8fa4-4606-aa4e-a408844fa965",
"issue": [
{
"severity": "information",
"code": "processing",
"details": {
"text": "Cancellation of Bulkdata request <6d7210a3-9c6d-4b4a-ad15-013515b524ba> has been accepted.\n\t\t\t\t\tCancellation requested at : 2022-05-10T03:14:12Z"
}
}
]
}
Note: The examples provided here are non-normative and replaying them in the public sandbox is not guaranteed to yield the results shown on the site.
Errors
The following common errors and OperationOutcomes may be returned from the delete request:
HTTP Status | Cause | Severity | Code |
---|---|---|---|
404 | The Population Application is not defined or not active. | error | not-found |
404 | The Request ID was not found. | error | not-found |
404 | This request was previously canceled or has expired. | error | deleted |
406 | The Bulk Data Server rejected this Status Request operation due to an invalid Accept header. | error | structure |
500 | An internal error occurred. | fatal | exception |
Population Data—Status Request
Once a bulk data request has started, bulk client applications can query its status by issuing an HTTP GET to the polling content location associated with the bulk data request.
Headers
Accept: application/fhir+json
Prefer: respond-async
Authorization: <OAuth2 Bearer Token>
Example
Request
GET https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/Group/All_Patients/$export?_outputFormat=ndjson&_since=2021-05-10T07:02:39.784Z&_type=Patient
Scenarios where polling content location matches the value returned in the response to the initial bulk data request.
Responses
A status request has the following possible responses:
- In Progress: Soarian Clinicals® is building the bulk data response but has not yet finished it.
- Error: Soarian Clinicals® encountered an error while building the bulk data response.
- Complete: Soarian Clinicals® finished building the bulk data response and it is ready for download.
Note: The examples provided here are non-normative and replaying them in the public sandbox is not guaranteed to yield the results shown on the site.
Example – In Progress
A successful response includes the following messages:
- HTTP Status Code: 202 Accepted
- X-Progress: A string estimating how much of the bulk data response has been built
Status: 202 Accepted
- x-progress : 23.0% complete
Example – Error
An error response includes the following information:
- HTTP Status Code: 4XX or 5XX.
- FHIR OperationOutcome: This information is included in the body of the error response.
{
"resourceType": "OperationOutcome",
"id": "af736a47-a308-49df-ba17-0eb3e0bb4830",
"issue": [
{
"severity": "error",
"code": "not-found",
"details": {
"text": "Population Group with group id <All_Patients> not assigned in FHIR Population\n\t\t\t\t\tApplication Configuration tool for Population Application <SoFIE - BulkApi App>.\n\t\t\t\t\tReference id for support: [af736a47-a308-49df-ba17-0eb3e0bb4830]."
}
}
]
}
This error response indicates that the operation has completely failed, that is, no NDJSON files containing bulk data have been created. In the case where the operation has partially succeeded (some— but not all— NDJSON files containing bulk data were created), the response indicates a Complete status.
Example – Complete
A 100% successful response includes:
- HTTP Status Code: 200 OK
The body of the response includes a list of output file URLs in the output array element.
Status: 200 OK
{
"transactionTime": "2022-05-10T03:03:04Z",
"request": "https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/request/Group/All_Patients/$export?_type=Patient",
"requiresAccessToken": "true",
"output": [
{
"type": "Patient",
"url": "https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/download/677d425a-ba0e-499f-98eb-8de26dbd4bb1/6C68089A-25BA-49CC-AC48-9C1E56D0C593_Patient.ndjson"
}
],
"error": [
]
}
A partially successful response also includes a list of output file URLs in the output array element, pointing to data files that were successfully created. The response body also contains an error array element, which contains a list of URLs that point to NDJSON OperationOutcome resources that detail the errors encountered.
Status: 200 OK
{
"transactionTime": "2022-05-10T03:17:51Z",
"request": "https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/request/Group/All_Patients/$export?_type=Goal,Patient,Procedure",
"requiresAccessToken": "true",
"output": [
{
"type": "Patient",
"url": "https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/download/173a39fc-a2c3-4df2-ae41-5445240f3612/2A168AB6-7F5E-4BDC-BD53-F5911FF82D68_Patient.ndjson"
},
{
"type": "Goal",
"url": "https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/download/173a39fc-a2c3-4df2-ae41-5445240f3612/FCCC3692-4A03-4DA1-8BB3-8BD62E20C75C_Goal.ndjson"
}
],
"error": [
]
}
Errors
The following common errors and OperationOutcomes may be returned from the status request:
HTTP Status | Cause | Severity | Code |
---|---|---|---|
404 | The Population Application is not defined or not active. | error | not-found |
404 | The Request ID was not found. | error | not-found |
404 | This request was previously canceled or has expired. | error | deleted |
406 | The Bulk Data Server rejected this Status Request operation due to an invalid Accept header. | error | structure |
500 | An internal error occurred. | fatal | exception |
Population Data – File Request
As mentioned in previous sections, the status response for a completed request includes a list of output file URLs and if applicable, a list of OperationOutcome URLs. The client application may now download these files using these URLs.
Headers
Authorization: <OAuth2 Bearer Token>
Example
Request
GET https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/request/173a39fc-a2c3-4df2-ae41-5445240f3612
Where the URLs point to the download location.
Note that a valid access token must be supplied with the download request. The most recently obtained access token can be used if it is unexpired. Otherwise, a new access token must be obtained using the refresh token. See Authorization for details.
Response
{
"transactionTime": "2022-05-10T03:17:51Z",
"request": "https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/request/Group/All_Patients/$export?_type=Goal,Patient,Procedure",
"requiresAccessToken": "true",
"output": [
{
"type": "Patient",
"url": "https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/download/173a39fc-a2c3-4df2-ae41-5445240f3612/2A168AB6-7F5E-4BDC-BD53-F5911FF82D68_Patient.ndjson"
},
{
"type": "Goal",
"url": "https://fhir-ehr-sc.cerner.com/r4/2f8f5ec1-b7b8-4be5-ae27-e308284dd9c1/bulk-api/download/173a39fc-a2c3-4df2-ae41-5445240f3612/FCCC3692-4A03-4DA1-8BB3-8BD62E20C75C_Goal.ndjson"
}
],
"error": [
]
}
Note: The examples provided here are non-normative and replaying them in the public sandbox is not guaranteed to yield the results shown on the site.
Errors
The following common errors and OperationOutcomes may be returned from the file request:
HTTP Status | Cause | Severity | Code |
---|---|---|---|
403 | The expected scope does not match the URL. | error | Security |
404 | The Population Application is not defined or not active. | error | not-found |
404 | The Request ID was not found. | error | not-found |
404 | This request was previously canceled or has expired. | error | deleted |
404 | The file was not found. | error | not-found |
406 | The Bulk Data Server rejected this Status Request operation due to an invalid Accept header. | error | structure |