X12 855 Purchase Order Acknowledgment

The 855 is the X12 purchase order acknowledgment. The supplier sends it after receiving an 850 to confirm the order, and to report which lines are accepted, changed, backordered or rejected.

BAK carries the acknowledgment type for the whole order and references the PO number; each PO1 loop can carry ACK segments with line status, quantities and scheduled dates.

At a glance

Standard
X12
Version
004010
Functional group
PR (GS01)
Sent by
Supplier to buyer
Responses
997
ediFabric .NET template
TS855 in EdiFabric.Templates.X12
OpenEDI definition
View 855 in the spec library

855 structure

The full X12 855 layout from its OpenEDI definition, the same model ediFabric uses to parse, validate and generate it: 19 loops and 147 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
STTransaction Set HeaderMandatory1
BAKBeginning Segment for Purchase Order AcknowledgmentMandatory1
CURCurrencyOptional1
REFReference IdentificationOptional>1
PERAdministrative Communications ContactOptional3
TAXTax ReferenceOptional>1
FOBF.O.B. Related InstructionsOptional>1
CTPPricing InformationOptional>1
PAMPeriod AmountOptional10
CSHSales RequirementsOptional1
SAC loopService, Promotion, Allowance, or Charge InformationOptional25
SACService, Promotion, Allowance, or Charge InformationMandatory1
CURCurrencyOptional1
ITDTerms of Sale/Deferred Terms of SaleOptional5
DISDiscount DetailOptional20
INCInstallment InformationOptional1
DTMDate/Time ReferenceOptional10
LDTLead TimeOptional12
LINItem IdentificationOptional5
SIService Characteristic IdentificationOptional>1
PIDProduct/Item DescriptionOptional200
MEAMeasurementsOptional40
PWKPaperworkOptional25
PKGMarking, Packaging, LoadingOptional25
TD1Carrier Details (Quantity and Weight)Optional2
TD5Carrier Details (Routing Sequence/Transit Time)Optional12
TD3Carrier Details (Equipment)Optional12
TD4Carrier Details (Special Handling, or Hazardous Materials, or Both)Optional5
MANMarks and NumbersOptional10
TXITax InformationOptional>1
CTBRestrictions/ConditionsOptional>1
N9 loopReference IdentificationOptional1000
N9Reference IdentificationMandatory1
DTMDate/Time ReferenceOptional>1
MSGMessage TextOptional1000
N1 loopNameOptional200
N1NameMandatory1
N2Additional Name InformationOptional2
N3Address InformationOptional2
N4Geographic LocationOptional1
NX2Location ID ComponentOptional>1
REFReference IdentificationOptional12
PERAdministrative Communications ContactOptional>1
SIService Characteristic IdentificationOptional>1
FOBF.O.B. Related InstructionsOptional1
TD1Carrier Details (Quantity and Weight)Optional2
TD5Carrier Details (Routing Sequence/Transit Time)Optional12
TD3Carrier Details (Equipment)Optional12
TD4Carrier Details (Special Handling, or Hazardous Materials, or Both)Optional5
PKGMarking, Packaging, LoadingOptional25
MSGMessage TextOptional>1
ADV loopAdvertising Demographic InformationOptional>1
ADVAdvertising Demographic InformationMandatory1
DTMDate/Time ReferenceOptional>1
MTXTextOptional>1
PO1 loopBaseline Item DataOptional100000
PO1Baseline Item DataMandatory1
LINItem IdentificationOptional>1
SIService Characteristic IdentificationOptional>1
CURCurrencyOptional1
PO3Additional Item DetailOptional25
CTPPricing InformationOptional>1
PAMPeriod AmountOptional10
MEAMeasurementsOptional40
PID loopProduct/Item DescriptionOptional1000
PIDProduct/Item DescriptionMandatory1
MEAMeasurementsOptional10
PWKPaperworkOptional25
PO4Item Physical DetailsOptional>1
REFReference IdentificationOptional>1
PERAdministrative Communications ContactOptional3
SAC loopService, Promotion, Allowance, or Charge InformationOptional25
SACService, Promotion, Allowance, or Charge InformationMandatory1
CURCurrencyOptional1
IT8Conditions of SaleOptional1
CSHSales RequirementsOptional>1
ITDTerms of Sale/Deferred Terms of SaleOptional2
DISDiscount DetailOptional20
INCInstallment InformationOptional1
TAXTax ReferenceOptional>1
FOBF.O.B. Related InstructionsOptional>1
SDQDestination QuantityOptional500
DTMDate/Time ReferenceOptional10
LDTLead TimeOptional12
TD1Carrier Details (Quantity and Weight)Optional1
TD5Carrier Details (Routing Sequence/Transit Time)Optional12
TD3Carrier Details (Equipment)Optional12
TD4Carrier Details (Special Handling, or Hazardous Materials, or Both)Optional5
ACK loopLine Item AcknowledgmentOptional104
ACKLine Item AcknowledgmentMandatory1
DTMDate/Time ReferenceOptional1
MANMarks and NumbersOptional10
AMTMonetary AmountOptional1
CTBRestrictions/ConditionsOptional>1
TXITax InformationOptional>1
QTY loopQuantityOptional>1
QTYQuantityMandatory1
SIService Characteristic IdentificationOptional>1
PKG loopMarking, Packaging, LoadingOptional200
PKGMarking, Packaging, LoadingMandatory1
MEAMeasurementsOptional>1
SCH loopLine Item ScheduleOptional200
SCHLine Item ScheduleMandatory1
TD1Carrier Details (Quantity and Weight)Optional2
TD5Carrier Details (Routing Sequence/Transit Time)Optional12
TD3Carrier Details (Equipment)Optional12
TD4Carrier Details (Special Handling, or Hazardous Materials, or Both)Optional5
REFReference IdentificationOptional>1
N9 loopReference IdentificationOptional1000
N9Reference IdentificationMandatory1
DTMDate/Time ReferenceOptional>1
MSGMessage TextOptional1000
N1 loopNameOptional200
N1NameMandatory1
N2Additional Name InformationOptional2
N3Address InformationOptional2
N4Geographic LocationOptional1
NX2Location ID ComponentOptional>1
REFReference IdentificationOptional12
PERAdministrative Communications ContactOptional3
SIService Characteristic IdentificationOptional>1
DTMDate/Time ReferenceOptional1
FOBF.O.B. Related InstructionsOptional1
SCHLine Item ScheduleOptional200
TD1Carrier Details (Quantity and Weight)Optional2
TD5Carrier Details (Routing Sequence/Transit Time)Optional12
TD3Carrier Details (Equipment)Optional12
TD4Carrier Details (Special Handling, or Hazardous Materials, or Both)Optional5
QTYQuantityOptional>1
PKGMarking, Packaging, LoadingOptional25
SLN loopSubline Item DetailOptional1000
SLNSubline Item DetailMandatory1
MSGMessage TextOptional>1
SIService Characteristic IdentificationOptional>1
PIDProduct/Item DescriptionOptional1000
PO3Additional Item DetailOptional25
CTPPricing InformationOptional25
PAMPeriod AmountOptional10
ACKLine Item AcknowledgmentOptional104
SAC loopService, Promotion, Allowance, or Charge InformationOptional10
SACService, Promotion, Allowance, or Charge InformationMandatory1
CURCurrencyOptional1
DTMDate/Time ReferenceOptional10
PO4Item Physical DetailsOptional1
TAXTax ReferenceOptional3
ADVAdvertising Demographic InformationOptional>1
QTY loopQuantityOptional>1
QTYQuantityMandatory1
SIService Characteristic IdentificationOptional>1
N9 loopReference IdentificationOptional>1
N9Reference IdentificationMandatory1
DTMDate/Time ReferenceOptional>1
MSGMessage TextOptional>1
N1 loopNameOptional10
N1NameMandatory1
N2Additional Name InformationOptional2
N3Address InformationOptional2
N4Geographic LocationOptional1
NX2Location ID ComponentOptional>1
REFReference IdentificationOptional12
PERAdministrative Communications ContactOptional3
SIService Characteristic IdentificationOptional>1
CTT loopTransaction TotalsOptional1
CTTTransaction TotalsMandatory1
AMTMonetary AmountOptional1
SETransaction Set TrailerMandatory1

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.

