The 945 is the X12 warehouse shipping advice. A third-party warehouse sends it to the depositor - the owner of the goods - to confirm that an order was shipped.
It answers a 940 warehouse shipping order: W06 identifies the shipment and depositor order, N1 loops the parties, W27 the carrier, and LX loops with W12 segments report what was shipped per item.
004010SW (GS01)TS945 in EdiFabric.Templates.X12The full X12 945 layout from its OpenEDI definition, the same model ediFabric uses to parse, validate and generate it: 9 loops and 47 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 |
W06 | Warehouse Shipment Identification | Mandatory | 1 |
| N1 loop | Name | Mandatory | 10 |
N1 | Name | Mandatory | 1 |
N2 | Additional Name Information | Optional | 1 |
N3 | Address Information | Optional | 2 |
N4 | Geographic Location | Optional | 1 |
PER | Administrative Communications Contact | Optional | 5 |
N9 | Reference Identification | Optional | 10 |
G61 | Contact | Optional | 3 |
G62 | Date/Time | Optional | 5 |
NTE | Note/Special Instruction | Optional | 20 |
W27 | Carrier Detail | Optional | 1 |
W6 | Special Handling Code, Special Handling Code, Special Handling Code | Optional | 1 |
W28 | Consolidation Information | Optional | 1 |
W10 | Unit Load Detail | Optional | 10 |
G72 | Allowance or Charge | Optional | 5 |
| LM loop | Code Source Information | Optional | 10 |
LM | Code Source Information | Mandatory | 1 |
LQ | Industry Code | Mandatory | 100 |
| LX loop | Assigned Number | Optional | >1 |
LX | Assigned Number | Mandatory | 1 |
MAN | Marks and Numbers | Optional | >1 |
PAL | Pallet Information | Optional | 1 |
N9 | Reference Identification | Optional | 5 |
| W12 loop | Warehouse Item Detail | Optional | >1 |
W12 | Warehouse Item Detail | Mandatory | 1 |
G69 | Line Item Detail - Description | Optional | 5 |
N9 | Reference Identification | Optional | 200 |
G62 | Date/Time | Optional | 10 |
QTY | Quantity | Optional | 10 |
MEA | Measurements | Optional | 5 |
AMT | Monetary Amount | Optional | 1 |
R4 | Port or Terminal | Optional | 5 |
W27 | Carrier Detail | Optional | 1 |
N1 | Name | Optional | 5 |
G72 | Allowance or Charge | Optional | 5 |
| LM loop | Code Source Information | Optional | 10 |
LM | Code Source Information | Mandatory | 1 |
LQ | Industry Code | Mandatory | 100 |
| LS loop | Loop Header | Optional | 1 |
LS | Loop Header | Mandatory | 1 |
| LX loop | Assigned Number | Optional | >1 |
LX | Assigned Number | Mandatory | 1 |
N9 | Reference Identification | Optional | >1 |
G62 | Date/Time | Optional | 10 |
N1 | Name | Optional | 1 |
| LM loop | Code Source Information | Optional | 10 |
LM | Code Source Information | Mandatory | 1 |
LQ | Industry Code | Mandatory | 100 |
LE | Loop Trailer | Mandatory | 1 |
| FA1 loop | Type of Financial Accounting Data | Optional | >1 |
FA1 | Type of Financial Accounting Data | Mandatory | 1 |
FA2 | Accounting Data | Mandatory | >1 |
W03 | Total Shipment Information | 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 shipping advice for one depositor order with item details. 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*945*0001~ W06*X*12345*CCYYMMDD*123456*1234**01*9999****Z~ N1*WH*Warehouse Name*9*123456~ N1*DE*Depositor Name*9*0123456789000~ N9*SN*Seal Number~ N9*ZZ*Temperature Recording Device Number~ W27*H*TRUK*TRUCKING*CC***Equipment ID~ LX*1~ W12*CC*72*72**CA*007117901645*UK*10071179016458*40550*799*G*L~ G69*Some description~ N9*LI*1000~ N9*PC*989JAN281301~ N9*LV*00100752782101847618*36~ N9*LV*00100752782101847619*36~ LX*2~ W12*CC*72*72**CA*007117901645*UK*10071179016458*40551*884*G*L~ G69*Some description~ N9*LI*1000~ N9*PC*989JAN291301~ N9*LV*00100752782101847620*72~ W03*240*15360*LB~ SE*22*0001~ 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": "945",
"TransactionSetControlNumber_02": "0001"
},
"W06": {
"ReportingCode_01": "X",
"DepositorOrderNumber_02": "12345",
"Date_03": "CCYYMMDD",
"ShipmentIdentificationNumber_04": "123456",
"AgentShipmentIDNumber_05": "1234",
"MasterReferenceLinkNumber_07": "01",
"LinkSequenceNumber_08": "9999",
"ActionCode_12": "Z"
},
"N1Loop": [
{
"N1": {
"EntityIdentifierCode_01": "WH",
"Name_02": "Warehouse Name",
"IdentificationCodeQualifier_03": "9",
"IdentificationCode_04": "123456"
}
},
{
"N1": {
"EntityIdentifierCode_01": "DE",
"Name_02": "Depositor Name",
"IdentificationCodeQualifier_03": "9",
"IdentificationCode_04": "0123456789000"
}
}
],
"N9": [
{
"ReferenceIdentificationQualifier_01": "SN",
"ReferenceIdentification_02": "Seal Number"
},
{
"ReferenceIdentificationQualifier_01": "ZZ",
"ReferenceIdentification_02": "Temperature Recording Device Number"
}
],
"W27": {
"TransportationMethodTypeCode_01": "H",
"StandardCarrierAlphaCode_02": "TRUK",
"Routing_03": "TRUCKING",
"ShipmentMethodofPayment_04": "CC",
"EquipmentNumber_07": "Equipment ID"
},
"LXLoop": [
{
"LX": {
"AssignedNumber_01": "1"
},
"W12Loop": [
{
"W12": {
"ShipmentOrderStatusCode_01": "CC",
"QuantityOrdered_02": "72",
"NumberofUnitsShipped_03": "72",
"UnitorBasisforMeasurementCode_05": "CA",
"UPCCaseCode_06": "007117901645",
"ProductServiceIDQualifier_07": "UK",
"ProductServiceID_08": "10071179016458",
"WarehouseLotNumber_09": "40550",
"Weight_10": "799",
"WeightQualifier_11": "G",
"WeightUnitCode_12": "L"
},
"G69": [
{
"FreeformDescription_01": "Some description"
}
],
"N9": [
{
"ReferenceIdentificationQualifier_01": "LI",
"ReferenceIdentification_02": "1000"
},
{
"ReferenceIdentificationQualifier_01": "PC",
"ReferenceIdentification_02": "989JAN281301"
},
{
"ReferenceIdentificationQualifier_01": "LV",
"ReferenceIdentification_02": "00100752782101847618",
"FreeformDescription_03": "36"
},
{
"ReferenceIdentificationQualifier_01": "LV",
"ReferenceIdentification_02": "00100752782101847619",
"FreeformDescription_03": "36"
}
]
}
]
},
{
"LX": {
"AssignedNumber_01": "2"
},
"W12Loop": [
{
"W12": {
"ShipmentOrderStatusCode_01": "CC",
"QuantityOrdered_02": "72",
"NumberofUnitsShipped_03": "72",
"UnitorBasisforMeasurementCode_05": "CA",
"UPCCaseCode_06": "007117901645",
"ProductServiceIDQualifier_07": "UK",
"ProductServiceID_08": "10071179016458",
"WarehouseLotNumber_09": "40551",
"Weight_10": "884",
"WeightQualifier_11": "G",
"WeightUnitCode_12": "L"
},
"G69": [
{
"FreeformDescription_01": "Some description"
}
],
"N9": [
{
"ReferenceIdentificationQualifier_01": "LI",
"ReferenceIdentification_02": "1000"
},
{
"ReferenceIdentificationQualifier_01": "PC",
"ReferenceIdentification_02": "989JAN291301"
},
{
"ReferenceIdentificationQualifier_01": "LV",
"ReferenceIdentification_02": "00100752782101847620",
"FreeformDescription_03": "72"
}
]
}
]
}
],
"W03": {
"NumberofUnitsShipped_01": "240",
"Weight_02": "15360",
"UnitorBasisforMeasurementCode_03": "LB"
},
"SE": {
"NumberofIncludedSegments_01": "22",
"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\WarehouseShippingAdvice.txt")) using (var reader = new X12Reader(stream, "EdiFabric.Templates.X12")) { var items = await reader.ReadToEndAsync(); foreach (var transaction in items.OfType<TS945>()) { 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("WarehouseShippingAdvice.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("WarehouseShippingAdvice.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("WarehouseShippingAdvice.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 '@WarehouseShippingAdvice.txt'
Populate a TS945 object in .NET, or pass JSON in the shape shown above to ediFabric Native or ediFabric Cloud, and get a valid 945 file back.
using EdiFabric.Templates.X12004010; License.SetSerial("YOUR_SERIAL_KEY"); var transaction = new TS945(); // Transaction Set Identifier Code = "945" // (Receiving Advice / Acceptance Certificate) // Transaction Set Control Number = 0002 transaction.ST = new ST(); transaction.ST.TransactionSetIdentifierCode_01 = "945"; transaction.ST.TransactionSetControlNumber_02 = "0001"; // ... 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("WarehouseShippingAdvice.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("WarehouseShippingAdvice.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("WarehouseShippingAdvice.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 '@WarehouseShippingAdvice.json' \ -o 'WarehouseShippingAdvice.txt'
The 940 is the depositor's instruction to ship an order. The 945 is the warehouse's confirmation of what was actually shipped.
W12 carries the quantity ordered, the quantity shipped and the difference for each item.
The 945 goes to the owner of the goods. The 856 goes to the customer receiving them, and is often generated from the same data.
In .NET, install EdiFabric and EdiFabric.Templates.X12, read the file with X12Reader into TS945 objects and write them back with X12Writer. From Python, Java or C, use ediFabric Native, which converts 945 files to JSON and JSON back to X12 inside your process. From any other language, post the file to the ediFabric Cloud REST API.