FHIR Bulk Data Export
Oystehr FHIR API implements Group-level data export described in Bulk Data Access IG 2.0.0 (opens in a new tab). An export request triggered on a Group resource will result in exporting all members of the Group as well as all resources which belong to a compartment of any Patient which is a member of a Group. Single patient export can be performed with an export of a Group which contains only the desired patient. Exported data will be available in NDJSON (opens in a new tab) format.
Typical export workflow
- Get an access token to be able to call Oystehr's FHIR API.
- Make a request to
/Group/[id]/$export. - The response will contain
Content-Locationheader with an URL for getting status of the export request. - Periodically make a request to the "export status" URL to check if the export is still in-progress or finished.
Start export
Request
curl --location 'https://fhir-api.zapehr.com/r4/Group/[id]/$export' \
--header 'Authorization: Bearer <your_access_token>' \
--header 'x-oystehr-project-id: <your_project_id>'There is an optional _since parameter which forces to export resources updated after a certain point in time only.
Response
- HTTP Status Code of
202 Accepted Content-Locationheader with the absolute URL of an endpoint for subsequent status requests (polling location)- Optionally, a FHIR
OperationOutcomeresource in the body in JSON format
Export status
Request
curl --location 'https://fhir-api.zapehr.com/r4/export/job/[id]' \
--header 'Authorization: Bearer <your_access_token>' \
--header 'x-oystehr-project-id: <your_project_id>'Response
- In-Progress
Status: 202 AcceptedX-Progress and Retry-After are not guaranteed for export jobs.
- Error
Status: 404 Not Found (job deleted or does not exist)
Status: 410 Gone (job result expired)
Content-Type: application/fhir+json
{
"resourceType": "OperationOutcome",
"id": "not-found",
"issue": [
{
"severity": "error",
"code": "not-found",
"details": {
"text": "Not found"
}
}
]
}- Complete
Status: 200 OK
Expires: Mon, 22 Jul 2019 23:59:59 GMT
Content-Type: application/json
{
"transactionTime": "2021-01-01T00:00:00Z",
"expiresAt": "2021-01-01T01:00:00.000Z",
"request" : "https://example.com/fhir/Patient/$export?_type=Patient,Observation",
"requiresAccessToken" : true,
"output" : [{
"type" : "Patient",
"url" : "https://example.com/output/patient_file_1.ndjson"
},{
"type" : "Patient",
"url" : "https://example.com/output/patient_file_2.ndjson"
},{
"type" : "Observation",
"url" : "https://example.com/output/observation_file_1.ndjson"
}],
"deleted" : [{
"type" : "Bundle",
"url" : "https://example.com/output/del_file_1.ndjson"
}],
"error" : [{
"type" : "OperationOutcome",
"url" : "https://example.com/output/err_file_1.ndjson"
}],
"extension":{"https://example.com/extra-property": true}
}deleted and extension are optional and preserved for backward compatibility with older bulk export clients.
SDK helpers
The SDK includes helper methods for export job polling and output retrieval:
startGroupExport(groupId, options?)getExportJob(jobId)waitForExportJob(jobId, options?)cancelExportJob(jobId)waitForExportBulkOutput(jobId, options?)waitForExportBulkBundle(jobId, options?)
SDK example
import Oystehr, { FhirResource } from '@oystehr/sdk';
const oystehr = new Oystehr({
accessToken: '<your_access_token>',
projectId: '<your_project_id>',
});
const handle = await oystehr.fhir.startGroupExport('<group_id>');
// Recommended for larger exports
const bulkOutput = await oystehr.fhir.waitForExportBulkOutput<FhirResource>(handle.jobId, {
pollIntervalMs: 1000,
timeoutMs: 600000,
});
for (const file of bulkOutput.output) {
console.log(file.type, file.resources.length);
}
// Convenience helper for smaller exports
const bundle = await oystehr.fhir.waitForExportBulkBundle<FhirResource>(handle.jobId, {
pollIntervalMs: 1000,
timeoutMs: 600000,
});
console.log(bundle.type); // "collection"
console.log(bundle.unbundle().length);waitForExportBulkOutput is preferred for large datasets because it preserves file boundaries and avoids building one large in-memory bundle. waitForExportBulkBundle is a convenience helper for small-to-medium datasets.
Cancel/Delete an export
Request
curl --location 'https://fhir-api.zapehr.com/r4/export/job/[id]' \
--request DELETE
--header 'Authorization: Bearer <your_access_token>' \
--header 'x-oystehr-project-id: <your_project_id>'Response
- HTTP Status Code of
202 Accepted - Optionally a FHIR
OperationOutcomeresource in the body in JSON format