NEWFree ROI Calculators — quantify what prior auth and siloed data are costing your organization.Prior Auth ROI Siloed Data ROI
HL7 v2Code Table6 min read

HL7 Table HL70103: Processing ID

HL70103 is the small but consequential table that tells a receiver whether a message is real. It sits in MSH-11.1 Processing ID and answers a single binary-ish question: should the receiver write this to the production database, send it to a test sandbox, or treat it as a debugging artifact that should be logged but never persisted. Three codes — D, P, T — cover every v2 version from 2.1 through 2.8.1, unchanged across the entire history of the standard.

Purpose

HL70103 disambiguates traffic on shared interface infrastructure. In modern hospitals, the same MLLP listener often serves production, integration-test, and training environments behind a single endpoint, distinguished only by MSH-11. A receiver that respects HL70103 will route a T message to its training database, return an AA acknowledgment that does not trigger downstream production workflows, and never invoice a patient or order a medication based on a non-P message.

The field is one character in v2.5 and earlier (PT data type, processing ID only) and gains a second component in v2.6+ for the processing mode (archive, initial load, restore, current), but the first component — HL70103 — is the part this page covers.

Where it's used

  • MSH-11.1 Processing ID — the canonical home of HL70103, populated on every v2 message ever sent. The field is required (R) on every version of MSH.
  • BHS-11 / FHS-11 Batch and File Header processing IDs use the same code set when a batch envelopes multiple messages.

Code list

CodeDisplayComment/Description
DDebuggingMessage is for development or troubleshooting; receiver should log and discard, never persist to clinical or financial systems.
PProductionMessage reflects a real-world event; receiver should process normally and update its system of record.
TTrainingMessage belongs to a training environment; receiver should persist to training/sandbox data only, never to production.

Code system OID

  • OID: 2.16.840.1.113883.18.32
  • Canonical URI: http://terminology.hl7.org/CodeSystem/v2-0103

HL7-defined vs user-defined

HL70103 is HL7-defined and the code set is closed at three values. Sites occasionally invent local fourth values like S (Staging) or U (UAT), but these break conformance — every receiver is expected to interpret only D, P, T. Multi-environment routing is normally handled by separate MLLP endpoints or by MSH-3 / MSH-5 sending and receiving application identifiers, not by extending HL70103.

Version differences

  • v2.1 – v2.5 — Single-component PT data type carrying just the processing ID (D, P, T). No further structure.
  • v2.6+ — MSH-11 retains HL70103 as MSH-11.1 but gains an optional MSH-11.2 Processing Mode (HL70207) with values like A (Archive), R (Restore), I (Initial load), C (Current processing). HL70103 itself is unchanged.
  • v2.8 – v2.8.1 — Set stable; the three-code table has never been extended.

Common mistakes

  • Emitting P from a non-production system. A test harness or staging environment that accidentally sends P will cause the receiver to write real records — phantom admissions, ghost orders, fake encounters. This is one of the most common root causes of "test data appeared in production"; the fix is to hard-wire test environments to emit T or D at the engine level and refuse to allow operators to override it.
  • Sending T and then expecting prod-grade audit. Receivers under HIPAA and similar regimes treat T and D messages as out-of-scope for audit logging and chain-of-custody. If you need a fully audited training environment, you need a separate production-grade endpoint, not MSH-11 = T.
  • Using D for "production debug" mode. D means the message will not be persisted. Sites who flip MSH-11 to D to "get more logging" on production traffic end up with messages that downstream systems silently drop. Use a debug log channel, not MSH-11.
  • Leaving MSH-11 empty. MSH-11 is required on every version. An empty MSH-11 is a conformance error; receivers should reject the message with AE rather than guess.
  • Lowercase codes. p, t, d are not valid; HL70103 is case-sensitive uppercase.

Examples

A production ADT admission:

MSH|^~&|EPIC|MGH|RHIO|STATE|20260625120000||ADT^A01^ADT_A01|MSG00001|P|2.5
PID|1||10456^^^MRN^MR||DOE^JANE^A||19850412|F

The same message from a training environment — note T in MSH-11:

MSH|^~&|EPIC-TRAIN|MGH|RHIO-TRAIN|STATE|20260625120000||ADT^A01^ADT_A01|MSG99001|T|2.5
PID|1||TRAIN001^^^MRN^MR||TESTPATIENT^TRAINING||19850412|F

A debug message during interface development — D tells the receiver not to persist:

MSH|^~&|DEV|MGH|TEST|MGH|20260625120000||ADT^A01^ADT_A01|MSG_DEBUG_001|D|2.5
PID|1||DEBUG1^^^MRN^MR||DEBUG^PATIENT||19850412|F

A v2.6+ message using both MSH-11 components — P processing ID, A archive mode:

MSH|^~&|EPIC|MGH|ARCH|MGH|20260625120000||ADT^A01^ADT_A01|MSG_ARCH_001|P^A|2.6
PID|1||10456^^^MRN^MR||DOE^JANE||19850412|F

FHIR projection of P as a Meta.tag on a transported resource:

{
  "resourceType": "Patient",
  "id": "10456",
  "meta": {
    "tag": [{
      "system": "http://terminology.hl7.org/CodeSystem/v2-0103",
      "code": "P",
      "display": "Production"
    }]
  }
}

FHIR mapping

FHIR does not publish a ValueSet for HL70103 because the processing mode is metadata about the message envelope, not the resource. The v2-to-FHIR IG suggests one of two patterns:

  1. Bundle-level tag — apply a Bundle.meta.tag to the entire converted Bundle with system = http://terminology.hl7.org/CodeSystem/v2-0103 and code = P|T|D. This preserves the original v2 semantics at the envelope level.
  2. Resource-level tag — apply the same tag to each resource inside the Bundle so a non-production resource can be filtered out by every downstream consumer, not just the one that opens the Bundle.

Vorro emits both, since downstream FHIR consumers vary in how strictly they unwrap Bundles.

Engine considerations

  • Default behavior on missing MSH-11. Engines should treat missing MSH-11 as a conformance error and reject with AE rather than default to P — defaulting to production is the worst possible failure mode.
  • Environment-locked emission. Test environments should be configured at the engine level to emit T (or D) and to refuse to forward any outbound message with MSH-11 = P. This is a one-line config that has prevented countless "test data appeared in prod" incidents.
  • Routing on MSH-11. Some sites use a single MLLP port for production and test, dispatching internally on MSH-11. This works, but the recommended pattern is separate ports / separate endpoints — fewer ways to misroute.
  • Case sensitivity. Codes are case-sensitive uppercase. Normalize on ingest if upstream senders are sloppy, and log every normalization so a sender emitting p instead of P is identified and corrected.

How Vorro handles HL70103

Vorro validates MSH-11.1 against the three published HL70103 codes on every inbound message. Messages with an empty MSH-11 or an unknown code are rejected at the port boundary with AE rather than passed to downstream handlers, because the cost of guessing wrong (production data corruption, missed training-data quarantine) is asymmetrically high.

Vorro's outbound channels are environment-locked: a non-production deployment will refuse to emit P even if the upstream sender supplied it, and will rewrite MSH-11 to T with an audit log entry. This prevents the most common cross-environment leak.

Sources

← Back to HL7 v2 Guide

Ready to Integrate This Into Your Workflow?

Talk to a Vorro expert about implementing HL7 v2 in your specific environment.

Browse HL7 v2 Guides
HL7 Table HL70103: Processing ID | Vorro Academy | Vorro