Correlation Identifier
When an MDN lands three hours after the order, how do you find the matching order? Every EDI reply explicitly carries the reference of the message it acknowledges — this is the pivot that closes the loop.
Problem
A requester emits several requests in parallel: 50 X12 850 orders in a single day. Replies arrive in arbitrary order, sometimes on another channel, sometimes hours later. How does the requester match each reply to its request? Without an explicit identifier, you have to join on timestamp, content, or guess — fragile and not scalable.
Forces
- Asynchronous by default. In EDI, nearly everything is async: the reply does not come back on the same connection as the request.
- Multiplexing. A single AS2 channel transports dozens of parallel transactions; the requester needs a unique id per correlation.
- Stability. The identifier must survive retransmissions, hub hops, format conversions.
- No semantic content required. The id need not carry business meaning — it is an opaque label.
Solution
EIP §163 (Hohpe & Woolf, 2003) prescribes: each reply carries a reference (the Correlation Identifier) to the unique id of the original request. The requester keeps a request id → context table; on reception it reads the identifier and restores its context (callback to invoke, transaction state to update, future to complete). The pattern is the dual of Return Address — one says where, the other says what.
X12 — AK1 / AK2 of the 997
The X12 997 functional acknowledgement is the canonical example. When the receiver acknowledges a PO functional group containing an 850, the 997 carries:
-
AK1referencing the group's identifier code (PO) and its Group Control Number (original GS06); -
AK2referencing each transaction set by its identifier (850) and its Transaction Set Control Number (original ST02); -
AK5andAK9carrying the overall decision.
ISA*00* *00* *ZZ*ACMEVENDOR *ZZ*ACMERETAIL *260514*1500*U*00401*000000456*0*P*>~
GS*FA*ACMEVENDOR*ACMERETAIL*20260514*1500*456*X*004010~
ST*997*0001~
AK1*PO*123~
AK2*850*0001~
AK5*A~
AK9*A*1*1*1~
SE*6*0001~
GE*1*456~
IEA*1*000000456~ Original message
─────────────────
ST 850, Control 0001 (ST02 = original)
GS, Control 123 (GS06 = original)
ISA, Control 000000123 (ISA13 = original)
Functional ACK 997
──────────────────
AK1 PO 123 ← references GS06 of the original group
AK2 850 0001 ← references ST02 of the original transaction
AK9 A 1 1 1 ← group-level decision
Reading: on reception of the 997, the requester reads
AK101 (PO) and AK102 (123) → it knows this
is the ACK of functional group 123 it sent this morning. Then
AK2 850 0001 → it pinpoints the exact transaction.
Without these references, automated reconciliation is impossible.
EDIFACT — UCI / UCM of CONTRL
The EDIFACT CONTRL message applies the same mechanic. UCI
(Interchange Response) references the Interchange Control
Reference of the original UNB; UCM (Message
Response) references the Reference Number of the original
UNH. The requester recovers its context exactly as in X12, reading
these two reference levels.
AS2 and AS4 — Original-Message-ID
AS2 (RFC 4130) embeds the pattern in the MIME header of the MDN: the
Original-Message-ID field of the MDN carries the
Message-ID value of the original message. The AS2
application receiving the MDN uses this field as the key to recover
the trace of its send.
AS4 (OASIS ebMS3) systematises this via the eb:Receipt
block: the eb:RefToMessageId element in the reply header
points at the MessageId of the original. This is the
instrument of the PEPPOL Receipt and of Non-Repudiation of Receipt
(NRR).
Anti-patterns
- Timestamp-based correlation. Assuming the closest reply in time matches the in-flight request breaks the moment there is parallelism, retransmission or clock skew between systems.
- Content-based correlation. Joining on the internal order number is misleading: two requests can share the same content without being the same transaction (retransmission, duplicate).
- Identifier minted on the receiver side. If the receiver assigns a fresh id in the reply without echoing the original id, the requester can no longer correlate. Always echo the original id.
- Too-short or non-unique id. A 4-digit counter rolls over in days on a high-volume channel — use a UUID or a 9-digit ISA13.
Related patterns
- Return Address — says where to send the reply; Correlation Identifier says what to put in it.
- Idempotency — the correlation id can double as an idempotency key on the receiver side.
- Acknowledgements — the mechanism that carries the Correlation Identifier.
- Process Manager — the orchestrator that consumes correlations to advance its state machine.
Sources
- Hohpe G., Woolf B. — Enterprise Integration Patterns, pattern Correlation Identifier (§163). enterpriseintegrationpatterns.com — Correlation Identifier
- X12 .004010 — AK1 / AK2 segments. Definition of the Group and Transaction Set Control Number references in the 997.
- ISO 9735 — CONTRL message. UCI / UCM segments, complete structure of the EDIFACT acknowledgement and correlation.
- RFC 4130 — AS2. Section on Original-Message-ID in the MDN. rfc-editor.org/rfc/rfc4130
- OASIS ebMS3 / AS4. The eb:RefToMessageId element of the Receipt and Error. docs.oasis-open.org/ebxml-msg