From HL7 Pipes to FHIR APIs: A Deep Dive into Clinical Laboratory Interoperability

For clinical informaticists and data scientists: Understanding the translation layer between legacy HL7 v2.x messages and modern FHIR resources is essential for building interoperable healthcare systems. This guide walks through the complete lab workflow—from physician order to clinical decision support—showing exactly how data transforms at each step.


The Interoperability Challenge

Picture this scenario: A physician orders a fasting glucose test at 9:30 AM. By noon, the results are in the patient’s chart, flagged as abnormal, with a clinical decision support alert suggesting follow-up. Behind this seemingly simple workflow lies a complex dance of systems, standards, and semantics.

The challenge isn’t just moving data—it’s preserving meaning.

Interoperability Evolution

This is where the healthcare interoperability stack comes into play:

Healthcare Standards Stack

Standard Layer Role
HL7 v2.x Messaging Pipe-delimited transactional backbone
FHIR Structure RESTful JSON resources for modern APIs
LOINC Identification Universal codes for what was measured
SNOMED CT Semantics Clinical meaning for why and interpretation

A Real-World Scenario: Mr. Smith’s Diabetes Diagnosis

Let’s follow a complete clinical workflow to understand how these standards work together.

The Patient

Attribute Value
Name John Q. Smith
Age 55, Male
Chief Complaint Fatigue and increased thirst for 2 weeks
Clinical Suspicion Type 2 Diabetes Mellitus
MRN MRN123456

The Timeline

Lab Workflow Timeline

Now let’s examine the data structures that make this workflow possible.


Part 1: HL7 v2.x Message Anatomy

HL7 v2.x messages are the transactional backbone of healthcare. They use a pipe-delimited format that, while dated, remains ubiquitous in production systems worldwide.

Message Delimiters

Understanding the delimiter hierarchy is essential for parsing HL7:

Character Symbol Purpose
<CR> Carriage Return Segment terminator
\| Pipe Field separator
^ Caret Component separator
& Ampersand Subcomponent separator
~ Tilde Repetition separator
\ Backslash Escape character

Core Segments for Laboratory Messaging

HL7 Core Segments

Segment Name Clinical Purpose
MSH Message Header Routing metadata, message type, version
PID Patient Identification Demographics, MRN, name, DOB
PV1 Patient Visit Encounter context, attending physician
ORC Common Order Order control, placer/filler numbers
OBR Observation Request Test ordered, LOINC code, specimen info
OBX Observation/Result Actual test values and interpretations
NTE Notes Free-text clinical comments

Part 2: The Order Flow (ORM^O01)

When Dr. Williams clicks “Sign Order” in the EHR, an ORM^O01 message is generated:

Complete ORM Example

MSH|^~\&|EPIC|CITYCLINIC|LABSYS|CITYLAB|20251130093500||ORM^O01|MSG00001|P|2.5.1|||AL|NE
PID|1||MRN123456^^^CITYCLINIC^MR||Smith^John^Q||19700215|M|||123 Main St^^Chicago^IL^60601||312-555-1234
PV1|1|O|CLINIC^^^CITYCLINIC||||1234567^Williams^Robert^J^MD
ORC|NW|ORD123456^EPIC||||||^^^^^R||20251130093000|||1234567^Williams^Robert^J^MD
OBR|1|ORD123456^EPIC||2345-7^Glucose [Mass/volume] in Serum or Plasma^LN|||20251130093500||||||||1234567^Williams^Robert^J^MD
NTE|1||R/O Diabetes Mellitus - Patient reports fatigue and polyuria x 2 weeks
ORC|NW|ORD123457^EPIC||||||^^^^^R||20251130093000|||1234567^Williams^Robert^J^MD
OBR|2|ORD123457^EPIC||4548-4^Hemoglobin A1c/Hemoglobin.total in Blood^LN|||20251130093500
ORC|NW|ORD123458^EPIC||||||^^^^^R||20251130093000|||1234567^Williams^Robert^J^MD
OBR|3|ORD123458^EPIC||24323-8^Comprehensive metabolic panel^LN|||20251130093500

Segment-by-Segment Breakdown

MSH (Message Header)

The MSH segment is always first and defines the message envelope:

MSH|^~\&|EPIC|CITYCLINIC|LABSYS|CITYLAB|20251130093500||ORM^O01|MSG00001|P|2.5.1
    │    │    │          │      │       │               │       │        │ │
    │    │    │          │      │       │               │       │        │ └─ HL7 Version
    │    │    │          │      │       │               │       │        └─── Processing ID (P=Production)
    │    │    │          │      │       │               │       └───────────── Message Control ID
    │    │    │          │      │       │               └───────────────────── Message Type (Order)
    │    │    │          │      │       └───────────────────────────────────── Timestamp
    │    │    │          │      └───────────────────────────────────────────── Receiving Facility
    │    │    │          └──────────────────────────────────────────────────── Receiving Application
    │    │    └─────────────────────────────────────────────────────────────── Sending Facility
    │    └──────────────────────────────────────────────────────────────────── Sending Application
    └───────────────────────────────────────────────────────────────────────── Encoding Characters

