The 850 is the X12 purchase order. A buyer - a retailer, distributor or manufacturer - sends it to a supplier to order goods or services, and it is the transaction most trading relationships start with.
BEG identifies the order, N1 loops name the buyer, ship-to and bill-to parties, and each PO1 loop is a line item with quantity, unit price and product identifiers. CTT closes the order with the line count.
004010PO (GS01)TS850 in EdiFabric.Templates.X12The full X12 850 layout from its OpenEDI definition, the same model ediFabric uses to parse, validate and generate it: 31 loops and 196 segment positions, in file order. Loops are shaded and their segments indented; Max use is how many times a segment or loop may repeat.
| Segment / loop | Name | Usage | Max use |
|---|---|---|---|
ST | Transaction Set Header | Mandatory | 1 |
BEG | Beginning Segment for Purchase Order | Mandatory | 1 |
CUR | Currency | Optional | 1 |
REF | Reference Identification | Optional | >1 |
PER | Administrative Communications Contact | Optional | 3 |
TAX | Tax Reference | Optional | >1 |
FOB | F.O.B. Related Instructions | Optional | >1 |
CTP | Pricing Information | Optional | >1 |
PAM | Period Amount | Optional | 10 |
CSH | Sales Requirements | Optional | 5 |
TC2 | Commodity | Optional | >1 |
| SAC loop | Service, Promotion, Allowance, or Charge Information | Optional | 25 |
SAC | Service, Promotion, Allowance, or Charge Information | Mandatory | 1 |
CUR | Currency | Optional | 1 |
ITD | Terms of Sale/Deferred Terms of Sale | Optional | >1 |
DIS | Discount Detail | Optional | 20 |
INC | Installment Information | Optional | 1 |
DTM | Date/Time Reference | Optional | 10 |
LDT | Lead Time | Optional | 12 |
LIN | Item Identification | Optional | 5 |
SI | Service Characteristic Identification | Optional | >1 |
PID | Product/Item Description | Optional | 200 |
MEA | Measurements | Optional | 40 |
PWK | Paperwork | Optional | 25 |
PKG | Marking, Packaging, Loading | Optional | 200 |
TD1 | Carrier Details (Quantity and Weight) | Optional | 2 |
TD5 | Carrier Details (Routing Sequence/Transit Time) | Optional | 12 |
TD3 | Carrier Details (Equipment) | Optional | 12 |
TD4 | Carrier Details (Special Handling, or Hazardous Materials, or Both) | Optional | 5 |
MAN | Marks and Numbers | Optional | 10 |
PCT | Percent Amounts | Optional | >1 |
CTB | Restrictions/Conditions | Optional | 5 |
TXI | Tax Information | Optional | >1 |
| AMT loop | Monetary Amount | Optional | >1 |
AMT | Monetary Amount | Mandatory | 1 |
REF | Reference Identification | Optional | >1 |
DTM | Date/Time Reference | Optional | 1 |
PCT | Percent Amounts | Optional | >1 |
| FA1 loop | Type of Financial Accounting Data | Optional | >1 |
FA1 | Type of Financial Accounting Data | Mandatory | 1 |
FA2 | Accounting Data | Mandatory | >1 |
| N9 loop | Reference Identification | Optional | 1000 |
N9 | Reference Identification | Mandatory | 1 |
DTM | Date/Time Reference | Optional | >1 |
MSG | Message Text | Optional | 1000 |
| N1 loop | Name | Optional | 200 |
N1 | Name | Mandatory | 1 |
N2 | Additional Name Information | Optional | 2 |
N3 | Address Information | Optional | 2 |
N4 | Geographic Location | Optional | >1 |
NX2 | Location ID Component | Optional | >1 |
REF | Reference Identification | Optional | 12 |
PER | Administrative Communications Contact | Optional | >1 |
SI | Service Characteristic Identification | Optional | >1 |
FOB | F.O.B. Related Instructions | Optional | 1 |
TD1 | Carrier Details (Quantity and Weight) | Optional | 2 |
TD5 | Carrier Details (Routing Sequence/Transit Time) | Optional | 12 |
TD3 | Carrier Details (Equipment) | Optional | 12 |
TD4 | Carrier Details (Special Handling, or Hazardous Materials, or Both) | Optional | 5 |
PKG | Marking, Packaging, Loading | Optional | 200 |
| LM loop | Code Source Information | Optional | >1 |
LM | Code Source Information | Mandatory | 1 |
LQ | Industry Code | Mandatory | >1 |
| SPI loop | Specification Identifier | Optional | >1 |
SPI | Specification Identifier | Mandatory | 1 |
REF | Reference Identification | Optional | 5 |
DTM | Date/Time Reference | Optional | 5 |
MSG | Message Text | Optional | 50 |
| N1 loop | Name | Optional | 20 |
N1 | Name | Mandatory | 1 |
N2 | Additional Name Information | Optional | 2 |
N3 | Address Information | Optional | 2 |
N4 | Geographic Location | Optional | 1 |
REF | Reference Identification | Optional | 20 |
G61 | Contact | Optional | 1 |
MSG | Message Text | Optional | 50 |
| CB1 loop | Contract and Cost Accounting Standards Data | Optional | >1 |
CB1 | Contract and Cost Accounting Standards Data | Mandatory | 1 |
REF | Reference Identification | Optional | 20 |
DTM | Date/Time Reference | Optional | 5 |
LDT | Lead Time | Optional | 1 |
MSG | Message Text | Optional | 50 |
| ADV loop | Advertising Demographic Information | Optional | >1 |
ADV | Advertising Demographic Information | Mandatory | 1 |
DTM | Date/Time Reference | Optional | >1 |
MTX | Text | Optional | >1 |
| PO1 loop | Baseline Item Data | Mandatory | 100000 |
PO1 | Baseline Item Data | Mandatory | 1 |
LIN | Item Identification | Optional | >1 |
SI | Service Characteristic Identification | Optional | >1 |
CUR | Currency | Optional | 1 |
CN1 | Contract Information | Optional | 1 |
PO3 | Additional Item Detail | Optional | 25 |
| CTP loop | Pricing Information | Optional | >1 |
CTP | Pricing Information | Mandatory | 1 |
CUR | Currency | Optional | 1 |
PAM | Period Amount | Optional | 10 |
MEA | Measurements | Optional | 40 |
| PID loop | Product/Item Description | Optional | 1000 |
PID | Product/Item Description | Mandatory | 1 |
MEA | Measurements | Optional | 10 |
PWK | Paperwork | Optional | 25 |
PO4 | Item Physical Details | Optional | >1 |
REF | Reference Identification | Optional | >1 |
PER | Administrative Communications Contact | Optional | 3 |
| SAC loop | Service, Promotion, Allowance, or Charge Information | Optional | 25 |
SAC | Service, Promotion, Allowance, or Charge Information | Mandatory | 1 |
CUR | Currency | Optional | 1 |
CTP | Pricing Information | Optional | 1 |
IT8 | Conditions of Sale | Optional | 1 |
CSH | Sales Requirements | Optional | >1 |
ITD | Terms of Sale/Deferred Terms of Sale | Optional | 2 |
DIS | Discount Detail | Optional | 20 |
INC | Installment Information | Optional | 1 |
TAX | Tax Reference | Optional | >1 |
FOB | F.O.B. Related Instructions | Optional | >1 |
SDQ | Destination Quantity | Optional | 500 |
IT3 | Additional Item Data | Optional | 5 |
DTM | Date/Time Reference | Optional | 10 |
TC2 | Commodity | Optional | >1 |
TD1 | Carrier Details (Quantity and Weight) | Optional | 1 |
TD5 | Carrier Details (Routing Sequence/Transit Time) | Optional | 12 |
TD3 | Carrier Details (Equipment) | Optional | 12 |
TD4 | Carrier Details (Special Handling, or Hazardous Materials, or Both) | Optional | 5 |
PCT | Percent Amounts | Optional | >1 |
MAN | Marks and Numbers | Optional | 10 |
MSG | Message Text | Optional | >1 |
SPI | Specification Identifier | Optional | >1 |
TXI | Tax Information | Optional | >1 |
CTB | Restrictions/Conditions | Optional | >1 |
| QTY loop | Quantity | Optional | >1 |
QTY | Quantity | Mandatory | 1 |
SI | Service Characteristic Identification | Optional | >1 |
| SCH loop | Line Item Schedule | Optional | 200 |
SCH | Line Item Schedule | Mandatory | 1 |
TD1 | Carrier Details (Quantity and Weight) | Optional | 2 |
TD5 | Carrier Details (Routing Sequence/Transit Time) | Optional | 12 |
TD3 | Carrier Details (Equipment) | Optional | 12 |
TD4 | Carrier Details (Special Handling, or Hazardous Materials, or Both) | Optional | 5 |
REF | Reference Identification | Optional | >1 |
| PKG loop | Marking, Packaging, Loading | Optional | 200 |
PKG | Marking, Packaging, Loading | Mandatory | 1 |
MEA | Measurements | Optional | >1 |
| LS loop | Loop Header | Optional | 1 |
LS | Loop Header | Mandatory | 1 |
| LDT loop | Lead Time | Optional | >1 |
LDT | Lead Time | Mandatory | 1 |
QTY | Quantity | Optional | >1 |
MSG | Message Text | Optional | 1 |
REF | Reference Identification | Optional | 3 |
| LM loop | Code Source Information | Optional | >1 |
LM | Code Source Information | Mandatory | 1 |
LQ | Industry Code | Mandatory | >1 |
LE | Loop Trailer | Mandatory | 1 |
| N9 loop | Reference Identification | Optional | 1000 |
N9 | Reference Identification | Mandatory | 1 |
DTM | Date/Time Reference | Optional | >1 |
MEA | Measurements | Optional | 40 |
MSG | Message Text | Optional | 1000 |
| N1 loop | Name | Optional | 200 |
N1 | Name | Mandatory | 1 |
N2 | Additional Name Information | Optional | 2 |
N3 | Address Information | Optional | 2 |
N4 | Geographic Location | Optional | 1 |
QTY | Quantity | Optional | >1 |
NX2 | Location ID Component | Optional | >1 |
REF | Reference Identification | Optional | 12 |
PER | Administrative Communications Contact | Optional | 3 |
SI | Service Characteristic Identification | Optional | >1 |
DTM | Date/Time Reference | Optional | 1 |
FOB | F.O.B. Related Instructions | Optional | 1 |
SCH | Line Item Schedule | Optional | 200 |
TD1 | Carrier Details (Quantity and Weight) | Optional | 2 |
TD5 | Carrier Details (Routing Sequence/Transit Time) | Optional | 12 |
TD3 | Carrier Details (Equipment) | Optional | 12 |
TD4 | Carrier Details (Special Handling, or Hazardous Materials, or Both) | Optional | 5 |
PKG | Marking, Packaging, Loading | Optional | 200 |
| LDT loop | Lead Time | Optional | >1 |
LDT | Lead Time | Mandatory | 1 |
MAN | Marks and Numbers | Optional | 10 |
QTY | Quantity | Optional | 5 |
MSG | Message Text | Optional | 1 |
REF | Reference Identification | Optional | 3 |
| SLN loop | Subline Item Detail | Optional | 1000 |
SLN | Subline Item Detail | Mandatory | 1 |
MSG | Message Text | Optional | >1 |
SI | Service Characteristic Identification | Optional | >1 |
PID | Product/Item Description | Optional | 1000 |
PO3 | Additional Item Detail | Optional | 104 |
TC2 | Commodity | Optional | >1 |
ADV | Advertising Demographic Information | Optional | >1 |
DTM | Date/Time Reference | Optional | 10 |
CTP | Pricing Information | Optional | 25 |
PAM | Period Amount | Optional | 10 |
PO4 | Item Physical Details | Optional | 1 |
TAX | Tax Reference | Optional | 3 |
| N9 loop | Reference Identification | Optional | >1 |
N9 | Reference Identification | Mandatory | 1 |
DTM | Date/Time Reference | Optional | >1 |
MSG | Message Text | Optional | >1 |
| SAC loop | Service, Promotion, Allowance, or Charge Information | Optional | 25 |
SAC | Service, Promotion, Allowance, or Charge Information | Mandatory | 1 |
CUR | Currency | Optional | 1 |
CTP | Pricing Information | Optional | 1 |
| QTY loop | Quantity | Optional | >1 |
QTY | Quantity | Mandatory | 1 |
SI | Service Characteristic Identification | Optional | >1 |
| N1 loop | Name | Optional | 10 |
N1 | Name | Mandatory | 1 |
N2 | Additional Name Information | Optional | 2 |
N3 | Address Information | Optional | 2 |
N4 | Geographic Location | Optional | 1 |
NX2 | Location ID Component | Optional | >1 |
REF | Reference Identification | Optional | 12 |
PER | Administrative Communications Contact | Optional | 3 |
SI | Service Characteristic Identification | Optional | >1 |
| AMT loop | Monetary Amount | Optional | >1 |
AMT | Monetary Amount | Mandatory | 1 |
REF | Reference Identification | Optional | 1 |
PCT | Percent Amounts | Optional | >1 |
| LM loop | Code Source Information | Optional | >1 |
LM | Code Source Information | Mandatory | 1 |
LQ | Industry Code | Mandatory | >1 |
| CTT loop | Transaction Totals | Optional | 1 |
CTT | Transaction Totals | Mandatory | 1 |
AMT | Monetary Amount | Optional | 1 |
SE | Transaction Set Trailer | Mandatory | 1 |
Mandatory segments must be sent, Optional ones only when the data applies. Trading partners often add their own rules in companion guides - ediFabric templates can be adjusted to match. Open the element-level definition in the EdiNation spec library.
A tax-exempt purchase order for one line item, from the X12 examples. Paste it into EdiNation to see every element named and validated.
ISA*00* *00* *16*SENDER1 *1B*RECEIVER1 *071216*1406*U*00204*000000263*1*T*>~ GS*IN*SENDER1*RECEIVER1*20071216*1406*000000001*X*004010~ ST*850*0001~ BEG*00*SA*XX-1234**20170301**NA~ PER*BD*ED SMITH*TE*8001234567~ TAX*53247765*SP*CA*********9~ N1*BY*ABC AEROSPACE*9*1234567890101~ N2*AIRCRAFT DIVISION~ N3*2000 JET BLVD~ N4*FIGHTER TOWN*CA*98898~ PO1*1*25*EA*36*PE*MG*XYZ-1234~ MEA*WT*WT*10*OZ~ IT8*******B0~ SCH*25*EA***106*20170615~ CTT*1~ AMT*TT*900~ SE*15*0001~ GE*1*000000001~ IEA*1*000000263~
ediFabric turns every loop, segment and element into a named field. This is the transaction from the sample, in the JSON that ediFabric Native and Cloud return and accept.
{
"ST": {
"TransactionSetIdentifierCode_01": "850",
"TransactionSetControlNumber_02": "0001"
},
"BEG": {
"TransactionSetPurposeCode_01": "00",
"PurchaseOrderTypeCode_02": "SA",
"PurchaseOrderNumber_03": "XX-1234",
"Date_05": "20170301",
"AcknowledgmentType_07": "NA"
},
"PER": [
{
"ContactFunctionCode_01": "BD",
"Name_02": "ED SMITH",
"CommunicationNumberQualifier_03": "TE",
"CommunicationNumber_04": "8001234567"
}
],
"TAX": [
{
"TaxIdentificationNumber_01": "53247765",
"LocationQualifier_02": "SP",
"LocationIdentifier_03": "CA",
"TaxExemptCode_12": "9"
}
],
"N1Loop": [
{
"N1": {
"EntityIdentifierCode_01": "BY",
"Name_02": "ABC AEROSPACE",
"IdentificationCodeQualifier_03": "9",
"IdentificationCode_04": "1234567890101"
},
"N2": [
{
"Name_01": "AIRCRAFT DIVISION"
}
],
"N3": [
{
"AddressInformation_01": "2000 JET BLVD"
}
],
"N4": [
{
"CityName_01": "FIGHTER TOWN",
"StateorProvinceCode_02": "CA",
"PostalCode_03": "98898"
}
]
}
],
"PO1Loop": [
{
"PO1": {
"AssignedIdentification_01": "1",
"QuantityOrdered_02": "25",
"UnitorBasisforMeasurementCode_03": "EA",
"UnitPrice_04": "36",
"BasisofUnitPriceCode_05": "PE",
"ProductServiceIDQualifier_06": "MG",
"ProductServiceID_07": "XYZ-1234"
},
"MEA": [
{
"MeasurementReferenceIDCode_01": "WT",
"MeasurementQualifier_02": "WT",
"MeasurementValue_03": "10",
"CompositeUnitofMeasure_04": {
"UnitorBasisforMeasurementCode_01": "OZ"
}
}
],
"IT8": {
"ProductServiceSubstitutionCode_07": "B0"
},
"SCHLoop": [
{
"SCH": {
"Quantity_01": "25",
"UnitorBasisforMeasurementCode_02": "EA",
"DateTimeQualifier_05": "106",
"Date_06": "20170615"
}
}
]
}
],
"CTTLoop": {
"CTT": {
"NumberofLineItems_01": "1"
},
"AMT": {
"AmountQualifierCode_01": "TT",
"MonetaryAmount_02": "900"
}
},
"SE": {
"NumberofIncludedSegments_01": "15",
"TransactionSetControlNumber_02": "0001"
}
}Read the file into typed objects with ediFabric .NET, convert it to JSON in process with the ediFabric Native bindings for Python, Java and C, or post it to the ediFabric Cloud REST API from any language.
using EdiFabric.Templates.X12004010; License.SetSerial("YOUR_SERIAL_KEY"); using (var stream = File.OpenRead(@"C:\edi\PurchaseOrder.txt")) using (var reader = new X12Reader(stream, "EdiFabric.Templates.X12")) { var items = await reader.ReadToEndAsync(); foreach (var transaction in items.OfType<TS850>()) { if (transaction.IsValid(out MessageErrorContext errors)) Console.WriteLine($"{transaction.ST.TransactionSetControlNumber_02} is valid"); else Console.WriteLine(string.Join(Environment.NewLine, errors.Flatten())); } }
import json import edifabric_x12 as ef serial = "YOUR_SERIAL_KEY" ef.load_library() ef.set_serial(serial) ef.set_map(json.dumps({"default": serial, "maps": {}})) edi = open("PurchaseOrder.txt", "rb").read() output, offset = ef.parse(edi, ef.ParseMode.JSON_VALIDATE) transactions = output[:offset] report = json.loads(output[offset:]) print(report["errors_count"])
import com.edifabric.nativex12.EdiFabricX12; import com.edifabric.nativex12.ParseMode; import com.edifabric.nativex12.ParseResult; String serial = "YOUR_SERIAL_KEY"; EdiFabricX12.loadLibrary(); EdiFabricX12.setSerial(serial); EdiFabricX12.setMap("{\"default\":\"" + serial + "\",\"maps\":{}}"); String edi = Files.readString(Path.of("PurchaseOrder.txt")); ParseResult result = EdiFabricX12.parse(edi, ParseMode.JSON_VALIDATE); System.out.println(result.getTransactions()); System.out.println(result.getReport());
#include "edifabric_x12.h" const char *serial = "YOUR_SERIAL_KEY"; ef_parse_result result; if (ef_load_library(NULL) != 0) return 1; ef_set_serial(serial); ef_set_map("{\"default\":\"YOUR_SERIAL_KEY\",\"maps\":{}}"); char *edi = read_file("PurchaseOrder.txt", NULL); /* helper in example_all_functions.c */ if (ef_parse(edi, EF_PARSE_JSON_VALIDATE, NULL, &result) == 0) { /* transactions = output[0 .. offset), report = output[offset .. length) */ fwrite(result.output.data, 1, (size_t)result.output.length, stdout); ef_free(result.output.data); }
curl -X POST 'https://api.edination.com/v2/x12/read' \ -H 'Ocp-Apim-Subscription-Key: YOUR_SERIAL_KEY' \ -H 'Content-Type: application/octet-stream' \ --data-binary '@PurchaseOrder.txt'
Populate a TS850 object in .NET, or pass JSON in the shape shown above to ediFabric Native or ediFabric Cloud, and get a valid 850 file back.
using EdiFabric.Templates.X12004010; License.SetSerial("YOUR_SERIAL_KEY"); var transaction = new TS850(); // Indicates the start of a purchase order transaction set and assigns a control number. transaction.ST = new ST(); transaction.ST.TransactionSetIdentifierCode_01 = "850"; transaction.ST.TransactionSetControlNumber_02 = "0001"; // Indicates that this is original purchase order number XX-1234, dated March 1, 2017, and that no acknowledgment is necessary. transaction.BEG = new BEG(); transaction.BEG.TransactionSetPurposeCode_01 = "00"; transaction.BEG.PurchaseOrderTypeCode_02 = "SA"; transaction.BEG.PurchaseOrderNumber_03 = "XX-1234"; transaction.BEG.Date_05 = "20170301"; transaction.BEG.AcknowledgmentType_07 = "NA"; // Repeating PER transaction.PER = new List<PER>(); // ... set the remaining loops and segments the same way // SegmentBuilders is in the Common project of the example repository using (var stream = new MemoryStream()) { using (var writer = new X12Writer(stream)) { writer.Write(SegmentBuilders.BuildIsa("1")); writer.Write(SegmentBuilders.BuildGs("1")); writer.Write(transaction); } Console.WriteLine(Encoding.UTF8.GetString(stream.ToArray())); }
import json import edifabric_x12 as ef serial = "YOUR_SERIAL_KEY" ef.load_library() ef.set_serial(serial) ef.set_map(json.dumps({"default": serial, "maps": {}})) # the transactions JSON returned by ef.parse, edited or produced by your application transactions = open("PurchaseOrder.json", "rb").read() edi = ef.build(transactions, postfix="\r\n") print(edi)
import com.edifabric.nativex12.EdiFabricX12; String serial = "YOUR_SERIAL_KEY"; EdiFabricX12.loadLibrary(); EdiFabricX12.setSerial(serial); EdiFabricX12.setMap("{\"default\":\"" + serial + "\",\"maps\":{}}"); // the transactions JSON returned by parse, edited or produced by your application String transactions = Files.readString(Path.of("PurchaseOrder.json")); String edi = EdiFabricX12.build(transactions, "\r\n"); System.out.println(edi);
#include "edifabric_x12.h" ef_buffer edi; if (ef_load_library(NULL) != 0) return 1; ef_set_serial("YOUR_SERIAL_KEY"); ef_set_map("{\"default\":\"YOUR_SERIAL_KEY\",\"maps\":{}}"); /* the transactions JSON returned by ef_parse, edited or produced by your application */ char *transactions = read_file("PurchaseOrder.json", NULL); if (ef_build(transactions, "\r\n", &edi) == 0) { fwrite(edi.data, 1, (size_t)edi.length, stdout); ef_free(edi.data); }
# the JSON returned by /read, edited or produced by your application curl -X POST 'https://api.edination.com/v2/x12/write' \ -H 'Ocp-Apim-Subscription-Key: YOUR_SERIAL_KEY' \ -H 'Content-Type: application/json' \ --data-binary '@PurchaseOrder.json' \ -o 'PurchaseOrder.txt'
The supplier returns a 997 functional acknowledgment, often an 855 purchase order acknowledgment, then an 856 ship notice when the goods ship and an 810 invoice.
With an 860 purchase order change request, or by resending the 850 with BEG01 set to 01 (cancellation) or 05 (replace) when the trading partner allows it.
The X12 standard is broad, so each trading partner publishes an implementation guide with the segments, qualifiers and codes it uses. ediFabric templates can be adjusted to match.
In .NET, install EdiFabric and EdiFabric.Templates.X12, read the file with X12Reader into TS850 objects and write them back with X12Writer. From Python, Java or C, use ediFabric Native, which converts 850 files to JSON and JSON back to X12 inside your process. From any other language, post the file to the ediFabric Cloud REST API.