X12 404 Rail Carrier Shipment Information

The 404 is the X12 rail carrier shipment information - the electronic bill of lading for rail. Shippers send it to the railroad to tender a car or container for movement.

BX and BNX describe the shipment and payment, N7 loops the rail equipment, N1 loops the parties, and L5, L0 and hazardous material segments describe the lading.

At a glance

Standard
X12
Version
004010
Functional group
SR (GS01)
Sent by
Shipper to rail carrier
Responses
997
ediFabric .NET template
TS404 in EdiFabric.Templates.X12
OpenEDI definition
View 404 in the spec library

404 structure

The full X12 404 layout from its OpenEDI definition, the same model ediFabric uses to parse, validate and generate it: 14 loops and 88 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
ZC1Beginning Segment for Data Correction or ChangeOptional1
BXGeneral Shipment InformationOptional1
BNXRail Shipment InformationOptional1
M3ReleaseMandatory1
N9Reference IdentificationMandatory30
CMCargo ManifestOptional2
M1InsuranceOptional1
DTMDate/Time ReferenceOptional5
N7 loopEquipment DetailsMandatory500
N7Equipment DetailsMandatory1
EMEquipment CharacteristicsOptional1
VC loopMotor Vehicle ControlOptional21
VCMotor Vehicle ControlMandatory1
N1 loopNameOptional2
N1NameMandatory1
N3Address InformationOptional2
N4Geographic LocationOptional1
H3Special Handling InstructionsOptional1
M7Seal NumbersOptional5
N5Equipment OrderedOptional1
ICIntermodal Chassis EquipmentOptional1
IMIntermodal Movement InformationOptional1
M12In-bond Identifying InformationOptional2
E1 loopEmpty Car Disposition - Pended Destination ConsigneeOptional2
E1Empty Car Disposition - Pended Destination ConsigneeMandatory1
E4Empty Car Disposition - Pended Destination CityOptional1
E5Empty Car Disposition - Pended Destination RouteOptional13
PIPrice Authority IdentificationOptional1
GACanadian Grain InformationOptional15
REF loopReference IdentificationOptional99
REFReference IdentificationMandatory1
N10Quantity and DescriptionOptional15
N1 loopNameOptional5
N1NameMandatory1
N3Address InformationOptional1
N4Geographic LocationOptional1
NACross-Reference EquipmentOptional10
F9Origin StationMandatory1
D9Destination StationMandatory1
N1 loopNameMandatory10
N1NameMandatory1
N2Additional Name InformationOptional2
N3Address InformationOptional2
N4Geographic LocationOptional1
REFReference IdentificationOptional2
PERAdministrative Communications ContactOptional2
BLBilling InformationOptional12
S1 loopStop-off NameOptional12
S1Stop-off NameMandatory1
S2Stop-off AddressOptional2
S9Stop-off StationOptional1
N1NameOptional1
N2Additional Name InformationOptional1
N3Address InformationOptional1
N4Geographic LocationOptional1
PERAdministrative Communications ContactOptional1
R2Route InformationOptional13
R9Route Code IdentificationOptional1
E1 loopEmpty Car Disposition - Pended Destination ConsigneeOptional2
E1Empty Car Disposition - Pended Destination ConsigneeMandatory1
E4Empty Car Disposition - Pended Destination CityOptional1
E5Empty Car Disposition - Pended Destination RouteOptional13
PIPrice Authority IdentificationOptional1
H3Special Handling InstructionsOptional20
PSProtective Service InstructionsOptional5
LX loopAssigned NumberMandatory25
LXAssigned NumberMandatory1
L5Description, Marks and NumbersMandatory15
L0 loopLine Item - Quantity and WeightOptional25
L0Line Item - Quantity and WeightMandatory1
MEAMeasurementsOptional3
L1Rate and ChargesOptional10
PIPrice Authority IdentificationOptional30
X1Export LicenseOptional6
T1 loopTransit Inbound OriginOptional64
T1Transit Inbound OriginMandatory1
T2Transit Inbound LadingOptional30
T3Transit Inbound RouteOptional12
T6Transit Inbound RatesOptional1
T8Free-form Transit DataOptional99
L3Total Weight and ChargesOptional1
LS loopLoop HeaderOptional1
LSLoop HeaderMandatory1
LH1 loopHazardous Identification InformationOptional100
LH1Hazardous Identification InformationMandatory1
LH2Hazardous Classification InformationOptional4
LH3Hazardous Material Shipping NameOptional10
LFHFreeform Hazardous Material InformationOptional20
LEPEPA-Required DataOptional3
LH4Canadian Dangerous RequirementsOptional1
LHTTransborder Hazardous RequirementsOptional3
LHRHazardous Material Identifying Reference NumbersOptional5
PERAdministrative Communications ContactOptional5
LELoop TrailerMandatory1
PERAdministrative Communications ContactOptional5
LH2Hazardous Classification InformationOptional6
LHRHazardous Material Identifying Reference NumbersOptional1
LH6Hazardous CertificationOptional5
XHPro Forma - B13 InformationOptional1
X7Customs InformationOptional10
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 404 file