PID (Patient Identification)

The PID segment carries all patient demographics:

PID|1||MRN123456^^^CITYCLINIC^MR||Smith^John^Q||19700215|M|||123 Main St^^Chicago^IL^60601
    │  │                         │             │        │   │
    │  │                         │             │        │   └─ Address (Street^^City^State^ZIP)
    │  │                         │             │        └───── Sex (M/F)
    │  │                         │             └────────────── DOB (YYYYMMDD)
    │  │                         └──────────────────────────── Name (Last^First^Middle)
    │  └────────────────────────────────────────────────────── MRN^^^Authority^Type
    └───────────────────────────────────────────────────────── Set ID

The patient identifier includes the assigning authority (CITYCLINIC) and identifier type (MR = Medical Record Number).

ORC (Common Order)

The ORC segment controls order management:

ORC|NW|ORD123456^EPIC||FIL789012^LABSYS|||||20251130093000|||1234567^Williams^Robert^J^MD
    │  │               │                    │                 │
    │  │               │                    │                 └─ Ordering Provider (XCN format)
    │  │               │                    └───────────────────── Transaction Date/Time
    │  │               └────────────────────────────────────────── Filler Order Number (LIS assigns)
    │  └────────────────────────────────────────────────────────── Placer Order Number (EHR assigns)
    └───────────────────────────────────────────────────────────── Order Control (NW = New Order)

Order Control Codes:

Code Meaning Use Case
NW New Order Initial order placement
CA Cancel Cancel previously placed order
XO Change Modify existing order
SC Status Changed Order status update
RE Observations Results accompanying order

OBR (Observation Request)

The OBR segment specifies what test to perform using LOINC codes:

OBR|1|ORD123456^EPIC|FIL789012^LABSYS|2345-7^Glucose [Mass/volume] in Serum or Plasma^LN
    │ │               │               │
    │ │               │               └─ Universal Service ID (LOINC Code^Display^System)
    │ │               └───────────────── Filler Order Number
    │ └───────────────────────────────── Placer Order Number
    └─────────────────────────────────── Set ID

This is where LOINC integration begins—the code 2345-7 universally identifies “Glucose [Mass/volume] in Serum or Plasma.”


Part 3: The Results Flow (ORU^R01)

When the lab completes analysis, an ORU^R01 message carries the results back:

Complete ORU Example

MSH|^~\&|LABSYS|CITYLAB|EPIC|CITYCLINIC|20251130120000||ORU^R01|MSG00002|P|2.5.1|||AL|NE
PID|1||MRN123456^^^CITYCLINIC^MR||Smith^John^Q||19700215|M|||123 Main St^^Chicago^IL^60601
PV1|1|O|CLINIC^^^CITYCLINIC||||1234567^Williams^Robert^J^MD
ORC|RE|ORD123456^EPIC|FIL789012^LABSYS||||^^^^^R||20251130093000|||1234567^Williams^Robert^J^MD
OBR|1|ORD123456^EPIC|FIL789012^LABSYS|2345-7^Glucose [Mass/volume] in Serum or Plasma^LN|||20251130094500|||||||||1234567^Williams^Robert^J^MD||||||20251130120000|||F
OBX|1|NM|2345-7^Glucose^LN||186|mg/dL|70-100|H|||F|||20251130113000||9876543^Johnson^Mary^L^MT
NTE|1||Fasting specimen confirmed
ORC|RE|ORD123457^EPIC|FIL789013^LABSYS
OBR|2|ORD123457^EPIC|FIL789013^LABSYS|4548-4^Hemoglobin A1c/Hemoglobin.total in Blood^LN|||20251130094500|||||||||1234567^Williams^Robert^J^MD||||||20251130120000|||F
OBX|1|NM|4548-4^Hemoglobin A1c/Hemoglobin.total^LN||8.2|%|4.0-5.6|H|||F|||20251130114500
NTE|1||Result indicates poor glycemic control over past 2-3 months

The OBX Segment: Heart of Lab Results

The OBX segment carries individual test results:

OBX|1|NM|2345-7^Glucose^LN||186|mg/dL|70-100|H|||F|||20251130113000
    │ │  │                   │   │      │       │   │   │
    │ │  │                   │   │      │       │   │   └─ Observation Date/Time
    │ │  │                   │   │      │       │   └───── Result Status (F=Final)
    │ │  │                   │   │      │       └───────── Abnormal Flag (H=High)
    │ │  │                   │   │      └───────────────── Reference Range
    │ │  │                   │   └──────────────────────── Units
    │ │  │                   └──────────────────────────── Result Value
    │ │  └──────────────────────────────────────────────── Observation ID (LOINC)
    │ └─────────────────────────────────────────────────── Value Type (NM=Numeric)
    └───────────────────────────────────────────────────── Set ID

