Musings on healthcare IT, FHIR, EHR systems, and digital health innovation

🔥 FHIR in the hole!
Back to posts

EHI → FHIR mappings that get better with every record

Original on LinkedIn

Rebuilding (and improvig) Epic’s FHIR from one patient’s EHI export — and how a tiny community of data contributions could cultivate a new kind of mapping pipeline.

Under ONC’s health-IT certification rules, any patient can request an EHI export: a complete, machine-readable copy of the electronic health information their provider holds about them. Every major EHR has to support it as a condition of certification. Epic’s version of that export is what I used here, and it is gloriously, intimidatingly raw: a near-complete dump spread across thousands of tab-separated tables. For my own record it came to 590 populated tables and about 25,000 rows: order numbers, claim lines, flowsheet readings, note text, the works. Most people who open it bounce off immediately.

Two things make the export remarkable. It is rich, carrying far more than any FHIR API typically surfaces. And its schema is openly published, documented table by table. (Structurally these tables are very close to Clarity, Epic’s reporting database.) That combination raised a question I couldn’t let go of: starting from nothing but the raw export, how much of Epic’s own FHIR API output could you reconstruct? (And could you improve upon it?)

I happen to have both halves of the picture for one patient: me. I have my EHI export, and I have my FHIR from Epic’s API. So I treated them as a paired sample, EHI on the source side and FHIR on the target side, and asked a coding agent to bridge them.

Mapping by example

Article content

Building a source-to-FHIR mapping usually means writing a specification, implementing it, and maintaining it as the source evolves: months of work and a standing team, repeated at every site. Here I skipped the spec and gave the agent examples. Here is the EHI, here is the FHIR Epic produced from it, make the first reproduce the second.

A single richly-populated record carries a surprising amount of the complexity you need. One patient still exercises dozens of resource types, repeating groups, coded and uncoded values, cross-references between resources, and plenty of messy edge cases. One record covers nowhere near everything, but it covers enough to bootstrap.

No LLM sits in the data conversion pipeline. The agent writes deterministic TypeScript translators (they live in src/), one per domain, that read the EHI and emit FHIR R4. The model authors the mapping; running it is ordinary, inspectable, reproducible code. You can diff it, review it, and run it a thousand times for the same answer. That property matters enormously for anything you’d want to trust with real data.

Output is checked by the HL7 FHIR R4 validator and by a reference-integrity pass that confirms every reference resolves to an allowed type. The part I’m proudest of is an element-by-element tolerance ledger: every element in the target FHIR is classified EXACT, TOLERATED (a justified, rule-verified difference), or GAP. Nothing is silently ignored.

The scorecard

So how faithful is it? From one patient’s EHI, the translators reconstruct 90.4% of Epic’s FHIR faithfully: 13,895 elements exact and 1,849 equivalent, out of 17,421 in the target.

Article content

The report draws this as a scorecard, one bubble per resource type, placed by how rich each instance is (average fields per instance) against how much we reproduced, and sized by how many of that type Epic returned. Some types come back essentially whole: Location 100%, DiagnosticReport 99%, Condition 97%, and Patient (a single 192-field resource) at 93%. Others are harder. Encounter is the floor at 67%, and the high-volume Observations carry the largest absolute share of what remains. The hard cases sit exactly where you’d expect, on resources that lean on context the raw tables don’t fully spell out.

One significant caveat: terminology. The EHI ships categorical values as local text, usually with no standard code attached, so LOINC, SNOMED, RxNorm, CVX, and ICD are normally absent. Rather than guess, the translators emit the text and omit the code. A separate recovered crosswalk, built by pairing the EHI’s local codes with the standard codes that do appear elsewhere in the export, then lifts standard-coding coverage from a 10% baseline to 79%. The report shows both views, so you can see exactly what the raw export gives you and what the crosswalk recovers.

What a gap actually looks like

The GAPs sort into a few recognizable kinds. A handful of small ones build the intuition.

A label locked in a dictionary the export never shipped. Epic’s FHIR shows the visit type (“Office Visit”, “Telephone”) on every encounter reference, but the export ships neither the encounter-type code nor the dictionary that spells out those labels.

Condition.encounter.display

target: "Office Visit"
ours: (absent)

A flag the server stamps on the way out. Some values are decorations the API adds at response time, with nothing in the raw data to derive them.

DocumentReference.type.coding.userSelected

target: true
ours: (absent)

A field the export has no column for. Epic’s FHIR marks whether a provider is currently active; the provider directory in the export has no status column to read.

Practitioner.active

target: true
ours: (absent)

A disagreement where we trust the export. The API and the export sometimes report different instants for the same event. We emit the export’s value; the API’s lands a few seconds earlier, matching no source byte anywhere in the dump.

DiagnosticReport.issued

target: "2022-08-29T20:41:51Z"
ours:   "2022-08-29T20:42:02Z"

A smaller set are whole resources we can’t rebuild: a few DocumentReferences exist only as API metadata, with no note body anywhere in the export to reconstruct from.

Two things the comparison revealed

Building the mappings was the goal, but the same paired sample surfaced two findings I wasn’t looking for.

