The SI (Sequence ID) data type has existed since HL7 v2.1 and is the v2 standard's purpose-built integer for ordering repeating segments inside a message. Its job is small and singular: number each occurrence of a segment, starting at 1, so receivers can correlate, deduplicate, and re-order. SI is the underlying type for the Set ID fields you will see in nearly every interface: PID-1, NK1-1, PV1-1, OBX-1, AL1-1, OBR-1, and DG1-1.
Purpose
When a message contains multiple instances of the same segment — three diagnoses, five observation lines, two next-of-kin records — receivers need a stable way to refer to each occurrence. SI provides that handle. It is not an identifier of the underlying clinical fact (that is what fields like DG1-3 or OBX-3 carry); it is purely a positional label scoped to the current message. Two messages may both contain an OBX|1 and they refer to different observations.
Format and constraints
SI is a primitive with no components or sub-components.
- Domain: non-negative integers in decimal notation. Conventional usage starts at 1 and increments by 1 within a message.
- No leading zeros, no sign character, no decimal point, no thousands separator.
- Whitespace is not permitted inside the value.
- The standard allows
0in principle but in practice every segment that defines a Set ID requires it to start at 1; senders should never emit0. - Length: historically 1..4. v2.7 deprecated the fixed maximum in favour of conformance-profile constraints; HAPI v2.8.1 imposes no length cap at the type level.
- Scope: an SI is meaningful only within the current message. It is not a global identifier and must not be persisted as one.
- The HL7 "delete" sentinel (
"") is legal but meaningless for SI — implementations either reject it or treat it as absent.
Where it's used
- PID-1 Set ID — PID (one PID per patient repeat in a batch message).
- NK1-1 Set ID — NK1 (numbers the next-of-kin records).
- PV1-1 Set ID — PV1 (rare; most messages have a single PV1).
- OBX-1 Set ID — OBX (numbers observation lines within an order).
- AL1-1 Set ID — AL1 (numbers the patient's allergies).
- OBR-1 Set ID — OBR (numbers orders within a message).
- DG1-1 Set ID — DG1 (numbers diagnoses on a financial or clinical message).
- BUI-1 Set ID — BUI (numbers blood-unit segments within a transfusion message).
The IAR segment, by contrast, has no Set ID — its position within its surrounding group establishes order.
Version differences
- v2.1 through v2.6: SI defined with a recommended 1..4 length and a 1-based, increment-by-1 convention.
- v2.7: fixed maximum length deprecated in favour of conformance-profile constraints; convention unchanged.
- v2.7.1, v2.8, v2.8.1, v2.8.2: no changes to the type.
The semantics of SI — non-negative integer, message-scoped positional label — have been stable across every published v2 revision.
Common mistakes
- Skipping numbers — sending
OBX|1,OBX|3,OBX|4without anOBX|2. Most engines flag a conformance violation; some silently re-number, which destroys cross-message correlation. - Restarting numbering inside a group when the standard requires continuity (or vice versa). The cardinality rule lives in the message structure, not in SI itself.
- Treating SI as a stable identifier across messages — a follow-up corrected result with
OBX|1does not necessarily refer to the originalOBX|1from a prior message. - Sending
0instead of starting at1. The standard tolerates it but every consuming segment definition starts the sequence at 1. - Emitting
1.0or01— SI is a pure integer; leading zeros and trailing.0are conformance violations.
Examples
Minimal:
1
In context — a sequence of OBX lines within a single ORU result:
OBX|1|NM|GLU^Glucose^L||92|mg/dL|70-110|N|||F
OBX|2|NM|BUN^BUN^L||14|mg/dL|7-25|N|||F
OBX|3|NM|CREAT^Creatinine^L||1.0|mg/dL|0.6-1.3|N|||F
In context — multiple diagnoses on an ADT:
DG1|1|I10|E11.9^Type 2 diabetes mellitus without complications^I10||20260620|F
DG1|2|I10|I10^Essential hypertension^I10||20260620|F
In context — two next-of-kin entries:
NK1|1|Smith^Jane^A|SPO^Spouse^HL70063|123 Main St^^Cincinnati^OH^45202|^PRN^PH^^^513^5550101
NK1|2|Smith^John^M|CHD^Child^HL70063|123 Main St^^Cincinnati^OH^45202|^PRN^PH^^^513^5550102
Common pitfall:
WRONG: OBX|1|NM|GLU|...
OBX|3|NM|BUN|...
Skipping SI=2 confuses correlation; many engines reject the message.
RIGHT: OBX|1|NM|GLU|...
OBX|2|NM|BUN|...
FHIR mapping
SI has no dedicated v2-to-FHIR ConceptMap because it carries no clinical meaning on its own. When it appears as part of a mapping, it is rendered as a FHIR positiveInt:
- In bundle-style mappings, the SI value often becomes the
entryordering or an extension on the target resource. - For diagnoses and allergies, SI typically maps to a custom ordinal extension on
ConditionorAllergyIntolerancerather than to a first-class FHIR element. - For OBX, SI is generally not preserved in FHIR at all —
Observation.idserves the cross-resource correlation role.
Engine considerations
- Validate monotonic, gap-free numbering per segment-type-per-group at the boundary. Silent renumbering hides upstream bugs.
- Never reuse an SI across messages as an identifier. If you need persistent identity, attach a UUID at the engine boundary and carry it in a separate field.
- Store SI as an integer in your internal model, not as a string. Round-trips through string types introduce
1.0/01corruption opportunities. - When merging two messages (e.g. resequencing a result with corrections), recompute SI for the merged output rather than carrying source numbers forward.
- HAPI v2.8.1 represents SI as a Java
Integer-backed primitive; null or empty values surface asnull, not0. - Some EHRs require SI starting at 1 even when a profile would technically allow 0; default to 1 for maximum interop.
How Vorro parses and produces SI
Vorro parses SI directly into an Option<u32> in its canonical model — strict non-negative integer parsing, no decimal tolerance, no string fallback. Values outside the 1..u32::MAX range are rejected at ingress with a typed conformance error rather than silently coerced.
On outbound, Vorro renumbers SI fields from 1 within each segment group as a final pass before serialization. This guarantees gap-free numbering even when intermediate transforms have dropped or re-ordered segments, and it eliminates a whole class of "why is my receiver complaining about OBX|3 with no OBX|2" bugs from downstream interfaces.
