ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

An introduction to FHIR for non-healthcare developers

FHIR — Fast Healthcare Interoperability Resources — is healthcare's REST API. If you have ever written a GET/POST/PUT to an endpoint and read back JSON, you already know 80% of FHIR. This page covers the remaining 20%.

Why FHIR exists

Before FHIR, healthcare interoperability rested on two main standards, incompatible with each other. HL7 v2.5.1 (1989, 2007 for the minor) is a pipe-delimited protocol extremely deployed in hospitals but ill-suited to modern APIs. HL7 v3 (2005) is a rigorous XML standard but heavy, never convinced clinically: too verbose, too academic, learning curve too steep.

In 2011, Grahame Grieve started FHIR as an experimental project at HL7: take the best of v2 (pragmatic, modular) and v3 (structured model, terminologies) and expose it as a REST API with JSON or XML as representation. The DSTU version shipped in 2014, STU3 in 2017, R4 in 2019, R4B in 2022, and R5 became normative in March 2023. FHIR is today the de facto standard for any new external healthcare interface.

The Resource, basic block

In FHIR, everything is a Resource. A Resource is a self-contained business unit — a patient, an observation, a prescription, an appointment, a diagnosis — with its own identifier and URL. FHIR R5 defines about 160 Resource types, organised in families. A few essentials:

  • Patient — patient demographics;
  • Practitioner — a healthcare professional;
  • Encounter — a stay or consultation;
  • Observation — a clinical measurement (blood pressure, glucose);
  • Condition — a diagnosis;
  • MedicationRequest — a prescription;
  • DiagnosticReport — a test report (lab, imaging);
  • Appointment — a scheduled appointment.

Each Resource has a JSON and XML schema defined by HL7. A minimal Patient in JSON:

{ "resourceType":"Patient", "id":"example", "name":[{"family":"Dupont","given":["Marie"]}], "gender":"female", "birthDate":"1985-12-10" }

The resourceType field is mandatory at the top: it tells the parser which Resource this is. The id field is the local permalink (on this FHIR server), distinct from business identifiers found in identifier.

The Bundle, Resource container

A Bundle is a Resource of a peculiar kind: it contains other Resources. It is FHIR's equivalent of the SBDH envelope on the PEPPOL side or the UNG segment in EDIFACT: a container to transmit several documents at once. Bundles serve several purposes: search result (type: searchset), atomic transaction (type: transaction), complete clinical document (type: document), or FHIR message (type: message).

A transaction Bundle lets you create several linked Resources in a single HTTP request: for example a Patient + Encounter + Observation, with atomicity over the set. If one fails, none is created. It is healthcare's equivalent of the commerce-side PO/ASN/INVOIC saga.

The FHIR REST API in practice

The standard FHIR interaction is the REST API. A few typical verbs:

  • GET /Patient/example — retrieve a Resource by id;
  • POST /Patient with a Patient JSON body — create a new Resource;
  • PUT /Patient/example with a Patient JSON body — replace (idempotent);
  • DELETE /Patient/example — delete (often logical, soft delete);
  • GET /Patient?name=Dupont&birthdate=1985-12-10 — search with standardised parameters.

Beyond classic REST verbs, FHIR adds special operations prefixed with $: $everything returns every Resource linked to a Patient (full summary); $expand on a ValueSet unfolds a list of codes; $validate checks that a Resource respects a given profile.

The FHIR server also exposes a CapabilityStatement at the root (GET /metadata) describing every supported Resource, available operations, and accepted search parameters. It is FHIR's equivalent of an OpenAPI: automatic capability introspection.

Implementation Guides (IG)

FHIR R5 publishes generic Resources that cannot, as-is, cover every country's, sector's, or use case's needs. To bridge that gap, HL7 and national communities publish Implementation Guides (IG): packages that constrain Resources, fix mandatory values, add specific constraints.

A few key IGs in 2026:

  • US Core — US IG that serves as a base for every US EHR;
  • IPS (International Patient Summary) — international IG for cross-border patient summaries (used by EHDS);
  • Interopérabilité Santé France — IG published by the French Agence du Numérique en Santé (ANS) for the French ecosystem (DMP, Mon Espace Santé);
  • CARIN BB — US IG for sharing health insurance data between payers and patients;
  • SMART on FHIR App Launch — technical IG for launching third-party applications.

An IG is technically a set of profiles (StructureDefinition), ValueSets (allowed-code lists), CapabilityStatements and documentation pages. The whole is packaged in an NPM-like format and downloadable from HL7.org. FHIR servers can validate a Resource against an IG using the $validate operation.

SMART on FHIR — standardised authentication

A fundamental question: how does a third-party app authenticate against a FHIR server? SMART on FHIR answers it. It is a 2014 standard using OAuth 2.0 + OpenID Connect with healthcare-specific scopes: patient/*.read allows reading every Resource tied to a patient, user/Patient.read allows reading every patient, and so on.

The SMART "App Launch" flow lets an EHR (Electronic Health Record) launch a third-party app — for example a diabetes management tool — in the context of a given patient, with a time-limited and scope-limited access token. Over 700 SMART- certified apps exist in 2026, and every major US EHR (Epic, Cerner, Allscripts) supports the flow.

Common pitfalls on first contact

A few typical mistakes when discovering FHIR from other backgrounds:

  • Conflating id and identifier. id is the local permalink on the FHIR server (often a UUID); identifier is the business identifier (SSN, GLN, RPPS). Conflating them in a mapping is the number-one mistake of newcomers.
  • Forgetting the system field. Every FHIR identifier and code is qualified by a system URI: urn:oid:1.2.250.1.213.1.4.8 for the French RPPS, http://loinc.org for LOINC, etc. Without a system the code is ambiguous and invalid.
  • Ignoring versions. Many US EHRs still expose R4, not R5. R4↔R5 backward compatibility is partial (R4B is a clinical-Resource stabilisation tier). Always check the FHIR version of the server via CapabilityStatement before coding.
  • Under-estimating terminologies. FHIR points to external terminologies — LOINC, SNOMED CT, ICD-10, RxNorm — with their own usage rules, their own licences (SNOMED CT is paid in some countries), and their own annual updates. A serious FHIR project always has a terminology workstream.

Further reading