ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

Acknowledgements — three stacked levels

Every EDI flow needs three distinct acknowledgements to be audit-closable: "I received the bytes", "the syntax is valid", "I took the content into account". Confusing them is the first cause of integration incidents.

Problem

When a sender wants to know where an EDIFACT ORDERS stands, the question is not one — it is three:

  1. Did the partner actually receive the bytes I sent?
  2. Is the message syntactically valid for its parser?
  3. Did its ERP accept the order, partially or in full?

Without an answer to each, you can neither close the send, nor trigger a sensible retry, nor alert the right business team. Yet in practice we too often see a single "ACK received" cell in the integration log — without saying which of the three.

Forces

  • Asymmetric latency. The three acknowledgements do not arrive together: transport comes back in seconds, functional in minutes, business in hours or days.
  • Legal liability. Non-repudiation of receipt (NRR) only covers the bytes received, not the business processing. Conflating them is expensive in dispute resolution.
  • Multiple standards. EDIFACT (CONTRL, APERAK), X12 (997, 999, 824), UBL and cXML each have their own ACK forms, and partner conventions further redefine error thresholds.
  • Cost of a missing ACK. If the partner doesn't ACK within N hours, do you retry, alert, or treat silence as success? None of the three answers is universal.

Solution: three stacked levels

The canonical pattern is to model each send with three independent state machines, transitioning on receipt of an ACK at the corresponding level:

  1. Level 1 — transport. Initial state SENT. Receives an MDN (AS2), Receipt (AS4), or EERP (OFTP2). Transitions to DELIVERED. If no ACK arrives within the partner SLA, transitions to TRANSPORT_FAILED.
  2. Level 2 — functional. State DELIVERED. Receives a CONTRL or a 997/999. Transitions to SYNTAX_OK or SYNTAX_KO. This is the ACK that validates the partner can read the message — not that it accepts it.
  3. Level 3 — business. State SYNTAX_OK. Receives an ORDRSP (EDIFACT), 855/860/865 (X12), a cXML ConfirmationRequest, or a UBL InvoiceResponse. Transitions to ACCEPTED, PARTIAL, or REJECTED.
plaintext acknowledgements.txt
Sender                                Receiver
──────                                ────────

[1] POST AS2 (signed ORDERS D.96A)       ───►
                          ◄─── [2] HTTP 200 + signed MDN (Received-content-MIC)

  (receiver parses EDIFACT)
                          ◄─── [3] CONTRL — syntactic acknowledgement
  (receiver integrates into ERP)
                          ◄─── [4] ORDRSP — functional reply
                                    (full / partial accept / reject)

  Legend:
  [1]  Send
  [2]  Transport ACK       — the bytes arrived
  [3]  Functional ACK      — the syntax is valid
  [4]  Business ACK        — the order is processed

EDIFACT — CONTRL and APERAK

In EDIFACT, level 2 (functional) is carried by the CONTRL message (UN/EDIFACT D.95B+). It contains a UCI segment with the original interchange reference, a UCM per covered message, and an action code: 4 accepted, 7 syntactic rejection, 8 partial rejection. Level 3 (business) can be carried by an APERAK on application error, or directly by the functional reply ORDRSP.

edifact contrl-d96a.edi
UNB+UNOC:3+RECEIVER:14+SENDER:14+260514:1545+CTRL900042'
UNH+CTRL1+CONTRL:2:2:UN'
UCI+CTRL000001+SENDER:14+RECEIVER:14+7'
UCM+1+ORDERS:D:96A:UN+7'
UNT+4+CTRL1'
UNZ+1+CTRL900042'

X12 — 997, 999, 824, 855

Level 2 in X12 has two flavours. The 997 (Functional Acknowledgment, 4010+) covers syntax at the functional group and transaction level. The 999 (Implementation Acknowledgment, 5010+) additionally checks conformance to the partner implementation guide (HIPAA explicitly mandates 999 since 2012). For business errors the 824 (Application Advice) serves as an X12 APERAK. Level 3 is typically the 855 (Purchase Order Acknowledgment).

plaintext 997-functional-ack.edi
ISA*00*          *00*          *ZZ*RECEIVER       *ZZ*SENDER         *260514*1545*U*00401*900000042*0*P*>~
GS*FA*RECEIVER*SENDER*20260514*1545*42*X*004010~
ST*997*0001~
AK1*PO*1000~
AK2*850*1001~
AK5*A~
AK9*A*1*1*1~
SE*6*0001~
GE*1*42~
IEA*1*900000042~

Reading the 997 above: AK1*PO*1000 identifies the original functional group (control number 1000), AK2*850*1001 targets the 850 transaction (control number 1001), AK5*A signals Accept, and AK9*A*1*1*1 summarises: 1 group received, 1 accepted, 1 transaction accepted.

Transport — MDN, Receipt, EERP

Level 1 depends on the protocol:

  • AS2 — signed MDN with Received-content-MIC (see the AS2 page). Synchronous or asynchronous per partner profile.
  • AS4 — SignalMessage carrying eb:Receipt and a NonRepudiationInformation block (see AS4).
  • OFTP2 — CMS-signed EERP, emitted after the application consumes the Virtual File (see OFTP2).
  • SFTP — no native ACK. A bilateral convention (.ok or .contrl trigger file) substitutes for a transport ACK.

Canonical sequence

Anti-patterns

  • "No ACK = success". A partner that doesn't send a 997 means tacit success? No. Absent an explicit contractual clause, missing ACK is failure.
  • Counting MDN as a business ACK. A signed MDN proves receipt of the bytes, not order acceptance. The legal NRR only covers the transport layer.
  • Silent CONTRL on success. Some historical EDIFACT implementations only send a CONTRL on error; silence is taken to mean success. Bad practice — require CONTRL action 4 (acknowledgement) even on success.
  • Retries triggered on missing level-1 ACK. If you retry on missing MDN you can send the same order twice — hence the need for idempotency.
  • Uniform alert thresholds. A 24h CONTRL timeout for every partner hides real incidents: a partner that historically returns CONTRL in 10 minutes and suddenly takes 12 hours is most likely broken, even within the generic SLA.
  • Idempotency — to avoid re-emitting the same order while waiting for an ACK.
  • Retry & backoff — the retransmission policy when an ACK is missing.
  • Exception flow — the escalation matrix when the business ACK is negative.

Sources

  • Hohpe G., Woolf B. — Enterprise Integration Patterns, Guaranteed Delivery and Return Address. enterpriseintegrationpatterns.com — Guaranteed Delivery
  • RFC 4130 §7.2 — MDN reliability, retries, sync vs async. rfc-editor.org/rfc/rfc4130
  • ASC X12 — 997 Functional Acknowledgment, technical report TR3 (version 004010). Public reading of AK1/AK2/AK5/AK9 codes.
  • UN/CEFACT — CONTRL D.95B+. Canonical definition of the EDIFACT acknowledgement message. service.unece.org/trade/untdid
  • Walmart Supplier CenterWalmart EDI Guidelines for the 997 + 855 convention mandated across the supplier base since 2002.