Sample 855 file

An acknowledgment of a purchase order with line-level status. Paste it into EdiNation to see every element named and validated.

ISA*00*          *00*          *16*SENDER1        *14*RECEIVER1      *071216*1406*U*00204*000000263*1*T*>~
GS*IN*SENDER1*RECEIVER1*20071216*1406*000000001*X*004010~
ST*855*0005~
BAK*16*AP*1234567*20050102~
DTM*068*20050203~
N1*SF*XYZ MANUFACTURING CO*01*987654321~
N1*ST*KOHLS DEPARTMENT STORES*92*0085~
PO1*000001*3*EA***UP*123456789012*VA*BLU89Z012*CM*123*SM*12345~
PO1*000002*5*EA***UP*123456798123*VA*BLK98A023*CM*321*SM*12345~
PO1*000003*1*EA***UP*999988888001*VA*981RACK~
CTT*3~
SE*10*0005~
GE*2*000000001~
IEA*1*000000263~

The same 855 as JSON

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": "855",
    "TransactionSetControlNumber_02": "0005"
  },
  "BAK": {
    "TransactionSetPurposeCode_01": "16",
    "AcknowledgmentType_02": "AP",
    "PurchaseOrderNumber_03": "1234567",
    "Date_04": "20050102"
  },
  "DTM": [
    {
      "DateTimeQualifier_01": "068",
      "Date_02": "20050203"
    }
  ],
  "N1Loop": [
    {
      "N1": {
        "EntityIdentifierCode_01": "SF",
        "Name_02": "XYZ MANUFACTURING CO",
        "IdentificationCodeQualifier_03": "01",
        "IdentificationCode_04": "987654321"
      }
    },
    {
      "N1": {
        "EntityIdentifierCode_01": "ST",
        "Name_02": "KOHLS DEPARTMENT STORES",
        "IdentificationCodeQualifier_03": "92",
        "IdentificationCode_04": "0085"
      }
    }
  ],
  "PO1Loop": [
    {
      "PO1": {
        "AssignedIdentification_01": "000001",
        "QuantityOrdered_02": "3",
        "UnitorBasisforMeasurementCode_03": "EA",
        "ProductServiceIDQualifier_06": "UP",
        "ProductServiceID_07": "123456789012",
        "ProductServiceIDQualifier_08": "VA",
        "ProductServiceID_09": "BLU89Z012",
        "ProductServiceIDQualifier_10": "CM",
        "ProductServiceID_11": "123",
        "ProductServiceIDQualifier_12": "SM",
        "ProductServiceID_13": "12345"
      }
    },
    {
      "PO1": {
        "AssignedIdentification_01": "000002",
        "QuantityOrdered_02": "5",
        "UnitorBasisforMeasurementCode_03": "EA",
        "ProductServiceIDQualifier_06": "UP",
        "ProductServiceID_07": "123456798123",
        "ProductServiceIDQualifier_08": "VA",
        "ProductServiceID_09": "BLK98A023",
        "ProductServiceIDQualifier_10": "CM",
        "ProductServiceID_11": "321",
        "ProductServiceIDQualifier_12": "SM",
        "ProductServiceID_13": "12345"
      }
    },
    {
      "PO1": {
        "AssignedIdentification_01": "000003",
        "QuantityOrdered_02": "1",
        "UnitorBasisforMeasurementCode_03": "EA",
        "ProductServiceIDQualifier_06": "UP",
        "ProductServiceID_07": "999988888001",
        "ProductServiceIDQualifier_08": "VA",
        "ProductServiceID_09": "981RACK"
      }
    }
  ],
  "CTTLoop": {
    "CTT": {
      "NumberofLineItems_01": "3"
    }
  },
  "SE": {
    "NumberofIncludedSegments_01": "10",
    "TransactionSetControlNumber_02": "0005"
  }
}

