DEV Community

challan116-ux
challan116-ux

Posted on

The EDI 850, Decoded: What a Purchase Order Actually Looks Like on the Wire

I'm Chris, founder of SignalEDI. Most of my days are spent staring at X12 documents, so let me do something I wish someone had done for me years ago: decode a real purchase order, segment by segment, with no hand-waving.

Below is a (sanitized) EDI 850 — the X12 purchase order — between a buyer and a widget manufacturer. Tilde ~ separates segments, asterisk * separates elements. If you squint, it's just a very flattened JSON file.

ISA*00*          *00*          *ZZ*RECEIVERID      *ZZ*SENDERID        *260929*1200*^*00501*000000001*0*P*>~
GS*PO*SENDERID*RECEIVERID*20260929*1200*1*X*005010~
ST*850*0001~
BEG*00*SA*PO-12345**20260929~
REF*DP*DEPT-101~
ITD*01*3*2**15**30~
N1*BT*ACME WIDGETS INC*92*WIDG-001~
N3*100 INDUSTRIAL PKWY~
N4*CHICAGO*IL*60601*US~
N1*ST*SOME WAREHOUSE*92*WH-07~
N3*500 DOCK RD~
N4*DALLAS*TX*75201*US~
PO1*1*100*EA*9.99**UP*012345678905~
CTP*RS*RES*9.99~
PID*F****HIGH QUALITY WIDGET~
PO4*1*12*EA~
CTT*1~
SE*20*0001~
GE*1*1~
IEA*1*000000001~
Enter fullscreen mode Exit fullscreen mode

The envelope: ISA / GS / ST

Every X12 interchange opens with ISA — the Interchange Control Header. Three things make it special:

  1. It's fixed-width — always 106 characters, including the segment terminator. Every position is contractual: characters 1–3 are ISA, positions 4–18 are the authorization qualifier and info, and so on.
  2. It tells you how to parse the file. The 16th character (ISA16) is the component element separator, and the very last character is the segment terminator. That's why you can always parse an X12 file even if nobody documented it — the envelope describes its own syntax.
  3. It carries identity: sender/receiver qualifiers (ZZ here = mutually defined) and the control number 000000001.

GS is the Functional Group Header (GS*PO = this group carries purchase orders), and ST opens the actual transaction set (ST*850*0001). One ISA can hold many GS groups; one GS can hold many ST transactions.

The order header: BEG / REF / ITD

BEG*00*SA*PO-12345**20260929 is where the business meaning starts:

  • 00 — original (not a change, not a cancel; 05 would mean "replace", 01 would mean "cancel")
  • SA — stand-alone order, the most common type (BK is blanket, NE is not-to-exceed)
  • PO-12345 — the buyer's purchase order number. This is the string your whole ERP will key off of for the next three weeks.
  • 20260929 — the order date, always CCYYMMDD. X12 has a strict opinion about date formats and it is never negotiable.

REF*DP*DEPT-101 is a reference — DP means department number. REF is the Swiss-army-knife segment: every trading partner stuffs a different internal identifier in here, which is half of why EDI mapping is a real discipline and not just parsing.

ITD*01*3*2**15**30 is payment terms, decoded: basic terms (01), 3% discount, payable within 15 days, net 30. If you've ever argued with a vendor about 2/10 net 30, you've been reading ITD segments your whole career.

The parties: N1 loops

N1*BT*ACME WIDGETS INC*92*WIDG-001 — BT is bill-to, identified by ID WIDG-001 with qualifier 92 (assigned by buyer). The second N1 loop says ST — ship-to — with a warehouse ID. N3/N4 are the address lines.

This is the segment where newcomers lose hours: BT vs. ST vs. SF (ship-from) look interchangeable until an invoice posts to the wrong entity. If your 810 invoices keep landing at corporate instead of the warehouse, the answer is almost always hiding in the 850's N1 qualifiers.

The line items: PO1 and friends

PO1*1*100*EA*9.99**UP*012345678905~
CTP*RS*RES*9.99~
PID*F****HIGH QUALITY WIDGET~
PO4*1*12*EA~
Enter fullscreen mode Exit fullscreen mode

PO1 is the money segment:

  • 1 — line item number
  • 100 — quantity ordered
  • EA — unit of measure (each). CA is case, PL is pallet — and yes, this is where unit-of-measure mismatches cause real chargebacks.
  • 9.99 — unit price
  • UP — product/service ID qualifier meaning UPC. VN is vendor item number, CB is buyer catalog number. A PO1 can carry several IDs at once, which is how one line can reference your SKU, their UPC, and the buyer's internal code simultaneously.

The companion segments: CTP confirms the resale pricing class, PID gives the human-readable description (F = free-form), and PO4 says the 100 units ship packed 12 to a case. Your warehouse cares about PO4 a lot more than your API does.

The trailer: CTT / SE / GE / IEA

CTT*1 — one line item in this transaction (a checksum against the PO1 count). SE*20*0001 — 20 segments in the transaction set, control number 0001. Then GS and ISA close with matching control numbers: GE*1*1 (one ST in this GS) and IEA*1*000000001 (one GS in this ISA, matching the ISA control number).

The trailer is EDI's integrity layer. If CTT says 3 but you only have 2 PO1s, the file is corrupt — and good validators catch this before the document ever reaches your parser.

Why this matters to API people

Three lessons I keep re-learning:

  1. The envelope is the contract. In REST we rely on content types and schemas negotiated out-of-band. X12 embeds the syntax declaration (separators) and the routing (sender/receiver IDs) in every file. When an 850 arrives and your parser chokes, the first 106 characters usually tell you why.
  2. Identifiers are tribal. REF, N1, and PO1 product IDs are all "the ID the partner assigns." Mapping them is where AI-assisted tooling earns its keep — a human can eyeball one 850, but not ten thousand with partner-specific REF qualifiers.
  3. Acknowledgments are first-class. Send an 850, expect a 997 functional acknowledgment back — and usually a 855 acknowledgment response. Webhooks that fire-and-forget would be considered rude in this world. (My previous article went deep on AS2 delivery semantics if that interests you.)

If you're integrating with a retailer or distributor and their onboarding packet says "we require EDI," this is the document you'll be generating first. It looks intimidating; it's mostly field positions and qualifiers. Start from the PO1 loop and work outward.

I run SignalEDI — we do AI-assisted EDI mapping and testing for SMBs, flat monthly pricing, no per-document fees. This week I'm writing a daily EDI deep-dive for developers; yesterday was AS2, today is the 850, tomorrow we'll take apart the 856 ship notice.

Top comments (0)