The EHI export has gaps, and sometimes the FHIR has more. Plenty of data that looked “missing” was actually one join away, a “not in the export” verdict that dissolved once I searched the whole dump instead of the obvious column (CPT codes hiding in SVC_LN_INFO, marital status in CLM_VALUES, and a dozen more). More interesting were the inversions, a few places where Epic’s FHIR API carried information the EHI export simply didn’t. Each one is a concrete, located, fileable opportunity to improve the export.

The EHI carries whole domains the FHIR API doesn’t expose at all. Going the other direction, the raw export holds rich data Epic’s FHIR endpoints don’t surface today: the entire billing and financial picture (ExplanationOfBenefit, Claim, ChargeItem, Invoice, Account, PaymentReconciliation, CoverageEligibilityResponse), plus Communication, the secure MyChart messages between patient and care team. No reference FHIR existed to copy for these, so the agent built it from scratch, and it passes the validator clean. The EHI lets you map to FHIR resources that go beyond the current API surface.

From one sample to many

The obvious caveat is n=1. One patient, one site’s configuration, so rare paths and unusual data shapes stay unproven. By “faithful” I mean semantically equivalent: I emit the true EHI value even where Epic’s FHIR shows a nickname or a corporate brand, so the meaning lines up even when the literal text does not. The resource IDs are synthetic but referentially consistent, and the terminology is best-effort. Treat all of this as a proof of concept.

The single-sample framing is also the most exciting part. If one paired source↔target record gets you to ~90%, a handful of records would converge quickly, contributed by different patients, from different sites, exercising different specialties and edge cases. The EHI schema is public, so the mappings derived from it can be a shared community asset. Several individuals, each contributing their own paired data, could converge toward a common set of high-quality targets instead of every site re-deriving the same mapping in private. The translators are open, the GAPs are a public to-do list, and each new sample fills more of them in.

That’s what I find most promising. EHI→FHIR mapping has always been expensive for one reason: the months of painstaking, per-site work to discover and maintain the rules. A small amount of correlated data, in the hands of a capable agent, turns that into something a community can build together.

The code is at github.com/jmandel/ehi-to-fhir, with the translators in src/. The interactive report (scorecard, per-resource breakdowns, and every tolerated and gap element with its rationale) is at joshuamandel.com/ehi-to-fhir. The whole thing rebuilds from public inputs with one command.

Conversation on LinkedIn