Parse and validate an 855 file

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\PurchaseOrdersAcknowledgement.txt"))
using (var reader = new X12Reader(stream, "EdiFabric.Templates.X12"))
{
    var items = await reader.ReadToEndAsync();
    foreach (var transaction in items.OfType<TS855>())
    {
        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("PurchaseOrdersAcknowledgement.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("PurchaseOrdersAcknowledgement.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("PurchaseOrdersAcknowledgement.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 '@PurchaseOrdersAcknowledgement.txt'

Generate an 855 file

Populate a TS855 object in .NET, or pass JSON in the shape shown above to ediFabric Native or ediFabric Cloud, and get a valid 855 file back.

using EdiFabric.Templates.X12004010;

License.SetSerial("YOUR_SERIAL_KEY");

var transaction = new TS855();

//  855 is the Transaction Set Identifier Code for the Purchase Orders Acknowledgement
//  0001 is the Transaction Set Control Number
transaction.ST = new ST();
transaction.ST.TransactionSetIdentifierCode_01 = "855";
transaction.ST.TransactionSetControlNumber_02 = "0001";


//  Purchase Order Number 1234567
//  Purchase Order Date 01 / 02 / 05            
transaction.BAK = new BAK();
transaction.BAK.TransactionSetPurposeCode_01 = "16";
transaction.BAK.AcknowledgmentType_02 = "AP";
transaction.BAK.PurchaseOrderNumber_03 = "1234567";
transaction.BAK.Date_04 = "20050102";

//  Repeating DTM
transaction.DTM = new List<DTM>();

// ... 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("PurchaseOrdersAcknowledgement.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("PurchaseOrdersAcknowledgement.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("PurchaseOrdersAcknowledgement.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 '@PurchaseOrdersAcknowledgement.json' \
-o 'PurchaseOrdersAcknowledgement.txt'

855 questions

What do the BAK02 codes mean?

AC acknowledge with detail and change, AD acknowledge with detail and no change, AK acknowledge with no detail or change, RJ rejected with no detail. Trading partners usually allow a subset.

How are line changes reported?

With ACK segments in the PO1 loop. ACK01 is the line status, such as IA accepted, IB backordered, IC changed or IR rejected, with the quantity and date in the following elements.

Is the 855 the same as a 997?

No. The 997 only confirms that the 850 was received and is syntactically valid. The 855 is a business response about the order itself.

How do I parse and generate X12 855 files in .NET, Python, Java and C?

In .NET, install EdiFabric and EdiFabric.Templates.X12, read the file with X12Reader into TS855 objects and write them back with X12Writer. From Python, Java or C, use ediFabric Native, which converts 855 files to JSON and JSON back to X12 inside your process. From any other language, post the file to the ediFabric Cloud REST API.

Parse your first 855 in five minutes

The Community plan is free forever and needs no credit card. It includes ediFabric .NET, Native and Cloud.