The blog  ·  2026-07-31

SAP still speaks IDoc, and IDoc is our home game

Written for ED-1 — the supply-chain ISV / traceability-vendor engineering org — the integration engineer who meets S/4HANA through a customer's system.

One thesis: S/4HANA's modern OData APIs and its decades-old IDoc traffic are two syntaxes for the same four documents, and because IDocs carry EDI semantics in SAP framing, the transaction layer treats them as a first-class dialect — compiled to the same CBV references as an 856 or a DESADV, not shoved through a second pipeline.

Two faces, one cycle

Every S/4HANA estate you will meet as an ISV engineer has both faces running at once. The catalog face is OData, and the operations that matter for the record have exact names:

  • API_PURCHASEORDER_2 — the purchase order, OData v4. (The v2 service, API_PURCHASEORDER_PROCESS_SRV, was deprecated in August 2024; new wiring targets the v4 API.)
  • API_INBOUND_DELIVERY_SRV_0002 — the inbound delivery: the supplier's despatch advice as SAP models it, and the object a goods receipt posts against.
  • API_SUPPLIERINVOICE_PROCESS_SRV — the supplier invoice.

The traffic face is IDoc, and it has not gone anywhere: ORDERS05 for purchase orders, DELVRY03 and DELVRY07 carrying DESADV despatch advices, INVOIC02 for invoices. These remain the workhorse message types moving between S/4HANA and its trading partners in 2026.

For a transaction layer this is not a complication, it is a homecoming. An IDoc is a segment-structured business document with a control record — the same anatomy as the X12 and EDIFACT dialects the parser already reads. The compile map is one table:

  • API_PURCHASEORDER_2 order / ORDERS05 → po
  • inbound delivery / DELVRY03/07 (DESADV) → desadv
  • goods receipt posted against the inbound delivery → recadv
  • supplier invoice / INVOIC02 → inv

Note what the middle two rows buy you: the inbound-delivery-plus-goods- receipt pair yields both desadv and recadv from one flow — the document that promised the shipment and the document that closed it, joined to the same delivery object, which is precisely the pairing the reconcile verdict consumes.

The proof artifact: one inbound delivery, compiled

A worked figure from the connector's committed output shape. An inbound delivery notification for one pallet of one lot-tracked material compiles to a receiving-side ObjectEvent skeleton carrying the two references and the party context:

{
  "type": "ObjectEvent",
  "action": "OBSERVE",
  "bizStep": "receiving",
  "disposition": "in_progress",
  "quantityList": [
    {
      "epcClass": "urn:epc:class:lgtin:4012345.011111.LOT2026A",
      "quantity": 48,
      "uom": "EA"
    }
  ],
  "bizTransactionList": [
    { "type": "desadv", "bizTransaction": "urn:epc:id:gdti:4012345.00001.0080012345" },
    { "type": "po", "bizTransaction": "urn:epc:id:gdti:4012345.00001.4500001234" }
  ],
  "sourceList": [
    { "type": "owning_party", "source": "urn:epc:id:pgln:4012345.00001" }
  ],
  "destinationList": [
    { "type": "owning_party", "destination": "urn:epc:id:pgln:0614141.00001" }
  ]
}

Every field there is core CBV machinery — bizTransactionList is a core field, not an extension — and the output validates against the pinned official EPCIS 2.0 JSON schema before it leaves the tool: superset where SAP's document carries more than the standard models, and conformant always, because the two claims only mean anything together.

Why the identifiers are the best in the matrix

The reason that figure can be GS1-real rather than SKU-approximate is an SAP fact worth stating precisely: the material master carries per-unit GTINsMARA-EAN11 for the base unit plus the MEAN table for additional GTINs per unit of measure — and the Business Partner model carries a GLN field with uniqueness enforcement. No other system in our verified connector matrix outside the standards rails ships both a validated GTIN home and an enforced GLN home. (The matrix's full census is the GTIN-gap post; SAP and Business Central are the two exceptions it names.)

So when the compile writes epcClass and pgln URIs above, it is reading identity the customer's own master data already governs — not inferring it from a free-text barcode column the way an ecommerce-sourced record must.

Access honesty: sandbox for shape, customer for reality

The gates, stated the way you will actually hit them. SAP's Business Accelerator Hub sandbox is genuinely public: a free SAP ID gets you an API key and live try-out calls against sandbox.api.sap.com, which is enough to verify shapes, field names, and the compile map before any commercial conversation exists. Production is another matter — a real S/4HANA system, communication arrangements configured by its administrators, and events arriving via Enterprise Event Enablement into Event Mesh (topics like sap.s4.beh.purchaseorder.released.v1). There is no self-serve door into a customer's ERP, and this page does not pretend otherwise: the SAP connector is activated through the customer's own platform team, who hold the keys and the change windows.

That is not a weakness of the connector; it is the shape of the segment. The estates running S/4HANA are exactly the counterparties whose IDoc traffic your smaller customers already receive — which means the dialect pays for itself even before any OData wiring happens, because DELVRY03 files arriving over the existing EDI plumbing compile on the same pipeline as everything else.

What lands where

The result of the compile is an event record that answers the questions the paperwork alone cannot: which lot crossed which dock under which PO, with the despatch advice and the receiving close on the same spine that epcis.dev captures and visibility.cloud answers from. The identifiers ride through because SAP already governs them; where a counterparty's data is weaker, the enrichment layer does the bridging.

If an SAP estate is in your integration path — yours or a customer's — tell us which one. The access flow asks which systems you run precisely so the SAP branch is wired in the order the answers demand.


894 words. The access flow is at /get-access/; the family's event door is epcis.dev.