27 comments · 191 reactionsReply on LinkedIn
  • Matt AbramsJun 19, 2026

    Advisor, Board Member, Co-Founder, Venture Partner, Dot Connector: cursed (and blessed) with curiosity and a drive to #leaveitbetter #startups #natsec #venture #informationquality #healthcare #informationintegrity

    Gabe Colburn

  • Michael D'InceccoJun 19, 2026

    Healthcare IT Leader | Digital and Patient Access Rev Cycle Advisor | Passionate Futurist | Sustainable Farming and Food Ecosphere Advocate | Outdoor and Youth Programming Volunteer

    The tools are powerful and you’re shepherding the new era! Thanks for all your insights. I’m encouraged with the progress to ensure data sovereignty for all.

  • Alex ThomasJun 19, 2026

    NFP Director | Snr Data/Intelligence Engineer | CyberBioSecurity, Data, BI, GIS, DevOps | Environment, Health and Human Services | Scout Ldr

    Superb…

  • Healthcare AI & Data Solutions Leader | CDMP, CPMAI, PMP

    That is truly amazing.

    1 reaction

  • Jason MarmonJun 19, 2026 · edited

    Co-founder & CTO of Novelcare (fka SelectIQ) | Ex-Palantir life sciences

    Same concept applies to unstructured docs. The regulations really should be rethought in a world where data formatting and consistency is no longer important. If EHRs were required to provide APIs to dump all the data in any format the entire industry could move 10x faster.

    3 reactions

  • Thomas K.Jun 19, 2026

    Healthcare Technical Strategist | Ex-Epic | Venture Capital

    I did something similar but the reverse for a client. Mapping many FHIR resources back to SQL queries to pull data out of Clarity.

    3 reactions

    • Michael E CampbellJun 20, 2026

      Health Informatics Consultant @ Indicina Certified Health & Wellness Coach @ Wellogin

      Thomas Kasl would the SQL on FHIR view definitions work in Clarity?

  • Christopher GyldenkærneJun 19, 2026 · edited

    Postdoc hos CAISA - Det Nationale Center for AI i Samfundet

    Jens Kristian Villadsen

    1 reaction

    • @Trifork

      Josh Mandel, MD to answer the question: yes 😀 . It is also the continuous subject for the Nordic hackathon series.

      1 reaction

  • Koray Atalag, MD, PhDJun 20, 2026 · edited

    Principal Consultant ➤ openEHR & FHIR Interoperability | VBHC & PROMs | Strategy → Architecture → Hands-on Implementation | GCC · Europe · ANZ

    https://ehignitechallenge.org/ there was a small and humble challenge by ONC to address exactly the single patient EHI export heterogenity. Josh Mandel, MD your previous post on grading hundreds of EHRs was an eye opener. I won't disclose just yet our proposal until winners are announced but what if we defined our dataset of interest and then work backwards to map or bind only those elements to source, instead of wholesale mappings - just targeted. Not suitable for all use cases but will solve a lot of others.

    2 reactions

    • Josh Mandel, MDAuthorJun 20, 2026

      Absolutely -- part of the demonstration here is saying "if you can define a coherent target format and your source data are complete enough to map, then the job of mapping is getting very fast and cheap." Nothing magic about FHIR here (but if course, it's a well defined target which makes the process easy to test without having to feel too creative.) You can map to task specific adhoc formats now.

      3 reactions

  • Meg D.Jun 20, 2026

    Reveune Cycle Healthcare Technology | Product Management & Operations Leader | Deep Experience in Medicare, Medicaid, & Regulatory Affairs | Seasoned Medical Coder - All Specialties | Passionate Patient Advocate

    Awesome!

  • Reuven SchnaiderJun 20, 2026

    Senior Project Manager | Healthcare Interoperability | FHIR | AI | Digital Health Innovation

    Very interesting.
    I wonder how different the results would be with a legacy healthcare system that has no FHIR-native API.
    In many organizations, especially outside the Epic ecosystem, the hardest problem is not generating FHIR resources. It's understanding what the source data actually means and rebuilding the clinical context that FHIR expects.
    Epic starts much closer to the finish line than most healthcare systems.
    In oncology systems, for example, workflow states, protocol logic, dose adjustments, and approval processes are often spread across multiple tables and workflows. Mapping them correctly requires much more than identifying field-to-field relationships.

    4 reactions

  • Jacob ReiderJun 21, 2026 · edited

    Health > Care

    :-)

    I exported from Epic a few weeks ago ... Had Claude combine it with other data from elsewhere, wrap it back into Epic envelope and sent to a new provider ..who imported it into their EHR without difficulty.

    End to end .. 6 minutes. Yes. I reviewed it before sending.

    My observation: no special tool necessary. The frontier models can do this darn well.

    Note that with this model there is no way to differentiate PGHD from an EHR as a source. Provenance is easy to fake.

    Hmmm

    4 reactions

  • Elliot KahenJun 22, 2026

    Multidisciplinary Data Science | Mol bio + Biochemistry pedigree. | Clinical Documentation (hem/onc/etc) | LLM/AI stuff

    While definitely cool, I frankly do not see how this or anything it would clearly lead to would improve the actual interoperability issues that preposterously continue to exist.

    * Labs: Epic has not implemented the simplest of concepts, a row which can be optionally included at the bottom of the table for each column: PERFLAB (performing lab, for example). Because of this, those in charge of mapping components/LOINC, often either just don't map external values at all, or do so selectively, because their best practices concerns about comparing data from different labs. For easily 90% of components, this worry is irrational and it 100% leads to providers missing data. I've seen it happen no less than 1000 times. Providers expect when they are trending a patients labs with CE and HT setup, that lab data from separate facilities are clearly being mapped and consolidated right? Otherwise why have this?
    i have had to explain this to 100 providers, why they are wrong, and no, it's not a bug. It's a feature.

    *Partially struct and unstructured data. "Encounters are the floor at 67%". This right here is funny from a clinically meaningful data persprective because Encounters are where those data live.
    Incongruence of priorities.

    1 reaction

    • Elliot KahenJun 22, 2026

      Multidisciplinary Data Science | Mol bio + Biochemistry pedigree. | Clinical Documentation (hem/onc/etc) | LLM/AI stuff

      I ran out of characters, started to feel kinda lazy. I can add on more if you care

      1 reaction

  • Director of Research Kaiser Permanente Northern California | DMD, ScD Strategic Leadership

    Cool!!!

  • Nathan DiNiroJun 28, 2026

    Fractional CEO/CMO/CTO | Strategic Technologist | Growth Architect | Digital Identity • Cybersecurity • AI • Immersive Media • Web3 | I Help Visionaries Brand, Build & Scale

    This isn't a surprise considering folks have been vibe coding with their data for some time now. I have actually done the reverse with some of your OS code to teach my development harness about health IT standards and practices. However, I would love to hear more signal in these posts about safety, security, and risk. As we advocate for people to have control over their data, the current risk environment that AI presents changes things in a way that's very difficult to translate. Even for lots of smart folks who have very little experience or understanding of the risks of what being presented as possible.

  • Tom WillisJun 28, 2026

    Product and Engineering Leader at Flexion Inc.

    Well played, Josh

  • Muhammad ZohaibJul 1, 2026

    Meta Ads Specialist | LinkedIn Ads Expert | Lead Generation & Performance Marketing

    Fascinating work! Using AI to accelerate FHIR mapping while keeping the output transparent and reviewable is a promising approach. Looking forward to seeing how community contributions evolve this further.

  • Full Stack OB/GYN. Healthcare Disruptor. AI x Health Ambassador. Human in the Loop. Wartime Consigliere.

    Theoretically… couldn’t every empty
    cell/field… from named tables + row and column headers, be able to reverse map the API schema?