— May 18, 2026 · 8 min read
FHIR Bulk Data Export: pattern and tooling
FHIR R4 (October 2019) published the Bulk Data Access Implementation Guide to address a need RESTful FHIR APIs alone did not cover: exporting large volumes of patient or population data asynchronously and efficiently.
The mass export problem in FHIR
The classic FHIR REST API answers very well to "give me patient 12345 and their 500 linked clinical resources". It is poorly sized for "give me all patients seen in 2025 by my 800-physician network, roughly 4 million Bundles". FHIR pagination (Bundle entry next) works, but in practice the client must issue thousands of synchronous requests — network cost, cumulative latency, server load, partial failures hard to recover from.
Bulk Data Export solves this with a classic two-step asynchronous pattern: kickoff (the client requests the export, the server responds 202 Accepted with a Content-Location to track status), polling + download (the client polls that URL until ready, then retrieves N pre-generated NDJSON files, one per ResourceType).
Phase 1: kickoff
Three standard endpoints: POST [base]/$export (system-level export,
all content), POST [base]/Patient/$export (export of all accessible
patients), POST [base]/Group/[id]/$export (export of a predefined
patient group). Mandatory headers: Accept: application/fhir+json and
Prefer: respond-async.
Common parameters: _type (filter by ResourceType, e.g.
Patient,Encounter,Observation), _since (incremental sync from a
date), _typeFilter (advanced FHIR Search filters, optional support).
Typical response: 202 Accepted with Content-Location
pointing to the job polling URL.
Phase 2: polling and download
The client polls the URL with GET at reasonable intervals (the
server may return Retry-After as a header to suggest cadence).
During export, response is 202 Accepted with X-Progress
giving human-readable progress.
When the export is ready, response is 200 OK with a JSON manifest
containing transactionTime, request (the kickoff URL),
requiresAccessToken (true/false), and an output array
listing files: each entry has type (ResourceType) and
url (signed URL to download). Files are in NDJSON
(Newline-Delimited JSON) — one FHIR resource per line, easy to stream.
Authorisation: SMART Backend Services
The Bulk Data IG specifies the use of SMART Backend Services
Authorization (a subset of SMART on FHIR for machine-to-machine contexts
without a user). The client authenticates via JWT signed with its private key,
the server verifies via the registered public key (JWKS endpoint). Used scopes:
system/Patient.read, system/*.read, etc. No end user,
no individual consent — the context is an exchange between established systems.
Why NDJSON and not a giant Bundle
The choice of NDJSON format (each line is an autonomous FHIR JSON) instead of a giant FHIR Bundle is deliberate. NDJSON streams line by line without loading the file in memory — essential for multi-GB exports. It is trivial to split, to resume after failure (line offset), to parse in parallel with independent workers. A single FHIR Bundle would force parsing the whole document before the first treatment.
The cost: NDJSON is not a "normative" FHIR format before export, which sometimes causes confusion. Good implementations verify each line is a valid FHIR resource before using it.
IPS (International Patient Summary) in bulk
The International Patient Summary IG (HL7 normative since 2024, published in
cooperation with ISO 27269:2021) defines a structured subset of the patient
record — allergies, medications, active problems, recent lab results — for
cross-border exchange. Bulk export of IPS for a network: combine
$export?_type=Bundle&_typeFilter=Bundle?type=document, IPS-
profiled Composition resource. Typical use case: feed a European Patient Summary
Service (cross-border eHealth via eHDSI) from a member state.
Reference tools in 2026
- Reference Implementation Bulk Data Server (smarthealthit.org) — SMART team reference, ideal for interoperability testing.
- HAPI FHIR JPA Server — native bulk export since HAPI 6.x, supports system, patient, group exports with SMART Backend Services.
- Smile CDR — commercial distribution of HAPI, scales bulk export on cluster.
- IBM Linux for Health FHIR Server — supports bulk export since 2020, enterprise target.
- Firely Server — .NET implementation supporting bulk export.
- bulk-data-client (SMART sandbox) — reference CLI client to test a server, download in parallel, handle resume.
Conclusion: one pattern, lots of tooling
FHIR Bulk Data Access is neither revolutionary nor complex: it is a classic asynchronous pattern, well specified, well tooled. It solves the precise need "extract a large volume of patient data" without reinventing FHIR. As health data is massively exploited for research, clinical AI and regulatory reporting, it has become a baseline skill for any FHIR team. For broader context, see our FHIR introduction.