A rail bill of lading for one car with its lading. 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*404*0001~
BX*00*R*11**NS*L*B*N~
BNX*A**S~
M3*R*20000301*1116*LT~
N9*BM*2041247**20000301*1116*LT~
N7*CR*237522*80503*N*******RR~
M7*582127*582128~
F9**WARREN*MI~
D9**VALLEY PARK*MO~
N1*11*CORPAY SOLUTIONS~
N3*PO BOX 195199/2065 S CENTER RD~
N4*BURTON*MI*48519~
N1*CN*ST LOUIS ASSEMBLY I*93*04087~
N3*1001 N HIGHWAY DRIVE~
N4*FENTON*MO*63026~
N1*UC*ST LOUIS ASSEMBLY I*93*04087~
N3*1001 N HIGHWAY DRIVE~
N4*FENTON*MO*63026~
N1*SH*STERLING STAMPING*93*06215~
N3*35777 VAN DYKE RD~
N4*STERLING HEIGHTS*MI*48312~
R2*NS*R*ESTL~
R2*BNSF*1~
LX*1~
L5*1*AUTO PARTS*3714993*T~
L0*1***80503*N***42*RCK~
SE*27*0001~
GE*2*000000001~
IEA*1*000000263~

The same 404 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": "404",
    "TransactionSetControlNumber_02": "0001"
  },
  "BX": {
    "TransactionSetPurposeCode_01": "00",
    "TransportationMethodTypeCode_02": "R",
    "ShipmentMethodofPayment_03": "11",
    "StandardCarrierAlphaCode_05": "NS",
    "WeightUnitCode_06": "L",
    "ShipmentQualifier_07": "B",
    "SectionSevenCode_08": "N"
  },
  "BNX": {
    "ShipmentWeightCode_01": "A",
    "BillingCode_03": "S"
  },
  "M3": {
    "ReleaseCode_01": "R",
    "Date_02": "20000301",
    "Time_03": "1116",
    "TimeCode_04": "LT"
  },
  "N9": [
    {
      "ReferenceIdentificationQualifier_01": "BM",
      "ReferenceIdentification_02": "2041247",
      "Date_04": "20000301",
      "Time_05": "1116",
      "TimeCode_06": "LT"
    }
  ],
  "N7Loop": [
    {
      "N7": {
        "EquipmentInitial_01": "CR",
        "EquipmentNumber_02": "237522",
        "Weight_03": "80503",
        "WeightQualifier_04": "N",
        "EquipmentDescriptionCode_11": "RR"
      },
      "M7": [
        {
          "SealNumber_01": "582127",
          "SealNumber_02": "582128"
        }
      ]
    }
  ],
  "F9": {
    "CityName_02": "WARREN",
    "StateorProvinceCode_03": "MI"
  },
  "D9": {
    "CityName_02": "VALLEY PARK",
    "StateorProvinceCode_03": "MO"
  },
  "N1Loop": [
    {
      "N1": {
        "EntityIdentifierCode_01": "11",
        "Name_02": "CORPAY SOLUTIONS"
      },
      "N3": [
        {
          "AddressInformation_01": "PO BOX 195199/2065 S CENTER RD"
        }
      ],
      "N4": {
        "CityName_01": "BURTON",
        "StateorProvinceCode_02": "MI",
        "PostalCode_03": "48519"
      }
    },
    {
      "N1": {
        "EntityIdentifierCode_01": "CN",
        "Name_02": "ST LOUIS ASSEMBLY I",
        "IdentificationCodeQualifier_03": "93",
        "IdentificationCode_04": "04087"
      },
      "N3": [
        {
          "AddressInformation_01": "1001 N HIGHWAY DRIVE"
        }
      ],
      "N4": {
        "CityName_01": "FENTON",
        "StateorProvinceCode_02": "MO",
        "PostalCode_03": "63026"
      }
    },
    {
      "N1": {
        "EntityIdentifierCode_01": "UC",
        "Name_02": "ST LOUIS ASSEMBLY I",
        "IdentificationCodeQualifier_03": "93",
        "IdentificationCode_04": "04087"
      },
      "N3": [
        {
          "AddressInformation_01": "1001 N HIGHWAY DRIVE"
        }
      ],
      "N4": {
        "CityName_01": "FENTON",
        "StateorProvinceCode_02": "MO",
        "PostalCode_03": "63026"
      }
    },
    {
      "N1": {
        "EntityIdentifierCode_01": "SH",
        "Name_02": "STERLING STAMPING",
        "IdentificationCodeQualifier_03": "93",
        "IdentificationCode_04": "06215"
      },
      "N3": [
        {
          "AddressInformation_01": "35777 VAN DYKE RD"
        }
      ],
      "N4": {
        "CityName_01": "STERLING HEIGHTS",
        "StateorProvinceCode_02": "MI",
        "PostalCode_03": "48312"
      }
    }
  ],
  "R2": [
    {
      "StandardCarrierAlphaCode_01": "NS",
      "RoutingSequenceCode_02": "R",
      "CityName_03": "ESTL"
    },
    {
      "StandardCarrierAlphaCode_01": "BNSF",
      "RoutingSequenceCode_02": "1"
    }
  ],
  "LXLoop": [
    {
      "LX": {
        "AssignedNumber_01": "1"
      },
      "L5": [
        {
          "LadingLineItemNumber_01": "1",
          "LadingDescription_02": "AUTO PARTS",
          "CommodityCode_03": "3714993",
          "CommodityCodeQualifier_04": "T"
        }
      ],
      "L0Loop": [
        {
          "L0": {
            "LadingLineItemNumber_01": "1",
            "Weight_04": "80503",
            "WeightQualifier_05": "N",
            "LadingQuantity_08": "42",
            "PackagingFormCode_09": "RCK"
          }
        }
      ]
    }
  ],
  "SE": {
    "NumberofIncludedSegments_01": "27",
    "TransactionSetControlNumber_02": "0001"
  }
}

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

Generate a 404 file

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

using EdiFabric.Templates.X12004010;

License.SetSerial("YOUR_SERIAL_KEY");

var transaction = new TS404();

//  Transaction Set Identifier Code
//  = “404” (Rail Carrier Shipment Information)
//  Transaction Set Control Number = 0001
transaction.ST = new ST();
transaction.ST.TransactionSetIdentifierCode_01 = "404";
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("RailCarrierShipment.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("RailCarrierShipment.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("RailCarrierShipment.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 '@RailCarrierShipment.json' \
-o 'RailCarrierShipment.txt'

404 questions

Is the 404 the rail bill of lading?

Yes. It carries the same information as the paper bill of lading and is how rail shipments are tendered electronically in North America.

How is hazardous material described?

With the LH1, LH2, LH3 and LH4 segments and the emergency contact information required for rail.

How is the equipment identified?

N7 carries the equipment initial and number (for example a railcar mark), with weights and seal numbers in related segments.

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

In .NET, install EdiFabric and EdiFabric.Templates.X12, read the file with X12Reader into TS404 objects and write them back with X12Writer. From Python, Java or C, use ediFabric Native, which converts 404 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 404 in five minutes

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