Healthcare Standards Primer
Healthcare Standards Primer
Five standards dominate healthcare data exchange in the US and internationally: HL7 v2, CDA/C-CDA, FHIR, X12, and DICOM. Each was designed for a different era and a different problem. None is going away soon. As an integrator you will encounter all of them — often within the same organisation, sometimes within the same workflow.
This article gives you enough depth on each standard to recognise messages in the wild, understand why things are structured the way they are, and make informed integration decisions. FHIR gets a summary here; the full treatment is at What Is FHIR.
HL7 v2
HL7 v2 is the most widely deployed healthcare messaging standard in existence. Depending on which survey you believe, somewhere between 70% and 95% of health information exchange in US hospitals today still moves over v2. It was designed in the late 1980s for real-time event-driven messaging over point-to-point connections. That design is both its strength and its limitation.
Message structure
A v2 message is a sequence of pipe-delimited segments, each on its own line. The first segment is always MSH (Message Header), which defines encoding characters, sending and receiving application identifiers, the message type, and the timestamp. Every message starts with MSH.
The encoding characters appear in positions 2–5 of the MSH segment:
MSH|^~\&|...
|— field separator^— component separator (within a field)~— repetition separator (for repeating fields)\— escape character&— subcomponent separator
These are fixed by convention. If you see |^~\& in a text stream, you are looking at an HL7 v2 message.
Common segments
| Segment | Name | Purpose |
|---|---|---|
MSH | Message Header | Metadata for every message: source, destination, type, timestamp, version |
PID | Patient Identification | Demographics: name, DOB, sex, address, MRNs, SSN |
PV1 | Patient Visit | Encounter info: location, attending physician, admit type, visit number |
OBR | Observation Request | Order details: order number, ordered test, ordering provider |
OBX | Observation Result | A single result value: the workhorse of lab and clinical data |
AL1 | Allergy Information | Allergy code, reaction, severity |
DG1 | Diagnosis | ICD code, description, type |
ZXX | Z-segments | Custom extensions — not standardised, site-specific |
A minimal ORU^R01 message
An ORU^R01 is an unsolicited observation result — the standard way a lab system sends results to an EHR:
MSH|^~\&|LAB_SYSTEM|REGIONAL_HOSPITAL|EHR_APP|MAIN_CAMPUS|20231015143022||ORU^R01|MSG00123|P|2.5.1
PID|1||MRN12345^^^REGIONAL_HOSPITAL^MR||SMITH^JOHN^A||19780315|M|||123 MAIN ST^^SPRINGFIELD^IL^62701^USA
PV1|1|I|4WEST^401^A^REGIONAL_HOSPITAL||||1234567^JONES^SARAH^M^^^MD|||||||||V987654
OBR|1|ORD98765^EHR_APP|RES11111^LAB_SYSTEM|2093-3^Sodium^LN|||20231015140000|||||||||1234567^JONES^SARAH^M^^^MD
OBX|1|NM|2093-3^Sodium^LN||138|mmol/L|136-145||||F|||20231015141500
OBX|2|NM|2823-3^Potassium^LN||4.1|mmol/L|3.5-5.0||||F|||20231015141500
Reading this: the lab system LAB_SYSTEM is sending to EHR_APP at timestamp 20231015143022. Patient John A. Smith, MRN MRN12345, has two results: Sodium 138 mmol/L (normal) and Potassium 4.1 mmol/L (normal). The F in position 12 of each OBX means the result is Final.
Common message types
| Message Type | Trigger Event | Meaning |
|---|---|---|
ADT^A01 | Admit/Visit Notification | Patient admitted or registered |
ADT^A03 | Discharge/End Visit | Patient discharged |
ADT^A08 | Update Patient Information | Demographics changed |
ORU^R01 | Unsolicited Observation Result | Lab or clinical results |
ORM^O01 | General Order | Lab or imaging order |
MDM^T02 | Original Document Notification with Content | Document (e.g., clinical note) transmitted |
ACK^xxx | General Acknowledgement | ACK or NAK for any received message |
ACK/NAK
Every v2 message expects an acknowledgement. A positive ACK confirms receipt:
MSH|^~\&|EHR_APP|MAIN_CAMPUS|LAB_SYSTEM|REGIONAL_HOSPITAL|20231015143023||ACK^R01|ACK00123|P|2.5.1
MSA|AA|MSG00123
MSA|AA means Application Accept. MSA|AE means Application Error (the message was received but something was wrong with the content). MSA|AR means Application Reject. If your interface engine gets AE or AR, the sending system’s message was not processed — it is not equivalent to the message being lost, it means the receiving application rejected it.
The version fragmentation problem
HL7 v2 has versions 2.1 through 2.9. Each version added fields and segments. The problem is that two systems negotiating v2.5.1 are not guaranteed to implement the same optional fields — and most fields are optional. The standard specifies that unrecognised segments should be silently ignored, which means a sender can populate a field that the receiver will never read, with no error.
In practice, every v2 interface is a custom implementation. The standard provides a vocabulary and a structure, but the actual field mapping between any two systems must be documented and agreed bilaterally. Expect an interface specification document (ISD or interface contract) for every v2 integration.
Z-segments
Anything starting with Z is a custom extension. Common examples: ZPI for additional patient identifiers, ZPR for custom result metadata, ZIN for insurance information not covered by standard segments. Z-segments are not interoperable — they are site-specific. When you see a Z-segment in a specification, read the source documentation; there is no HL7 definition for it.
CDA / C-CDA
The Clinical Document Architecture (CDA) is an HL7 standard for clinical documents, published in 2005. Consolidated CDA (C-CDA) is the US-specific set of document templates built on top of CDA, defined by ONC and required by Meaningful Use. When you see a patient summary, discharge summary, or progress note exchanged between hospital systems or through a Health Information Exchange (HIE), it is almost certainly a C-CDA document.
XML document structure
CDA is XML. Every CDA document has the same top-level structure:
<ClinicalDocument xmlns="urn:hl7-org:v3">
<!-- Header -->
<typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040"/>
<templateId root="2.16.840.1.113883.10.20.22.1.2"/> <!-- CCD template -->
<id root="..." extension="..."/>
<code code="34133-9" codeSystem="2.16.840.1.113883.6.1" displayName="Summarization of Episode Note"/>
<title>Continuity of Care Document</title>
<effectiveTime value="20231015143022"/>
<confidentialityCode code="N" codeSystem="..."/>
<recordTarget>
<patientRole>
<id root="..." extension="MRN12345"/> <!-- Patient identifier -->
<patient>
<name><given>John</given><family>Smith</family></name>
<birthTime value="19780315"/>
<administrativeGenderCode code="M" .../>
</patient>
</patientRole>
</recordTarget>
<author>...</author>
<custodian>...</custodian>
<!-- Body -->
<component>
<structuredBody>
<component>
<section>
<templateId root="..."/>
<code code="11450-4" .../> <!-- Problem list section -->
<title>Problem List</title>
<text>...</text> <!-- Human-readable narrative — REQUIRED -->
<entry>
<!-- Machine-readable clinical statement -->
</entry>
</section>
</component>
</structuredBody>
</component>
</ClinicalDocument>
The header carries patient identity, author, and custodian. The body contains sections (each keyed to a LOINC code), and each section contains a mandatory human-readable <text> narrative plus optional machine-readable <entry> elements.
The CDA hierarchy
ClinicalDocument
└── section (one per clinical domain: problems, medications, allergies, etc.)
└── entry
└── act / observation / substanceAdministration / procedure / encounter
└── entryRelationship (nested clinical statements)
The <observation> element is the workhorse. An observation has a code (what was observed), a value (the result), a status code, and an effective time. The observation inside an entry is what a downstream system parses to extract discrete data.
Common C-CDA document types
| Document Type | LOINC Code | Regulatory Context |
|---|---|---|
| Continuity of Care Document (CCD) | 34133-9 | Transitions of care, Meaningful Use |
| Discharge Summary | 18842-5 | Hospital discharge, required by many payers |
| Progress Note | 11506-3 | Outpatient encounters |
| History and Physical | 34117-2 | Admission documentation |
| Operative Note | 11504-8 | Surgical procedures |
| Referral Note | 57133-1 | Specialist referrals |
Why C-CDA is hard to parse reliably
Three interrelated problems make C-CDA difficult to consume:
Narrative-only entries. The spec requires the <text> narrative but makes <entry> elements optional. Many real-world C-CDAs contain rich narrative that a human can read but no machine-parseable entries at all. A consuming system cannot reliably assume entries exist.
Inconsistent section templates. The template IDs used to identify sections vary between vendors. A problems section might use any of several templateId values depending on the C-CDA version and vendor implementation. You cannot rely on a single templateId — you must check the section <code> LOINC value.
Coded vs uncoded entries. Even when entries exist, the coded values may be in different code systems (ICD-10, SNOMED, local codes) across vendors. A problem list entry might carry a SNOMED code from one vendor and an ICD-10 code from another, with no overlap.
The practical implication: always validate that entries are present and coded before attempting to extract discrete data. Fall back to narrative parsing (NLP) for sections where structured entries are absent.
FHIR
FHIR (Fast Healthcare Interoperability Resources) is the current-generation HL7 standard. Where v2 is message-based and CDA is document-based, FHIR is resource-based: discrete, addressable clinical concepts accessed via RESTful APIs.
Key characteristics from an integrator’s perspective:
- JSON-first (XML is also supported, but JSON is the default in modern implementations)
- Resources are individually addressable:
GET /Patient/123,GET /Observation?subject=Patient/123 - Modular: use only the resources relevant to your use case
- Extensible: profiles constrain and extend base resources for specific contexts (US Core, Da Vinci, etc.)
- SMART on FHIR handles OAuth2-based authorisation for patient-facing and provider-facing apps
The critical architectural difference from v2 and CDA: in v2 and CDA, data is embedded in messages or documents that are pushed to a destination. In FHIR, data lives in resources on a server and is pulled on demand. This inverts the integration model.
See What Is FHIR for the full treatment of resources, REST operations, profiles, and implementation guides.
X12
X12 is the EDI (Electronic Data Interchange) standard used for US healthcare billing, eligibility, and administrative transactions. It is maintained by ASC X12 (Accredited Standards Committee). Unlike HL7 standards, X12 was not designed specifically for healthcare — it is a general-purpose EDI standard with healthcare-specific transaction sets.
X12 is not going away. Despite FHIR’s emergence, X12 dominates production billing workflows today and is mandated by HIPAA for specific administrative transactions. Any integration touching payer systems will encounter X12.
Key healthcare transaction sets
| Transaction Set | Name | Purpose |
|---|---|---|
| 837P | Professional Claim | Outpatient, physician services |
| 837I | Institutional Claim | Inpatient, hospital services |
| 837D | Dental Claim | Dental services |
| 835 | Health Care Claim Payment/Advice | Remittance advice — explanation of payment |
| 270 | Eligibility, Coverage or Benefit Inquiry | Ask payer: is this patient covered? |
| 271 | Eligibility, Coverage or Benefit Information | Payer response with coverage details |
| 276 | Health Care Claim Status Request | Ask payer: what is the status of this claim? |
| 277 | Health Care Claim Status Response | Payer response with claim status |
| 278 | Health Care Services Review — Request/Response | Prior authorization |
Loop and segment structure
X12 uses a hierarchical structure of loops and segments. A segment is a line of tilde-delimited data elements. An envelope wraps transaction sets, which contain loops, which contain segments.
ISA*00* *00* *ZZ*SENDER_ID *ZZ*RECEIVER_ID *231015*1430*^*00501*000000001*0*P*:~
GS*HS*SENDER*RECEIVER*20231015*1430*1*X*005010X279A1~
ST*270*0001*005010X279A1~
BHT*0022*13*10001234*20231015*1430~
HL*1**20*1~
NM1*PR*2*REGIONAL HEALTH PLAN*****PI*12345~
HL*2*1*21*1~
NM1*1P*1*JONES*SARAH****XX*1234567890~
HL*3*2*22*0~
TRN*1*93175-012547*9877281234~
NM1*IL*1*SMITH*JOHN****MI*MEM123456789~
DMG*D8*19780315*M~
DTP*291*D8*20231015~
EQ*30~
SE*12*0001~
GE*1*1~
IEA*1*000000001~
This is a 270 eligibility inquiry. Reading the envelope:
ISA— Interchange Control Header (sender, receiver, timestamp, version)GS— Functional Group Header (transaction typeHS= health care eligibility)ST— Transaction Set Header (270 = eligibility inquiry)HL— Hierarchical Level segments define the hierarchy: payer → requesting provider → subscriberNM1— Name segments identify each partyEQ— Eligibility or Benefit Inquiry — what benefit is being queried (30= health benefit plan coverage)SE/GE/IEA— closing envelope segments
The * separates data elements within a segment. The ~ is the segment terminator. The : in the ISA header is the component element separator.
The indirection problem
X12 is the payer-facing standard. Provider systems (EHRs, billing systems) generate X12 transactions; clearinghouses translate and route them to payers; payers respond in X12. The provider-side system doesn’t talk directly to the payer — it talks to a clearinghouse, which handles the translation and routing.
This means X12 integration is typically clearinghouse integration, not payer integration. You send 837s to your clearinghouse, receive 835s from it, and query 270/271 through it. Each clearinghouse has its own API or SFTP conventions layered on top of the X12 structure.
FHIR is the emerging replacement for some X12 transactions (CoverageEligibilityRequest/Response replacing 270/271; Claim replacing 837; ClaimResponse replacing 835), but payer systems have not migrated at scale. Plan for X12 as the production reality and FHIR as the transition path.
DICOM
DICOM (Digital Imaging and Communications in Medicine) is the standard for medical imaging. It covers how imaging devices (CT scanners, MRI machines, ultrasound, X-ray) capture, store, and transmit images and associated metadata. DICOM predates FHIR by decades and operates at the PACS (Picture Archiving and Communication System) layer.
Modalities
| Abbreviation | Modality |
|---|---|
| CT | Computed Tomography |
| MR | Magnetic Resonance Imaging |
| XR / CR | X-Ray / Computed Radiography |
| US | Ultrasound |
| NM | Nuclear Medicine |
| PT | Positron Emission Tomography |
| MG | Mammography |
| ECG | Electrocardiography |
Object model
DICOM organises imaging data in a three-level hierarchy:
Study (one imaging encounter)
└── Series (one acquisition run — e.g., one set of CT slices)
└── Instance (one image / one SOP instance — e.g., one DICOM slice)
Each level has a unique identifier (Study Instance UID, Series Instance UID, SOP Instance UID). These UIDs are globally unique by construction and are the primary keys for DICOM data retrieval.
The DICOM object (a .dcm file) contains both the image pixel data and a rich metadata header: patient name, study date, modality, body part examined, series description, and hundreds of other attributes defined in the DICOM data dictionary.
Key DICOM services
| Service | Type | Purpose |
|---|---|---|
| C-STORE | Push | Send a DICOM image from one system to another |
| C-FIND | Query | Search for studies, series, or instances matching criteria |
| C-MOVE | Retrieve | Request that a system send images to a third-party destination |
| C-GET | Retrieve | Request that a system send images to the requesting system |
| WADO-RS | RESTful | HTTP-based image retrieval (part of DICOMweb) |
| STOW-RS | RESTful | HTTP-based image storage (part of DICOMweb) |
| QIDO-RS | RESTful | HTTP-based query (part of DICOMweb) |
C-STORE/C-FIND/C-MOVE use DICOM’s legacy DIMSE (DICOM Message Service Element) protocol over TCP. DICOMweb (WADO-RS, STOW-RS, QIDO-RS) is the modern RESTful interface — if you are building new integrations, prefer DICOMweb.
Why DICOM and FHIR coexist
DICOM owns the imaging device and PACS layer. FHIR’s ImagingStudy resource is a pointer to DICOM content — it carries the Study Instance UID, series metadata, and instance UIDs, but not the pixel data itself. The pixel data lives in PACS and is retrieved via WADO-RS.
The integration pattern: FHIR provides the clinical context (patient, encounter, ordering provider, order), and DICOM provides the imaging content. A FHIR ImagingStudy resource links to the DICOM study via the Study Instance UID. A viewer resolves the UID against a WADO-RS endpoint to retrieve and render the images.
This is not a migration path — FHIR is not replacing DICOM for imaging storage. They serve different purposes at different layers of the stack.
Comparison table
| Standard | Format | Transport | Primary Use Case | Governance | US Regulatory Status | FHIR Relationship |
|---|---|---|---|---|---|---|
| HL7 v2 | Pipe-delimited text | MLLP / TCP | Real-time clinical event messaging | HL7 International | HIPAA-referenced; widely mandated by EHR certifications | V2-to-FHIR mapping project; being replaced incrementally |
| CDA / C-CDA | XML | SOAP, IHE XDS, Direct | Clinical document exchange at transitions of care | HL7 International | ONC-mandated for transitions of care (Meaningful Use / USCDI) | C-CDA on FHIR IG; FHIR Composition is the successor |
| FHIR R4 | JSON (or XML) | HTTPS REST | APIs, patient access, modern integrations | HL7 International | ONC 21st Century Cures Act requires FHIR R4 patient access APIs | N/A — this is the reference standard |
| X12 | EDI fixed-format | SFTP, AS2, clearinghouse | Administrative: billing, eligibility, prior auth | ASC X12 | HIPAA mandates X12 for covered transactions | FHIR Claim / CoverageEligibility emerging; X12 still required |
| DICOM | Binary + metadata | DIMSE / DICOMweb (HTTPS) | Medical imaging storage and retrieval | NEMA | FDA-regulated for imaging devices | FHIR ImagingStudy is a pointer to DICOM content; coexistence model |
Decision guide by use case
| Use Case | Today’s Standard | Emerging Standard | Notes |
|---|---|---|---|
| Lab results from hospital to EHR | HL7 v2 ORU^R01 | FHIR Observation | v2 dominates in production; FHIR Observation increasingly used in new builds |
| Patient records on discharge | C-CDA CCD or Discharge Summary | FHIR DocumentReference / Composition | USCDI v1+ requires FHIR patient access; C-CDA still used for provider-to-provider |
| Insurance eligibility check | X12 270/271 | FHIR CoverageEligibilityRequest/Response | FHIR eligibility mandated by CMS for some payer APIs; X12 still required by HIPAA for EDI transactions |
| Claims submission | X12 837P/I | FHIR Claim | FHIR Claim not yet a HIPAA-mandated replacement; track Da Vinci PDEX Plan Net and Claims Data Exchange IGs |
| Imaging retrieval | DICOM C-MOVE / WADO-RS | DICOMweb WADO-RS (already RESTful) | Not a FHIR concern at the pixel level; FHIR ImagingStudy for clinical context only |
| Patient-facing app access | (not standardised before 2019) | FHIR R4 + SMART on FHIR | Required by 21st Century Cures Act; apps use SMART launch and FHIR APIs |
| Medication order to pharmacy | NCPDP SCRIPT (not covered above) | FHIR MedicationRequest | NCPDP SCRIPT is the e-prescribing standard; NewRx transactions; FHIR MedicationRequest emerging |
Migration paths
v2 to FHIR
The HL7 V2-to-FHIR Implementation Guide (published by HL7) provides segment-level mapping tables from common v2 message types to FHIR resources. For example, PID maps to Patient, OBX maps to Observation, DG1 maps to Condition.
The mapping is not mechanical — v2 fields carry combined data that FHIR splits across multiple elements, and many v2 fields have no FHIR equivalent and vice versa. Integration engines (Mirth Connect, Rhapsody, Iguana) implement these mappings in transformation scripts. The V2-to-FHIR IG gives you the reference; the implementation requires engineering.
C-CDA to FHIR
The C-CDA on FHIR Implementation Guide defines how C-CDA document sections map to FHIR resources. A CCD maps to a FHIR Bundle containing a Composition plus the referenced resources (Condition, MedicationRequest, AllergyIntolerance, etc.). ONC’s 2015 Edition Cures Update includes requirements for CDA-to-FHIR conversion.
The challenge is the same as with v2: inconsistent CDA implementations mean every conversion must handle vendor-specific variations.
X12 to FHIR
The transition from X12 to FHIR for administrative transactions is underway but incomplete. CMS has mandated FHIR APIs for prior authorisation (PAS) and for certain payer-to-payer exchange scenarios. Da Vinci project IGs cover the clinical use cases. For billing, the 837/835 remain required — FHIR Claim is not yet a HIPAA-mandated replacement.
Plan for coexistence: FHIR APIs for new digital channels, X12 EDI for existing payer connections. Budget for maintaining both until regulatory requirements catch up.
Where to go deeper
- Healthcare Interoperability: Landscape and Approach — the hub page for this topic cluster
- What Is FHIR — full FHIR reference
- Healthcare Data Semantics — SNOMED, LOINC, RxNorm, ICD-10, CPT, and mapping strategy
- Legacy-to-FHIR Mapping — mapping patterns and documentation expectations