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.
Header
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 SG3RFF+DTMand SG4CTA+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+STS— stock 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
CPSwith SG16PAC+MEA+QTYand SG17PCI+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.DTMin 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.
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 twoQTY+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
INVor 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
LOCis 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+356orDTM+8indicating 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+5on top, never instead.
Related messages
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.
{
"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 }]
}
]
}
}