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.

INVRPT — Inventory Report Message (D.96A)

The INVRPT message reports inventory status between trading partners in either direction: stock on hand, in transit, reserved, broken down by location and SKU.

Purpose

Per the official UN/CEFACT definition, INVRPT is "a message specifying information relating to held inventories. The Inventory report message is intended to be used in either direction between trading partners."

The standard adds that the information exchanged relates to inventories of raw materials, manufactured articles or other stockable items. The most common use case is VMI (Vendor Managed Inventory): the buyer or consignee sends a daily INVRPT to the supplier, who decides replenishment and issues a self-prompted ORDERS D.96A. INVRPT also supports financial valuation (prices) for statutory declarations, audits, or price-protection claims.

Segment structure

INVRPT D.96A has two named sections: a Header (groups SG1 to SG5) and a Detail (groups SG6 to SG17 — packing sequences and inventory lines). There is no formal Summary section: UNT comes directly after the last item loop.

Mandatory header segments: UNH M , BGM M , and DTM M .

Then the groups:

  • SG1 RFF+DTM — references (RFF+CT blanket contract, RFF+ON order).
  • SG2 NAD+LOC — parties (buyer, supplier, storage location) with SG3 RFF+DTM and SG4 CTA+COM.
  • SG5 CUX+DTM — currency (useful for financial valuation).

Detail (stock positions)

The Detail section opens with group SG6 CPS (Consignment Packing Sequence, up to 9,999 occurrences). CPS lets you identify the packaging context but is not mandatory in practice when inventory doesn't depend on packing.

The sub-group SG7 PAC+PCI describes the package and its identification, nesting SG8 QTY+GIN+DTM — Quantity + Goods Identity Number (SSCC) + Date.

The business core is the SG9 loop (up to 9,999 occurrences) built around: LIN M , PIA C , IMD C , MEA C , ALI C , LOC C , and DTM C .

Under each LIN nest the groups:

  • SG10 RFF+DTM — line references.
  • SG11 QTY+INV+GIN+LOC+DTM+STSstock position, the central loop (up to 9,999 occurrences). This is where the quantity (QTY) sits, qualified by INV , the GIN (lot/serial number), the LOC (sub-location), the observation date, and the STS (status).
  • SG12 NAD+LOC — party associated with the position (carrier, depositary).
  • SG13 PRI+CUX+DTM — unit price for valuation.
  • SG14 RFF+DTM — additional references.
  • SG15 CPS with SG16 PAC+MEA+QTY and SG17 PCI+RFF+DTM+GIN — line-internal packing sequences.

The QTY segment is qualified by a code (element 6063) that changes everything: 145 stock available, 59 in transit, 9 delivered quantity, 17 quantity on hand, 21 ordered quantity, 192 free goods, etc. Picking the right qualifier is the single most important decision in an INVRPT.

Trailer

INVRPT has no formal Summary section: no UNS, no CNT. After the last SG9 loop comes directly UNT M .

Mandatory / conditional

Four structural items are strictly mandatory in every D.96A INVRPT:

  • UNH — opens the message.
  • BGM — gives the function (33 = Inventory enquiry response / 31 = Inventory enquiry) and the number.
  • DTM in the header — at least one date (DTM+137 issue, DTM+356 snapshot date).
  • UNT — closes the message.

On the business side you also need: NAD+SU and NAD+BY (parties), at least one LIN in SG9, and at least one QTY in SG11 per line — otherwise the report is empty. For any serious VMI you also need a LOC per line (storage site) and a DTM for the snapshot, to pin the stock photo to a specific moment.

Real-world example

An inventory snapshot sent by a consignee to a supplier in a VMI setup: two SKUs, same site, reported with their stock-available and in-transit levels.

