What is FHIR
What is FHIR
FHIR (Fast Healthcare Interoperability Resources) is HL7’s API-first standard for healthcare data exchange. Unlike its predecessors — HL7 v2’s flat pipe-delimited messages and HL7 v3’s XML schemas — FHIR models healthcare concepts as discrete JSON resources accessible via standard RESTful HTTP. For a developer who has worked with any REST API: if you can GET /Patient/123, you can work with FHIR.
This page covers the FHIR model and its building blocks. For the broader interoperability landscape — how FHIR fits alongside v2, CDA, X12, and DICOM — see Healthcare Interoperability: Landscape and Approach. For a concise term definition, see the FHIR glossary entry.
The problem FHIR solves
HL7 v2 is fast and widely deployed, but each interface requires a custom parser — every vendor interprets the spec differently, and the format is positional and version-fragile. HL7 v3 introduced formal XML schemas and a Reference Information Model that proved too complex for most teams to implement correctly. FHIR’s design response was deliberate: smaller modular objects instead of monolithic messages; standard HTTP verbs instead of bespoke wire protocols; JSON-first serialization; and a URL convention any developer can recognize. The result is a standard that a developer unfamiliar with healthcare can engage with in hours, not weeks.
For a detailed comparison of each standard, see Healthcare Standards Primer.
The FHIR model
Resources
FHIR organizes healthcare data into modular units called resources. Each resource represents a single healthcare concept and has a defined structure, a unique server-assigned ID, and standard RESTful operations.
Common resource types:
- Patient — demographics and patient identification
- Observation — clinical measurements and lab results
- Condition — diagnoses and health problems
- MedicationRequest — prescriptions and medication orders
- Encounter — patient visits and episodes of care
- Practitioner — healthcare provider information
- DiagnosticReport — panel and study results
- Bundle — container for multiple resources (transactions, search results, messages)
FHIR R4 defines approximately 160 resource types. In practice, most integrations involve a small subset — a lab results pipeline uses Observation, DiagnosticReport, Patient, and Practitioner; a medication management workflow adds MedicationRequest and MedicationDispense.
Data formats
Resources can be serialized as:
- JSON — the default for modern implementations and all new integrations
- XML — supported for legacy system compatibility
- RDF/Turtle — for semantic web applications
All examples in this section use JSON.
RESTful operations
FHIR maps CRUD onto standard HTTP verbs:
GET /[type]/[id]— read a resourceGET /[type]?[params]— search for resources (returns a Bundle)POST /[type]— create (server assigns the ID)PUT /[type]/[id]— full update (client specifies the ID)DELETE /[type]/[id]— logical delete
GET /Patient/123
GET /Observation?patient=123&category=laboratory
POST /MedicationRequest
PUT /Patient/123
The base URL pattern is [server-base]/[ResourceType]/[id]. Operations that act on multiple resources or don’t fit CRUD use named operations prefixed with $ (e.g., $validate, $expand, $everything).
References
Resources link to each other via the Reference type. An Observation references the Patient it belongs to; a MedicationRequest references the prescribing Practitioner. References can be relative (Patient/123), absolute (https://server.example.org/Patient/123), or logical (identifier-based when the resource isn’t directly accessible).
For reference mechanics, contained resources, referential integrity, and identifier strategy, see FHIR References.
Profiles and Implementation Guides
Base FHIR is intentionally permissive — most elements are optional, value set bindings are loose, and the spec accommodates the widest possible range of implementations. A profile tightens this for a specific context: it makes certain elements required, restricts code choices to particular value sets, and declares which extensions are part of the contract.
A CapabilityStatement tells you which resource types and operations a server supports, and which profiles it expects. When you claim conformance to a profile via meta.profile, you’re asserting that the resource meets those constraints — validators verify the claim.
Real-world FHIR means implementing profiles from an Implementation Guide (IG), not base FHIR. In the US that means US Core; other jurisdictions have their own national IGs. “FHIR-compliant” without a named profile is almost meaningless for interoperability.
For profile mechanics (cardinality, Must Support, slicing, terminology bindings) and IG tooling, see FHIR Profiling.
Extensions
Base resource definitions are a common denominator — they can’t cover every jurisdiction’s reporting requirements or every specialty’s clinical needs. Extensions let you add data elements not in the base spec while remaining valid FHIR. A receiver that doesn’t recognize a non-modifier extension must ignore it and still process the resource.
{
"resourceType": "Patient",
"id": "example",
"extension": [
{
"url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race",
"extension": [
{ "url": "ombCategory", "valueCoding": { "system": "urn:oid:2.16.840.1.113883.6.238", "code": "2106-3", "display": "White" } },
{ "url": "text", "valueString": "White" }
]
}
],
"name": [{ "family": "Doe", "given": ["Jane"] }]
}
For extension structure, governance, modifier extensions, and common mistakes, see FHIR Extensions.
Search
FHIR’s search mechanism uses URL query parameters against a resource type endpoint. Results return as a searchset Bundle. Search supports standard parameters (_id, _lastUpdated, _profile), resource-specific parameters (e.g., Patient?name=Smith&birthdate=1980-01-15), modifiers (:exact, :contains, :missing), includes (_include, _revinclude), and pagination.
For search parameter types, modifiers, pagination strategy, and performance patterns, see FHIR Search.
FHIR versions
R4 — the production standard
FHIR R4 (released 2019) is the current dominant version in production. It achieved normative status for core resources including Patient, Observation, and the RESTful framework. All current US regulatory programs — US Core, ONC certification, CMS interoperability rules — are based on R4. Most FHIR servers, client libraries, IGs, and tooling target R4.
R4B — the bridge release
R4B (2022) is a targeted correction that introduced breaking changes for a small number of resources used in clinical research and evidence-based medicine (Evidence, EvidenceReport, Citation, and a few others). If your work doesn’t involve those specific resources, R4B offers no material benefit over R4.
R5 — the current specification
FHIR R5 (released 2023) brings improvements across the spec: more precise slicing discriminator types, better subscription mechanisms (SubscriptionTopic replacing the R4 channel model), improved FHIRPath capabilities, and refined resource structures. Tooling and IG support are growing but not yet at R4 parity. Few production IGs have published R5 versions.
Which version to use
Start with R4. It is the safe default: normative, broadly supported, and the basis for all current regulatory programs. Target R5 only if you are building a greenfield system and your ecosystem partners have committed to R5. When in doubt, ask which FHIR version the IG you’re implementing targets — that answer determines your version choice.
FHIR implementation
Servers
A FHIR server stores resources and exposes RESTful FHIR APIs. Servers handle persistence, search, validation, and versioning. Advertising capabilities via CapabilityStatement (at GET /metadata) is expected for any conformant server.
Widely used server implementations:
- HAPI FHIR (Java) — open source, widely deployed reference implementation
- Microsoft FHIR Server for Azure (.NET) — cloud-native, managed option
- Google Cloud Healthcare API — cloud-native, supports FHIR R4 and STU3
- IBM FHIR Server — Java-based, open source
Clients
A FHIR client consumes FHIR APIs to retrieve or submit data. Client libraries exist for most languages (Java, C#/.NET, JavaScript/TypeScript, Python, Go). For .NET, see Understanding Firely SDK Modeling Patterns and Attributes.
Validation
FHIR validation ensures resources conform to the specification and to any profiles they claim. Validation layers in order of increasing strictness:
- Structural — JSON is well-formed and matches the FHIR resource schema
- Cardinality — required fields are present; counts satisfy
min/max - Data type — values match expected types (
string,integer,dateTime, etc.) - Terminology — codes are valid against their declared code systems and value sets
- Profile — all profile-specific constraints, slices, and invariants are satisfied
Validation tools:
- HL7 FHIR Validator (
validator_cli.jar) — official Java CLI; authoritative for conformance testing - HAPI FHIR Validator — embedded validator in the HAPI library
- Firely .NET SDK — .NET-based validation, used in the Firely ecosystem
- Inferno — ONC’s testing platform for US Core and SMART on FHIR
Validation errors are returned as OperationOutcome resources:
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "required",
"diagnostics": "Patient.name: minimum required = 1, but only found 0",
"location": ["Patient.name"]
}
]
}
For profile validation mechanics, see FHIR Profiling.
HTTP operations in practice
Creating a resource
Server assigns the ID on POST. The response Location header returns the new resource URL:
POST https://fhir.example.org/Patient
Content-Type: application/fhir+json
{
"resourceType": "Patient",
"name": [{ "family": "Doe", "given": ["Jane"] }],
"gender": "female",
"birthDate": "1985-07-15"
}
# Response: 201 Created
# Location: https://fhir.example.org/Patient/new-id-456
Updating a resource
PUT is a full replacement — the server replaces the entire stored resource:
PUT https://fhir.example.org/Patient/456
Content-Type: application/fhir+json
{
"resourceType": "Patient",
"id": "456",
"name": [{ "family": "Doe", "given": ["Jane", "Marie"] }],
"gender": "female",
"birthDate": "1985-07-15"
}
Conditional operations
Create-if-not-exists and conditional update avoid duplicates during incremental loads:
# Create only if no match exists
POST https://fhir.example.org/Patient
If-None-Exist: identifier=http://hospital.org/mrn|12345
# Update by identifier instead of by ID
PUT https://fhir.example.org/Patient?identifier=http://hospital.org/mrn|12345
Transaction bundles
A transaction Bundle submits multiple operations atomically — all succeed or all fail. References within the bundle use temporary UUIDs resolved server-side:
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"request": { "method": "POST", "url": "Patient" },
"resource": {
"resourceType": "Patient",
"name": [{ "family": "Smith", "given": ["John"] }]
}
},
{
"request": { "method": "POST", "url": "Observation" },
"resource": {
"resourceType": "Observation",
"status": "final",
"subject": { "reference": "urn:uuid:patient-temp-id" }
}
}
]
}
Debugging and troubleshooting
Common issues:
- Invalid references — the referenced resource doesn’t exist at the URL provided; use conditional references or logical references when the resource may not yet be present
- Missing required fields — base FHIR requires very little; the profile you’re validating against likely requires much more; always validate against the target profile
- Incorrect data types — a
dateTimefield receiving a plain date string; check element definitions in the spec - Terminology binding errors — a code that isn’t in the required value set; verify your code system URI matches exactly
- Profile violations —
meta.profiledeclares conformance the resource doesn’t actually meet; don’t claim conformance you haven’t validated
Debugging tools:
- Postman / Insomnia — test FHIR API endpoints and inspect raw responses
- FHIR Validators — validate resources before submission; run in CI to catch regressions
- Server logs + OperationOutcome — servers return
OperationOutcomeon error; readissue.diagnosticsfor the specific path and constraint that failed - FHIR R4 specification —
hl7.org/fhir/R4/[ResourceType].htmlis the canonical element reference
See also
- FHIR glossary entry — concise term definition
- HL7 glossary entry — the standards organization
- Healthcare Interoperability: Landscape and Approach — FHIR in context alongside v2, CDA, X12
- Healthcare Standards Primer — deep-dive comparison of each standard
- FHIR Patient — Patient resource reference
- FHIR References — reference types, identifiers, referential integrity
- FHIR Search — search parameters, modifiers, pagination
- FHIR Profiling — profiles, IGs, Must Support, conformance
- FHIR Extensions — extension mechanics, governance, common mistakes
- FHIR Terminology — CodeSystem, ValueSet, bindings, terminology operations
- HL7 FHIR Specification