The SPS (Specimen Source) data type is a seven-component composite that packs everything a v2.3-era lab needed to describe a specimen into a single OBR-15 field: what the specimen is, what additives were added, how it was collected, where on the body it came from, how the body site is qualified, how the collection method is qualified, and what role the specimen plays (patient, control, calibrator, etc.). It was introduced in HL7 v2.3, used heavily through v2.4, and then formally deprecated in v2.5 in favor of a dedicated SPM segment that gives specimens their own first-class structure. Despite the deprecation, SPS still flows through enormous volumes of legacy lab traffic, and any integration touching pre-v2.5 lab systems must parse it correctly.
The name SPS is reused in HL7: there is also an SPS user-defined code table for stock-status. This page covers the data type, not the code table — hence the slug sps-datatype.
Purpose
SPS solves the problem that OBR needed to carry rich specimen context but predated the SPM segment. Stuffing the context into one composite kept OBR's field count manageable while letting senders describe a specimen completely enough that the receiving LIS could route, route, and resulting workflows could make sense of it. The composite mixes coded values (CWE for source, additives, body site, modifiers, role) with one free-text component (collection method), reflecting the reality that collection methods were rarely codified in the 1990s.
After v2.5 introduced the SPM segment, SPS became redundant: SPM expresses every SPS component as its own field, plus collection date/time, container, handling, and risk. New profiles use SPM; existing interfaces often continue to populate OBR-15 SPS for compatibility.
Component reference
Source: Caristix HL7 v2.8.1 definition — SPS. SPS has 7 components separated by ^.
| Seq | Name | Data Type | Length | Req | Description |
|---|---|---|---|---|---|
| SPS.1 | Specimen Source Name or Code | cwe | — | O | The specimen itself (whole blood, serum, urine, CSF, biopsy tissue, etc.). Drawn from HL70070. |
| SPS.2 | Additives | cwe | — | O | Additives present in the collection container — EDTA, heparin, citrate. Drawn from HL70371. |
| SPS.3 | Specimen Collection Method | tx | — | O | Free-text description of how the specimen was collected (e.g. "clean catch midstream", "venipuncture left antecubital"). |
| SPS.4 | Body Site | cwe | — | O | Anatomical site of collection. Drawn from HL70163. |
| SPS.5 | Site Modifier | cwe | — | O | Qualifier on the body site — left, right, upper, lower (HL70495). |
| SPS.6 | Collection Method Modifier Code | cwe | — | O | Qualifier on the collection method (e.g. "with tourniquet", "fasting"). |
| SPS.7 | Specimen Role | cwe | — | O | Role of the specimen — Patient (P), Control (Q), Calibrator (C), Pool (G). Drawn from HL70369. |
The mix of CWE and TX matters: SPS.3 alone is uncoded free text. Engines extracting structured data from SPS.3 typically need pattern matching or a downstream NLP pass.
Most-used components
- SPS.1 Specimen Source Name or Code — the only component populated in many legacy messages.
BLD,SER,UR(urine),CSFare common HL70070 codes. - SPS.2 Additives — critical for chemistry: EDTA vs heparin vs serum-separator can change the assay validity.
- SPS.4 Body Site — anatomical context for biopsy, wound, and culture specimens.
- SPS.7 Specimen Role — distinguishes patient specimens from QC controls in the same OBR. Defaults to Patient when absent.
Where it's used
SPS is concentrated in lab traffic, primarily in OBR-15:
- OBR-15 Specimen Source (v2.3 / v2.4) — the dominant use; replaced by SPM-4 / SPM-6 / SPM-8 in v2.5+.
- Some Z-segments in pathology and microbiology profiles that pre-date SPM.
- Custom blood-bank profiles that retained SPS for unit-source descriptions.
It is not used in newer profiles built against v2.5+. If you control both endpoints and the target is v2.5+, prefer SPM.
Version differences
- v2.3 — SPS introduced with the seven components seen today.
- v2.4 — Component constraints clarified; SPS.4 / SPS.5 codification refined against HL70163 and HL70495.
- v2.5 — SPS formally deprecated in favor of the SPM segment. OBR-15 remains backward-compatible.
- v2.6 / v2.7 / v2.7.1 — Component data types upgraded from CE to CWE as the broader v2 migration to CWE proceeded.
- v2.8 / v2.8.1 / v2.8.2 — Structurally stable per HAPI v2.8.1 javadocs: 7 components, CWE / CWE / TX / CWE / CWE / CWE / CWE.
Common mistakes
- Treating SPS as a single coded value. Engines that read only SPS.1 lose additive, site, and role context.
- Putting coded site information in SPS.3 (the free-text collection method) instead of SPS.4. The data is then unsearchable without NLP.
- Sending a deprecated specimen code in SPS.1 with no coding system (CWE.3 empty inside SPS.1). The receiver cannot disambiguate a local code from an HL70070 code.
- Populating OBR-15 SPS and an SPM segment in the same OBR with conflicting values. v2.5+ profiles should send one or the other; when both are present, SPM wins per most engine policies.
- Omitting SPS.7 Specimen Role on QC traffic. Without it, controls and calibrators are indistinguishable from patient specimens and pollute analytics.
Examples
Minimal — whole blood only:
BLD^Blood^HL70070
Common — whole blood with EDTA additive:
BLD^Blood^HL70070^EDTA^EDTA^HL70371
Body-site-qualified — venous blood, left antecubital, patient role:
BLD^Blood^HL70070^^^Venipuncture^LARM^Left arm^HL70163^^^^^P^Patient^HL70369
Fully populated example from the working set — whole blood with EDTA, free-text collection method, body site, role:
BLD^Blood^HL70070^EDTA^^^^^Whole blood^^^P^Patient^HL70369
In context — OBR-15 inside a lab order, expressing a CSF specimen collected via lumbar puncture for cell count:
OBR|1|ORD-001|LAB-001|CBC^Complete Blood Count^L|||20260610080000|||||||CSF^Cerebrospinal fluid^HL70070^^^Lumbar puncture L3-L4^LSPINE^Lumbar spine^HL70163^^^^^P^Patient^HL70369
Common pitfall — coded site information dropped into SPS.3 (free text) instead of SPS.4:
BLD^Blood^HL70070^^^Left antecubital fossa, venipuncture^^^
The site information is now invisible to any downstream code that consumes SPS.4 / SPS.5.
FHIR mapping
The HL7 v2-to-FHIR Implementation Guide publishes ConceptMap-datatype-sps-source-to-specimen, mapping SPS into a FHIR Specimen resource. The mapping covers the structured components; the free-text SPS.3 lands on a method note.
| HL7 v2 | FHIR target |
|---|---|
| SPS.1 Specimen Source Name or Code | Specimen.type (CodeableConcept) |
| SPS.2 Additives | Specimen.collection.additive (Reference or CodeableConcept) |
| SPS.3 Specimen Collection Method | Specimen.collection.method.text (free-text fallback) |
| SPS.4 Body Site | Specimen.collection.bodySite (CodeableConcept) |
| SPS.5 Site Modifier | extension on Specimen.collection.bodySite or merged into the CodeableConcept |
| SPS.6 Collection Method Modifier Code | Specimen.collection.method (joined with SPS.3 when present) |
| SPS.7 Specimen Role | Specimen.extension[specimenRole] (no first-class FHIR slot prior to R5) |
The mapping is lossy in one direction: a FHIR Specimen with a coded collection.method may not round-trip back into SPS.3 without dropping the code. When the downstream system is v2.5+, prefer mapping into SPM instead, which has typed slots for every SPS component.
Engine considerations
- Deprecation handling. Engines bridging v2.3 / v2.4 senders to v2.5+ receivers should up-convert OBR-15 SPS into SPM at the boundary, not pass SPS through. Keep an internal canonical specimen model and emit the format the receiver expects.
- Coding system consistency. SPS.1 / SPS.2 / SPS.4 each carry their own coding system inside the embedded CWE; engines must not assume HL70070 just because the field is "specimen source."
- Specimen role defaults. When SPS.7 is empty, default to
PPatient — but record that the default was applied. Treating an empty role as "unknown" leads to lost QC tracking. - Free-text extraction. SPS.3 frequently contains structured-looking text (
"L arm, venipuncture, 21g"); resist parsing it with regex in the engine. Route it to a downstream NLP pipeline or to a human curator if structure is needed. - HAPI typing.
ca.uhn.hl7v2.model.v281.datatype.SPSexposes typed accessors for all seven components, each returning the correct CWE / TX class. The v2.3 SPS class has the same shape but its CWE components are CE — calling code that compiles against v2.8.1 cannot read v2.3 OBR-15 without a version switch.
How Vorro parses and produces SPS
Vorro keeps an internal canonical specimen model that holds every SPS component plus SPM's additional fields. On inbound:
- OBR-15 SPS is parsed component-by-component; each CWE sub-composite flows through the same normalization as a standalone CWE, including vocabulary lookup against HL70070, HL70371, HL70163, HL70495, and HL70369.
- SPS.3 is preserved verbatim as a method-text field; we do not attempt to structure it.
- When both SPS (OBR-15) and SPM are present, SPM wins for canonical storage and SPS is retained as a fallback in the audit log.
- An empty SPS.7 is normalized to
P^Patient^HL70369with a normalization flag, never silently inferred.
On outbound, Vorro emits OBR-15 SPS when the destination profile declares v2.3 / v2.4 or when the receiver explicitly requests it; otherwise we emit an SPM segment. We never emit both with conflicting values.
Related pages
- CWE data type — Coded With Exceptions
- Varies data type — Variant field resolved at parse time
- VH data type — Visiting Hours
