HL7 v2 to FHIR terminology: OBX to Observation with LOINC and SNOMED
Map a de-identified ORU/OBX fragment onto Observation.code and value[x] using HL7 v2-to-FHIR 1.0.0. LOINC binds observations; SNOMED binds problems and allergies as the IG maps them. Local codes fail first, not PID.
Ala Ben Aicha

Direct answer
Map OBX to Observation using the v2-to-FHIR IG 1.0.0: OBX-3 becomes Observation.code, OBX-5 becomes value[x]. Bind LOINC on observations and SNOMED on problems and allergies. Local codes, not PID, are the usual failure.
Pin the published maps, then the bindings
Pin the published HL7 Version 2 to FHIR IG 1.0.0 (STU 1) (generated 7 October 2025, package hl7.fhir.uv.v2mappings#1.0.0 on FHIR R4). Prefer that package over the CI build. The hybrid engine pattern is the v2-to-FHIR migration playbook; the order/result choreography is the radiology and lab workflow. This page is the terminology contract inside that engine.
The segment map to pin is OBX → Observation. Problems and allergies are not OBX: the IG maps AL1 → AllergyIntolerance (AL1-3 → AllergyIntolerance.code) and DG1 → Condition (DG1-3 → Condition.code), also via EpisodeOfCare.diagnosis.
| v2 field | FHIR path | Binding / type map | Usual failure |
|---|---|---|---|
| OBX-3 Observation Identifier (CWE) | Observation.code |
LOINC http://loinc.org when CWE.3 is LN |
Local mnemonic (HGB^^^L) with no system |
| OBX-2 + OBX-5 | value[x] |
NM → valueQuantity; ST/FT/TX → valueString; CWE/CE/CNE/CF → valueCodeableConcept |
Value type and value[x] disagree |
| OBX-6 Units | valueQuantity unit/code |
UCUM when the sender actually sends it | Unit on the string, not on the Quantity |
| OBX-11 Result status | Observation.status |
Table 0085 → status (F → final) |
Treating C (corrected) as a new Observation |
| AL1-3 Allergen | AllergyIntolerance.code |
SNOMED CT when CWE.3 is SCT |
Free-text allergen with no code system |
| DG1-3 Diagnosis | Condition.code |
SNOMED CT (or the national diagnosis system the CWE names) as the IG maps CWE | Assuming every DG1 is a problem-list Condition without reading the message map |
LOINC and SNOMED are bindings. They are not a licence I sell, not a code-system I host, and not implied by a valid FHIR JSON document. The v2-to-FHIR IG maps CWE → CodeableConcept; it does not translate a local table into LOINC or SNOMED for you.
Primary sources: v2-to-FHIR 1.0.0, OBX → Observation ConceptMap, LOINC.
Identifier on the observation: OBX-3, not PID
PID still becomes Patient — that is the ADT article. Terminology failures show up when OBX-3 has no assigning coding system. A second Patient is the wrong fix.
De-identified ORU/OBX fragment (specification fixture, not a person):
MSH|^~\&|LIS|LAB-A|FHIR-BRIDGE|HOSP-A|20260919120000||ORU^R01^ORU_R01|MSG0007|P|2.5
PID|1||HOSP-MRN-0001^^^HOSP-A^MR||EXAMPLE^JANE^Q
OBR|1||FILL-2026-0042|58410-2^CBC panel - Blood by Automated count^LN
OBX|1|NM|718-7^Hemoglobin [Mass/volume] in Blood^LN||13.2|g/dL|12.0-16.0|N|||F
Projected Observation (truncated):
{
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "718-7",
"display": "Hemoglobin [Mass/volume] in Blood"
}
]
},
"valueQuantity": {
"value": 13.2,
"unit": "g/dL",
"system": "http://unitsofmeasure.org",
"code": "g/dL"
}
}
The local-code variant OBX|1|NM|HGB^Hemoglobin^^L||13.2|g/dL parses as v2 and as FHIR and still fails every semantic check that expects LOINC. That is the usual production defect — not a missing PID-3.
What to implement first
- Inventory OBX-3 coding systems on real de-identified messages (LN, SCT, local
L, empty). Count how many Observation.code values would have nosystem. - Pin
hl7.fhir.uv.v2mappings#1.0.0. Implement OBX → Observation including OBX-2 → value[x] branching; do not hard-codevalueQuantityfor every OBX. - Bind LOINC on lab/clinical observations and SNOMED CT on AL1/DG1 as the IG maps those segments. Keep national code systems as additional
codingentries; do not drop them. - Test corrections (
OBX-11 = C) and cancels, not only the happy-pathF. Report context still needs DiagnosticReport where the radiology/lab guide says so.
What this is not
This article is not a LOINC or SNOMED CT licence, not a UMLS subscription, not a patient-identity matcher, and not clinical advice. Mapping one OBX in a lab does not certify an interface. I do not sell terminology licences. PID mismatches belong on the ADT/MPI pages. Values above are fixtures, not a person.
Related reading
For engine work that preserves OBX-3 systems into Observation.code, use HL7 FHIR integration or start a project.