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 resource
  • GET /[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.

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:

  1. Structural — JSON is well-formed and matches the FHIR resource schema
  2. Cardinality — required fields are present; counts satisfy min/max
  3. Data type — values match expected types (string, integer, dateTime, etc.)
  4. Terminology — codes are valid against their declared code systems and value sets
  5. 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:

  1. 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
  2. Missing required fields — base FHIR requires very little; the profile you’re validating against likely requires much more; always validate against the target profile
  3. Incorrect data types — a dateTime field receiving a plain date string; check element definitions in the spec
  4. Terminology binding errors — a code that isn’t in the required value set; verify your code system URI matches exactly
  5. Profile violationsmeta.profile declares 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 OperationOutcome on error; read issue.diagnostics for the specific path and constraint that failed
  • FHIR R4 specificationhl7.org/fhir/R4/[ResourceType].html is the canonical element reference

See also

Section: fhir Content Type: reference Audience: technical
FHIR Versions:
R4 R4B R5
Published: 09/04/2022 Modified: 31/01/2026 10 min read
Keywords: FHIR HL7 FHIR healthcare interoperability health data exchange FHIR resources FHIR implementation FHIR server FHIR client
Sources: