The 861 is the X12 receiving advice/acceptance certificate. The receiving party sends it to confirm what was actually received from a shipment, and in what condition.
BRA identifies the receipt, and each RCD loop reports the received, accepted, returned or damaged quantities of an item, which lets the supplier reconcile the shipment against the 856 and the 810.
004010RC (GS01)TS861 in EdiFabric.Templates.X12The full X12 861 layout from its OpenEDI definition, the same model ediFabric uses to parse, validate and generate it: 7 loops and 55 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 |
BRA | Beginning Segment for Receiving Advice or Acceptance Certificate | Mandatory | 1 |
CUR | Currency | Optional | 1 |
REF | Reference Identification | Optional | >1 |
PER | Administrative Communications Contact | Optional | 3 |
DTM | Date/Time Reference | Mandatory | 10 |
PRF | Purchase Order Reference | Optional | 25 |
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 |
MEA | Measurements | Optional | 40 |
| 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 |
REF | Reference Identification | Optional | 100 |
PER | Administrative Communications Contact | Optional | 3 |
FOB | F.O.B. Related Instructions | Optional | 1 |
| LM loop | Code Source Information | Optional | 10 |
LM | Code Source Information | Mandatory | 1 |
LQ | Industry Code | Mandatory | 100 |
| RCD loop | Receiving Conditions | Optional | 200000 |
RCD | Receiving Conditions | Mandatory | 1 |
SN1 | Item Detail (Shipment) | Optional | 1 |
CUR | Currency | Optional | 1 |
LIN | Item Identification | Optional | 100 |
PID | Product/Item Description | Optional | 1000 |
PO4 | Item Physical Details | Optional | 100 |
REF | Reference Identification | Optional | 12 |
PER | Administrative Communications Contact | Optional | 3 |
DTM | Date/Time Reference | Optional | 10 |
PRF | Purchase Order Reference | Optional | 25 |
MEA | Measurements | Optional | >1 |
FOB | F.O.B. Related Instructions | Optional | 1 |
TD1 | Carrier Details (Quantity and Weight) | Optional | 20 |
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 |
SAC | Service, Promotion, Allowance, or Charge Information | Optional | 10 |
MAN | Marks and Numbers | Optional | >1 |
| LM loop | Code Source Information | Optional | 10 |
LM | Code Source Information | Mandatory | 1 |
LQ | Industry Code | Mandatory | 100 |
| SLN loop | Subline Item Detail | Optional | 100 |
SLN | Subline Item Detail | Mandatory | 1 |
PID | Product/Item Description | Optional | 1000 |
NM1 | Individual or Organizational Name | Optional | 1 |
| LM loop | Code Source Information | Optional | 10 |
LM | Code Source Information | Mandatory | 1 |
LQ | Industry Code | Mandatory | 100 |
| 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 |
REF | Reference Identification | Optional | 100 |
PER | Administrative Communications Contact | Optional | 3 |
FOB | F.O.B. Related Instructions | Optional | 1 |
CTT | Transaction Totals | 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 receiving advice for items received against an order. 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*861*0002~ BRA*C000548241*20090224*00*3~ DTM*050*20090102*0855*ET~ N1*SU**92*43677~ RCD******1*EA*09~ LIN**BP*U0070062~ REF*ACC*A~ DTM*945*20090102*0855*ET~ SE*9*0002~ GE*2*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": "861",
"TransactionSetControlNumber_02": "0002"
},
"BRA": {
"ReferenceIdentification_01": "C000548241",
"Date_02": "20090224",
"TransactionSetPurposeCode_03": "00",
"ReceivingAdviceorAcceptanceCertificateTypeCode_04": "3"
},
"DTM": [
{
"DateTimeQualifier_01": "050",
"Date_02": "20090102",
"Time_03": "0855",
"TimeCode_04": "ET"
}
],
"N1Loop": [
{
"N1": {
"EntityIdentifierCode_01": "SU",
"IdentificationCodeQualifier_03": "92",
"IdentificationCode_04": "43677"
}
}
],
"RCDLoop": [
{
"RCD": {
"QuantityinQuestion_06": "1",
"CompositeUnitofMeasure_07": {
"UnitorBasisforMeasurementCode_01": "EA"
},
"ReceivingConditionCode_08": "09"
},
"LIN": [
{
"ProductServiceIDQualifier_02": "BP",
"ProductServiceID_03": "U0070062"
}
],
"REF": [
{
"ReferenceIdentificationQualifier_01": "ACC",
"ReferenceIdentification_02": "A"
}
],
"DTM": [
{
"DateTimeQualifier_01": "945",
"Date_02": "20090102",
"Time_03": "0855",
"TimeCode_04": "ET"
}
]
}
],
"SE": {
"NumberofIncludedSegments_01": "9",
"TransactionSetControlNumber_02": "0002"
}
}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\ReceivingAdvice.txt")) using (var reader = new X12Reader(stream, "EdiFabric.Templates.X12")) { var items = await reader.ReadToEndAsync(); foreach (var transaction in items.OfType<TS861>()) { 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("ReceivingAdvice.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("ReceivingAdvice.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("ReceivingAdvice.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 '@ReceivingAdvice.txt'
Populate a TS861 object in .NET, or pass JSON in the shape shown above to ediFabric Native or ediFabric Cloud, and get a valid 861 file back.
using EdiFabric.Templates.X12004010; License.SetSerial("YOUR_SERIAL_KEY"); var transaction = new TS861(); // Transaction Set Identifier Code = “861” // (Receiving Advice / Acceptance Certificate) // Transaction Set Control Number = 0002 transaction.ST = new ST(); transaction.ST.TransactionSetIdentifierCode_01 = "861"; transaction.ST.TransactionSetControlNumber_02 = "0001"; // Reference Identification = C000548241 // Date = 02 / 24 / 2009 // Transaction Set Purpose Code = “00” (Original) // Receiving Advice or Acceptance Certificate // = “3” (Disposition Advice) transaction.BRA = new BRA(); transaction.BRA.ReferenceIdentification_01 = "C000548241"; transaction.BRA.Date_02 = "20090224"; transaction.BRA.TransactionSetPurposeCode_03 = "00"; transaction.BRA.ReceivingAdviceorAcceptanceCertificateTypeCode_04 = "3"; // 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("ReceivingAdvice.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("ReceivingAdvice.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("ReceivingAdvice.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 '@ReceivingAdvice.json' \ -o 'ReceivingAdvice.txt'
The 856 says what the supplier shipped. The 861 says what the customer received, so discrepancies, shortages and damage can be settled before or after invoicing.
Units received or accepted, units returned, units in question and the related conditions, each with a unit of measure.
It can document acceptance, but many trading partners still use carrier proof of delivery (214 or POD) alongside it.
In .NET, install EdiFabric and EdiFabric.Templates.X12, read the file with X12Reader into TS861 objects and write them back with X12Writer. From Python, Java or C, use ediFabric Native, which converts 861 files to JSON and JSON back to X12 inside your process. From any other language, post the file to the ediFabric Cloud REST API.