Value Types in OBX:

Code Type Example
NM Numeric 186
ST String "Yellow"
CE Coded Entry 112144000^Blood group A^SCT
SN Structured Numeric <^5 or >^10000
TX Text Free-text narrative

Abnormal Flags:

Flag Meaning Clinical Significance
N Normal Within reference range
L Low Below normal
H High Above normal
LL Critical Low Panic value - immediate action needed
HH Critical High Panic value - immediate action needed

Part 4: Mapping HL7 to FHIR

Here’s where modernization happens. Each HL7 segment maps to a FHIR resource:

HL7 to FHIR Mapping Architecture

HL7 to FHIR Mapping

Mapping Matrix

HL7 Segment FHIR Resource Key Elements
PID Patient name, birthDate, gender, identifier, address
ORC/OBR ServiceRequest code (LOINC), subject, requester, status
OBX Observation code (LOINC), value, interpretation (SNOMED), referenceRange
SPM Specimen type, collection, receivedTime
ORU (full) DiagnosticReport result references, conclusion, status

FHIR Observation Example

Here’s how Mr. Smith’s glucose result transforms into FHIR:

{
  "resourceType": "Observation",
  "id": "glucose-result-mr-smith",
  "status": "final",
  "category": [{
    "coding": [{
      "system": "http://terminology.hl7.org/CodeSystem/observation-category",
      "code": "laboratory",
      "display": "Laboratory"
    }]
  }],
  "code": {
    "coding": [{
      "system": "http://loinc.org",
      "code": "2345-7",
      "display": "Glucose [Mass/volume] in Serum or Plasma"
    }]
  },
  "subject": {
    "reference": "Patient/mrn123456",
    "display": "John Q. Smith"
  },
  "effectiveDateTime": "2025-11-30T11:30:00Z",
  "valueQuantity": {
    "value": 186,
    "unit": "mg/dL",
    "system": "http://unitsofmeasure.org",
    "code": "mg/dL"
  },
  "interpretation": [{
    "coding": [{
      "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation",
      "code": "H",
      "display": "High"
    }]
  }],
  "referenceRange": [{
    "low": { "value": 70, "unit": "mg/dL" },
    "high": { "value": 100, "unit": "mg/dL" },
    "text": "70-100 mg/dL"
  }],
  "performer": [{
    "reference": "Practitioner/tech-mary-johnson",
    "display": "Mary L. Johnson, MT"
  }]
}

The Power of Coded Elements

Notice how the FHIR resource embeds multiple coding systems:

