Docs · FHIR Mapping

FHIR data mapping: from CSV to FHIR-ready fields

Most healthcare data does not arrive as FHIR. It arrives as a CSV export, an Excel sheet, or a legacy table — in five languages, with free-text headers and inconsistent code systems. FHIR mapping is the work of turning those columns into the resources, fields, and terminology that a FHIR-aware system expects.

Concepts

What FHIR mapping is

FHIR (Fast Healthcare Interoperability Resources, an HL7 standard) models healthcare data as resources — for example a Patient, an Observation, a Medication, or a Claim. Each resource has defined fields (elements) with types and cardinality, and many fields carry terminology bindings — they expect a coded value drawn from a specific code system rather than free text.

FHIR mapping, then, is a three-part problem: figure out which FHIR resource a row of your data represents, line up each of your columns with the right field on that resource, and make sure coded fields carry values from the right terminology — LOINC for lab observations, ICD-10 for diagnoses, CPT for procedures, and so on. The standard spells out the resources and their fields in detail at hl7.org/fhir.

The hard part

Why CSV → FHIR is hard

The gap between a spreadsheet and a FHIR resource is wider than it looks. Three things make it hard:

  • Free-text headers. A column called DOB, birth_dt, or Patient Birthday all mean Patient.birthDate, but no two source systems agree on the spelling.
  • Locale variance. Headers, date formats, and gender values differ across German, French, Italian, English, and Spanish source systems — common in multi-region healthcare data.
  • Code systems. FHIR’s coded fields expect values from specific terminologies — LOINC, ICD-10, CPT, ATC, NPI — and a raw export rarely arrives validated against them.

Get any of these wrong and the resulting resource is either rejected by the receiving system or — worse, for your-money-or-your-life healthcare data — silently incorrect.

The approach

How AdaptivMapr maps to FHIR

AdaptivMapr maps your inbound columns to a template’s canonical fields, and each healthcare template carries a fhir_resource mapping so you always know which FHIR resource and path a field corresponds to. It resolves and validates the mapping layer; your pipeline serialises the FHIR-ready fields into resources.

The 5-layer cascade

Header resolution runs through five layers, cheapest first. When a layer accepts a column, the layers below it never run — and the metered LLM is the last resort, not the first move.

  1. 1 · Statistics — no AI cost, deterministic; auto-accepts headers seen mapped the same way before.
  2. 2 · Heuristic — no AI cost; compares the normalised header against the column name, label, and every multilingual hint (DE / FR / IT / EN / ES).
  3. 3 · Fuzzy — no AI cost, pure compute; tolerates typos and reordered tokens.
  4. 4 · Semantic — cheap, cached embeddings for the long tail of paraphrases.
  5. 5 · LLM — metered; fires only on genuinely ambiguous columns, constrained to the template’s allowed field set so it cannot invent a field.

Validators & HITL gating

Healthcare templates attach field-level validators — LOINC, ICD-10, CPT, ATC, NPI, GTIN, IBAN and more — that run on every committed row. Each template also carries a risk level. Medium- and high-risk templates — patient_demographics, lab_results, claims_line_items, and drug_formulary — return requires_hitl: true with hitl_status: "pending_review" so you can gate your own commit workflow with a human review step.

On data handling: schema-only mapping is the default data-minimization mode — only headers and up to three sample rows (≤80 characters each) leave your environment. Full-data mapping requires a PHI subscription, where the layer-5 LLM call is routed through a PHI-eligible provider with X-PHI and X-Region headers to force a PHI-eligible, in-region model. A BAA is available; AdaptivMapr is HIPAA-aware.

Worked examples

Three columns, mapped

Each example links to the live template page, where you can see the full canonical schema, validators, and FHIR resource mapping.

mapping
"Geburtsdatum"  →  date_of_birth
  template  : patient_demographics_v1
  fhir      : Patient.birthDate
  caught by : Layer 2 · Heuristic

The German header matches a registered hint after the normalising pass, so the column resolves without AI. The date_range validator (1900-01-01 to today) fires on commit.

Patient demographics template →
mapping
"code loinc"  →  loinc_code
  template  : lab_result_catalog_v1
  fhir      : Observation.code
  caught by : Layer 2 · Heuristic

The French label resolves against the loinc hint, and the loinc_code validator checks the value against LOINC’s code format on commit.

Lab result catalog template →
mapping
"Diagnose (ICD)"  →  icd10_code
  template  : claims_line_items_v1
  fhir      : Claim.item
  caught by : Layer 3 · Fuzzy

A messy header with extra tokens still resolves via the fuzzy layer. Because this template is risk medium, the mapping is returned with requires_hitl:true so your team can gate the commit.

Claims line items template →

Questions

FHIR mapping FAQ

AdaptivMapr maps your inbound columns to a template’s canonical fields, and each healthcare template carries a fhir_resource mapping (for example Patient, Observation, or Claim.item) so you know which FHIR resource and path each field corresponds to. AdaptivMapr resolves and validates the mapping layer — it does not, on its own, emit a fully conformance-checked FHIR bundle. The output is a clean, validated, FHIR-ready field set that your downstream pipeline serialises into resources.
Healthcare templates ship field-level validators for the common clinical and administrative code systems, including LOINC (lab observations), ICD-10 (diagnoses), CPT (procedures), ATC and GTIN (drugs), NPI and GLN (providers), and IBAN (payment). Validators run on every committed row and surface failures in the per-row validation report.
Not in schema-only mode, the default data-minimization path: only your headers and up to three sample rows (each clamped to 80 characters) ever leave your environment. Full-data mapping requires a PHI subscription; the layer-5 LLM call is then routed through a PHI-eligible provider with X-PHI and X-Region headers so a PHI-eligible, in-region model is used. A BAA is available for full-data use.
Templates carry multilingual hints in German, French, Italian, English, and Spanish. A normalising pass strips accents, punctuation, and whitespace before the heuristic, fuzzy, and semantic layers compare your header against the canonical column name, label, and every hint. Most real-world headers resolve in those free, deterministic or cheap layers before the metered LLM is ever called.

Get started

Map your first file — without shipping raw records.

Schema-only mapping keeps raw records on your side — start there. The documentation covers the API, the MCP server, and the template catalogue.

Prepaid token wallet · schema-only data-minimization mode