UCUM in Observation.valueQuantity: The Strict Version

Editorial illustration in zellij-islamic-geometric style depicting a zellij Observation.valueQuantity strict shape with system, code, unit, and referenceRange constraints

Observation.valueQuantity is where most clinical measurements land, and it is where UCUM adherence matters most. The FHIR base spec binds Quantity.code to UCUM with an extensible strength on the base Observation. Profiles usually tighten that to required. Getting the strict form right is what turns Observation from "here is a number and a label" into a machine-readable, comparable measurement. The site's Clinical UCUM unit converter handles the conversions when you need them. For the wider FHIR framing, more healthcare interoperability content has more.

The Strict Quantity Shape

`` { "value": 5.4, "system": "http://unitsofmeasure.org", "code": "mmol/L", "unit": "mmol/L" } ``

Four fields. All four matter.

  • value — the numeric magnitude
  • system — must be http://unitsofmeasure.org for UCUM
  • code — a valid UCUM expression
  • unit — human-readable display; may differ from code

Common Non-Strict Shapes

  • Missing system — the code is unclaimed
  • Missing code — receivers cannot dispatch
  • system set to your organization's URL — private unit, not interoperable
  • Free-text code — not a UCUM expression

Each of these is technically valid FHIR but not strict enough for cross-system comparability. Profile validators reject them; the base validator warns.

For the canonical set of codes to use, canonical UCUM units the FHIR spec assumes you'll use is the entry.

The unit Field Is For Humans

unit is display text. It does not have to match code character-by-character. mL in code can be mL in unit or milliliter in unit — both are acceptable.

The receiver dispatches on code. Do not build machine logic on unit.

Reference Range Follows The Same Rule

Observation.referenceRange.low.system should be http://unitsofmeasure.org. The reference range's unit should match the value's unit — cross-unit ranges are confusing and error-prone.

If you store both original and canonical (per the storage discussion), pick one for the reference range and stick with it per Observation.

The Value-Absent Case

Not every Observation carries a numeric value. Coded results, categorical results, and non-quantitative observations use valueCodeableConcept, valueString, or valueInteger. For those cases, use the correct value shape rather than shoehorning into valueQuantity with a fake unit.

For the arbitrary-unit case, handling arbitrary units like 'per shift' that UCUM doesn't cover is the entry.

Component Observations Follow The Same Contract

Observation.component[].valueQuantity uses the same shape. Blood pressure with systolic and diastolic components each has its own valueQuantity in mm[Hg]. Panel results have per-component quantities each with their own UCUM code.

Consumers walk the component array and dispatch per unit. The FHIR strict form makes that straightforward.

What A Validator Enforces

A base-spec validator warns on non-UCUM systems. A profile validator with a required binding rejects them. For clinical decision support, treat non-UCUM values as invalid input — do not silently fall through.

The Extension For Alternative Representation

If you need to carry both the source unit and the canonical unit on one Quantity, use extensions. That is FHIR-native. For the storage side, storing quantities: original unit, canonical unit, or both is the entry.

The Short Version

Strict Quantity has value + system + code + unit. UCUM for code. Human text for unit. Reference range follows the same rule. Non-quantitative observations use the right non-Quantity shape. Enforce at ingestion, do not silently accept ambiguous units.

Zellij-geometric diagram of a strict Observation.valueQuantity payload with system, code, unit fields highlighted next to reference-range constraints, in tessellated tiles with indigo and violet accents on ivory

Sources

Aaliyah Jenkins

Interoperability specialist in Indianapolis. Covers MLLP, HL7v2 transport, and the parts of healthcare integration that haven't changed in 20 years.