Coded Elements in FHIR

  • LOINC (http://loinc.org): Identifies what was tested
  • UCUM (http://unitsofmeasure.org): Standardizes units
  • HL7 Interpretation codes: Flags abnormal values
  • SNOMED CT (when needed): Provides clinical semantics

Part 5: LOINC Deep Dive

LOINC (Logical Observation Identifiers Names and Codes) provides universal test identification through a 6-part model:

LOINC Code Structure

LOINC 6-Part Model

Part Name Example (2345-7)
1 Component Glucose
2 Property MCnc (Mass Concentration)
3 Time Pt (Point in time)
4 System Ser/Plas (Serum or Plasma)
5 Scale Qn (Quantitative)
6 Method (optional)

Combined: Glucose.MCnc.Pt.Ser/Plas.Qn = 2345-7

Essential Laboratory LOINC Codes

LOINC Test Category
2345-7 Glucose (Fasting) Chemistry
4548-4 Hemoglobin A1c Diabetes
2951-2 Sodium Electrolytes
2823-3 Potassium Electrolytes
2160-0 Creatinine Renal
718-7 Hemoglobin Hematology
6690-2 WBC Count Hematology
5902-2 Prothrombin Time Coagulation
883-9 ABO Group Blood Bank

LOINC in the Wild

In HL7 OBR/OBX:

OBR|1|...|2345-7^Glucose [Mass/volume] in Serum or Plasma^LN|...
         └─────┘                                           └─┘
         LOINC Code                                       LN = LOINC

In FHIR:

{
  "code": {
    "coding": [{
      "system": "http://loinc.org",
      "code": "2345-7",
      "display": "Glucose [Mass/volume] in Serum or Plasma"
    }]
  }
}

Part 6: SNOMED CT for Clinical Meaning

While LOINC tells you what was measured, SNOMED CT tells you what it means.

When SNOMED CT Applies

SNOMED CT Use Cases

  • Qualitative results: Blood type (A, B, AB, O)
  • Interpretations: Positive, Negative, Indeterminate
  • Clinical findings: Associated conditions
  • Diagnoses: Linked clinical diagnoses

Example: Blood Type Result

HL7 OBX (Coded Entry):

OBX|1|CE|882-1^ABO Group^LN||112144000^Blood group A^SCT||||N|||F
                               └─────────────────────────────┘
                               SNOMED CT code for "Blood group A"

FHIR Observation:

{
  "valueCodeableConcept": {
    "coding": [{
      "system": "http://snomed.info/sct",
      "code": "112144000",
      "display": "Blood group A (finding)"
    }]
  }
}

Common SNOMED CT Codes for Lab

Code Display Use Case
260385009 Negative Qualitative negative result
10828004 Positive Qualitative positive result
112144000 Blood group A ABO typing
278147001 Blood group O ABO typing

Part 7: The Complete Integration Architecture

Here’s how it all fits together in production:

Integration Architecture

Transformation Pipeline

Transformation Pipeline


Part 8: Clinical Results for Mr. Smith

Here’s the final results summary with clinical interpretation:

Results Table

Test LOINC Result Units Range Flag
Glucose, Fasting 2345-7 186 mg/dL 70-100 HIGH
Hemoglobin A1c 4548-4 8.2 % 4.0-5.6 HIGH
Sodium 2951-2 140 mmol/L 136-145 Normal
Potassium 2823-3 4.2 mmol/L 3.5-5.0 Normal
Chloride 2075-0 102 mmol/L 98-106 Normal
CO2 2028-9 24 mmol/L 23-29 Normal
BUN 3094-0 18 mg/dL 7-20 Normal
Creatinine 2160-0 1.0 mg/dL 0.7-1.3 Normal
Calcium 17861-6 9.4 mg/dL 8.5-10.5 Normal

Clinical Interpretation

The elevated fasting glucose (186 mg/dL) and HbA1c (8.2%) are consistent with Type 2 Diabetes Mellitus. Normal renal function (BUN, Creatinine) indicates no diabetic nephropathy at this time. Electrolytes within normal limits.

Diagnosis: Type 2 Diabetes Mellitus (ICD-10: E11.9)

What Makes This Data Interoperable

Interoperability Success Factors

  1. LOINC codes ensure the glucose test from City Clinic is recognized identically at any other facility
  2. Reference ranges enable automatic flagging regardless of which EHR displays results
  3. Structured data allows CDS rules to fire: “If Glucose > 126 AND HbA1c > 6.5, suggest Diabetes workup”
  4. FHIR resources enable real-time API queries across systems

Key Takeaways for Implementers

For Data Engineers

  1. Parse before transforming: Validate HL7 delimiter handling before FHIR mapping
  2. Preserve identifiers: Placer/filler order numbers link orders to results
  3. Handle repetitions: OBX segments repeat; create one Observation per OBX
  4. Validate terminology: LOINC codes must be valid; implement terminology server lookups

For Clinical Informaticists

  1. Map local codes: Many LIS systems use local codes—map them to LOINC
  2. Preserve clinical notes: NTE segments contain critical clinical context
  3. Abnormal flag consistency: Ensure HL7 flags map correctly to FHIR interpretations
  4. Reference range normalization: Different analyzers may have different ranges

For Data Scientists

  1. Structured codes enable ML: LOINC/SNOMED coded data is ML-ready
  2. Temporal data matters: effectiveDateTime enables time-series analysis
  3. Reference ranges as features: Abnormal flags are pre-computed clinical features
  4. Linkage is key: Patient/Encounter references enable longitudinal analysis

Resources and Further Reading

Official Standards

Resource URL
HL7 International https://www.hl7.org
FHIR R4 Specification https://www.hl7.org/fhir/
LOINC https://loinc.org
SNOMED CT https://www.snomed.org

Tools

Tool Purpose
RELMA LOINC mapping and search tool
HAPI FHIR Open-source FHIR server (Java)
Mirth Connect HL7 integration engine
Synthea Synthetic patient data generator

Conclusion

The journey from HL7 pipes to FHIR APIs represents healthcare IT’s transition from systems that talk to systems that understand. By leveraging:

  • HL7 v2.x for legacy transactional messaging
  • FHIR for modern, API-driven architecture
  • LOINC for universal test identification
  • SNOMED CT for clinical semantic meaning

We enable clinical systems to not just transfer data, but to reason about it—powering clinical decision support, AI/ML applications, and truly interoperable healthcare.

The pipes are still there. But now they carry meaning.


Have questions about implementing lab interoperability? Connect with me on GitHub or drop a comment below.


Tags: #FHIR #HL7 #LOINC #SNOMEDCT #Interoperability #ClinicalInformatics #HealthcareIT #LIS #EHR #DataStandards #HealthTech