edifact invrpt-d96a-example.edi
UNB+UNOC:3+5410000000456:14+5410000000123:14+260513:0700+CTRL000050'
UNH+1+INVRPT:D:96A:UN:EAN008'
BGM+33+INVRPT-2026-05-13+9'
DTM+137:20260513:102'
DTM+356:20260513:102'
RFF+CT:CONTRACT-2026-VMI-08'
NAD+SU+5410000000456::9'
NAD+BY+5410000000123::9'
LIN+1++3520000001234:EN'
LOC+18+WH-PARIS-NORD'
QTY+145:1240'
INV++1::145'
QTY+59:200'
INV++1::59'
DTM+8:202605130600:203'
LIN+2++3520000005678:EN'
LOC+18+WH-PARIS-NORD'
QTY+145:850'
INV++1::145'
DTM+8:202605130600:203'
UNT+19+1'
UNZ+1+CTRL000050'
  • BGM+33+INVRPT-2026-05-13+9 — type 33 (Inventory report), number INVRPT-2026-05-13, status 9 (Original).
  • DTM+137 — issue date. DTM+356 — inventory date (snapshot business date).
  • RFF+CT — tie-in to the VMI contract CONTRACT-2026-VMI-08.
  • NAD+SU / NAD+BY — Supplier and Buyer.
  • First line (GTIN 3520000001234): LOC+18+WH-PARIS-NORD (warehouse), then two QTY+INV — 1,240 available (qualifier 145) and 200 in transit (qualifier 59).
  • Second line: 850 units available.
  • DTM+8 — exact snapshot timestamp (qualifier 203).
  • UNT+19+1 — 19 segments, reference "1" matching UNH.

Common errors

  • QTY without inventory qualifier — a QTY without its INV or an ambiguous QTY[0] qualifier (e.g. forgetting code 145) makes the inventory unusable. The supplier can't tell whether the quantity is available, reserved, in transit, or expired.
  • Missing LOC — an INVRPT without LOC is interpreted as "all sites combined", which kills any per-warehouse replenishment logic in multi-site setups. At least one LOC+18 (warehouse) or LOC+11 (place of delivery) per line in practice.
  • Missing snapshot DTM — without DTM+356 or DTM+8 indicating the photo's date/time, the inventory has no temporal anchor. Critical for cover calculations (stock / consumption / horizon).
  • No UNS — INVRPT has no UNS. Don't insert one out of habit from ORDERS/INVOIC.
  • Wrong BGM function code — 33 (Original Inventory Report) for daily VMI, vs 4 (Change) for ad-hoc adjustments. Always sending "33 Original" on a delta prevents the supplier from computing inbound/outbound flows correctly.
  • GTIN ↔ internal SKU confusion — the LIN must carry the GTIN (qualifier EN). If inventory is also tracked by a supplier-internal SKU, use PIA+5 on top, never instead.

INVRPT sits inside a replenishment loop:

  • ORDERS D.96A — the replenishment order issued by the supplier or the buyer in response to the snapshot.
  • DESADV D.96A — the matching despatch advice.
  • RECADV D.96A — the receipt advice that will update the inventory.
  • DELFOR D.96A — the delivery schedule built from inventory projections.
  • PRICAT D.96A — the price catalogue, for financial valuation of stock.
  • CONTRL D.96A — the automatic syntactic acknowledgment.

JSON equivalent

JSON projection matching the example above. The mapping is not normative — it's an ediverse convention to ease integration in TypeScript / Python environments.

json invrpt-d96a-equivalent.json
{
  "interchange": {
    "controlRef": "CTRL000050",
    "from": { "id": "5410000000456", "qualifier": "14" },
    "to": { "id": "5410000000123", "qualifier": "14" },
    "datetime": "2026-05-13T07:00:00Z",
    "syntax": { "id": "UNOC", "version": "3" }
  },
  "message": {
    "ref": "1",
    "type": "INVRPT",
    "version": { "syntax": "D", "release": "96A", "agency": "UN", "association": "EAN008" }
  },
  "inventoryReport": {
    "number": "INVRPT-2026-05-13",
    "function": "33",
    "status": "9",
    "issueDate": "2026-05-13",
    "snapshotDate": "2026-05-13",
    "contract": "CONTRACT-2026-VMI-08",
    "parties": {
      "supplier": { "gln": "5410000000456" },
      "buyer": { "gln": "5410000000123" }
    },
    "lines": [
      {
        "ref": 1,
        "gtin": "3520000001234",
        "location": "WH-PARIS-NORD",
        "snapshotAt": "2026-05-13T06:00:00Z",
        "positions": [
          { "qualifier": 145, "label": "stock available", "value": 1240 },
          { "qualifier": 59, "label": "in transit", "value": 200 }
        ]
      },
      {
        "ref": 2,
        "gtin": "3520000005678",
        "location": "WH-PARIS-NORD",
        "snapshotAt": "2026-05-13T06:00:00Z",
        "positions": [{ "qualifier": 145, "label": "stock available", "value": 850 }]
      }
    ]
  }
}