Personal Health Records, published by HL7 International / Patient Empowerment. This guide is not an authorized publication; it is the continuous build for version 1.0.0-ballot2 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/personal-health-record-format-ig/ and changes regularly. See the Directory of published versions
| Page standards status: Informative |
Systems MAY wish to implement standard APIs for generating a .phr or .sphr file. Standard API queries that have been used in other systems are listed below.
# export everything from a single-user system as a FHIR Bundle
GET /Bundle/$phr-export
# export everything from a single-user system as an NDJSON Bulkd Data file
GET /Bundle/$phr-export?outputFormat=ndjson
# export everything from a single-user system as a PHR file
GET /Bundle/$phr-export?outputFormat=phr
# export everything from a single-user system as a SPHR file with security
GET /Bundle/$phr-export?outputFormat=sphr
# export everything from a specific date to current from a single-user system
GET /Bundle/$phr-export?start=2010
# export everything in a specific date range from a single-user system
GET /Bundle/$phr-export?start=2010&end=2020-06
# export everything for a specific patient in a multi-user system
GET /Bundle/$phr-export?patient=Patient/12345
# post a record to another system to be imported (NDJSON format)
POST /Bundle/$import
<<<<<<< HEAD
Systems MUST post the API endpoints they use in the system's CapabilityStatement.
=======
Import Considerations:
Export operations support multiple response formats:
| Format | MIME Type | Description |
|---|---|---|
| Bundle | application/fhir+json |
Standard FHIR Bundle resource |
| NDJSON | application/x-ndjson |
Newline-delimited JSON, one resource per line |
| PHR | application/x-ndjson |
Same as NDJSON with .phr extension |
| SPHR | application/zip |
Encrypted zip containing .phr file(s) plus supporting documents |
Systems MUST advertise supported operations in their CapabilityStatement:
{
"resourceType": "CapabilityStatement",
"rest": [{
"mode": "server",
"operation": [
{
"name": "phr-export",
"definition": "http://hl7.org/fhir/uv/phr/OperationDefinition/phr-export"
},
{
"name": "import",
"definition": "http://hl7.org/fhir/uv/phr/OperationDefinition/phr-import"
}
]
}]
}
SMART Health Links (SHLinks) provide a mechanism for patients to share their health records via QR codes or short URLs. A SMART Health Link encodes an API endpoint URL along with a decryption key, enabling secure, convenient data sharing without requiring pre-established technical connectivity.
A SMART Health Link QR code encodes a URL in the format:
shlink:/eyJ1cmwiOiJodHRwczovL...
When scanned, the QR code provides access to an API endpoint that returns encrypted health data. The decryption key is embedded in the link itself.
A SMART Health Link URL payload contains:
{
"url": "https://example.org/api/shl/abc123",
"key": "rxTgYlOaKJPFtcEd0qcceN8wEU4p94SqAwIWQe6uX7Q",
"exp": 1735689600,
"flag": "LP",
"label": "Patient Health Summary"
}
| Field | Description |
|---|---|
url |
API endpoint where encrypted payload can be retrieved |
key |
Base64url-encoded decryption key (256-bit AES-GCM) |
exp |
Optional expiration time (Unix timestamp) |
flag |
L = long-term, P = passcode required, U = single use |
label |
Human-readable description |
SMART Health Links use A256GCM (AES-256 in Galois/Counter Mode). The payload retrieved from the URL is a JWE (JSON Web Encryption) that can be decrypted using the embedded key.
When sharing via SMART Health Link:
While the .phr format is primarily designed for file-based storage and exchange, systems may also transmit PHR data directly over HTTP connections using streaming techniques.
When transmitting .phr content over HTTP, use the following headers:
Content-Type: application/x-ndjson
Content-Disposition: attachment; filename="patient-record.phr"
X-PHR-Version: 1.0
For FHIR-aware systems:
Content-Type: application/fhir+ndjson
NDJSON format is well-suited for streaming because each line is a complete, parseable JSON object. Receivers can process records as they arrive without waiting for the complete transmission, enabling:
Server (streaming response):
// Node.js example
response.setHeader('Content-Type', 'application/x-ndjson');
response.setHeader('Transfer-Encoding', 'chunked');
for await (const resource of patientResources) {
response.write(JSON.stringify(resource) + '\n');
}
response.end();
Client (streaming consumption):
// Process each line as it arrives
const readline = require('readline');
const rl = readline.createInterface({ input: response });
rl.on('line', (line) => {
const resource = JSON.parse(line);
processResource(resource);
});
| Aspect | PHR Format | Bulk Data IG |
|---|---|---|
| File structure | Single heterogeneous .ndjson | Separate file per resource type |
| Typical use | Single patient export | Multi-patient population export |
| Resource ordering | Patient-centric, mixed types | Grouped by resourceType |
| Streaming | Well-suited | Designed for batch |
The PHR format uses a single file with mixed resource types for patient-centric simplicity, while Bulk Data separates by type (Observation.ndjson, Condition.ndjson, etc.) for scalability with large populations.
For streaming transfers, errors may occur mid-stream. Recommended approach:
{"resourceType":"OperationOutcome","issue":[{"severity":"error","code":"processing","diagnostics":"Error at line 847: invalid reference"}]}
Include OperationOutcome resources inline to indicate processing errors while allowing the stream to continue for partial data recovery.
<<<<<<< HEAD
<<<<<<< HEAD
8404341b (FHIR-53513: Add PHR streaming over HTTP documentation to API page)
8404341b (FHIR-53513: Add PHR streaming over HTTP documentation to API page) ======= 8404341b (FHIR-53513: Add PHR streaming over HTTP documentation to API page)