Processing Inbound EDI
In much the same way that modern programming languages like Ruby and Typescript have abstracted away the need to write computer programs in assembly language, modern platforms like Tediware abstract away the need to deal with X12 EDI.
Instead of parsing and generating X12 EDI, Tediware translates EDI into JSON and back again.
This makes dealing with inbound EDI much easier. Let's take another look at the 990 Response to Load Tender from before. Here's what it looks like translated to JSON.
GF 990 Response To Load Tender - Accepted
EDI
ISA*00* *00* *ZZ*ACME *ZZ*WALDO *250303*1506*U*00401*000000052*0*P*:~ GS*GF*ACME*WALDO*20250303*1506*52*X*004010~ ST*990*00000052~ B1*ACME*339807*20250301*A~ N9*CN*ACM12345~ SE*4*00000052~ GE*1*52~ IEA*1*000000052~
JSON
{
"heading": {
"transaction_set_header_ST": {
"transaction_set_identifier_code_01": "response_to_a_load_tender_990",
"transaction_set_control_number_02": "00000052"
},
"beginning_segment_for_booking_or_pick_up_delivery_B1": {
"standard_carrier_alpha_code_01": "ACME",
"shipment_identification_number_02": "339807",
"date_03": "20250301",
"reservation_action_code_04": "reservation_accepted_A"
},
"reference_identification_N9": {
"reference_identification_qualifier_01": "carriers_reference_number_pro_invoice_CN",
"reference_identification_02": "ACM12345"
},
"transaction_set_trailer_SE": {
"number_of_included_segments_01": 4,
"transaction_set_control_number_02": "00000052"
}
}
}
Annotated
Interchange Control Header
ISA*00* *00* *ZZ*ACME *ZZ*WALDO *250303*1506*U*00401*000000052*0*P*:~
| Position | Value | Name | Meaning |
|---|---|---|---|
| ISA-01 | 00 | Authorization Information Qualifier | No authorization information present |
| ISA-02 | Authorization Information | Blank (not used) | |
| ISA-03 | 00 | Security Information Qualifier | No security information present |
| ISA-04 | Security Information | Blank (not used) | |
| ISA-05 | ZZ | Interchange ID Qualifier (Sender) | Mutually defined |
| ISA-06 | ACME | Interchange Sender ID | |
| ISA-07 | ZZ | Interchange ID Qualifier (Receiver) | Mutually defined |
| ISA-08 | WALDO | Interchange Receiver ID | |
| ISA-09 | 250303 | Interchange Date | |
| ISA-10 | 1506 | Interchange Time | |
| ISA-11 | U | Repetition Separator | |
| ISA-12 | 00401 | Interchange Control Version Number | X12 release 004010 |
| ISA-13 | 000000052 | Interchange Control Number | |
| ISA-14 | 0 | Acknowledgment Requested | No acknowledgment requested |
| ISA-15 | P | Usage Indicator | Production data |
| ISA-16 | : | Component Element Separator |
Functional Group Header
GS*GF*ACME*WALDO*20250303*1506*52*X*004010~
| Position | Value | Name | Meaning |
|---|---|---|---|
| GS-01 | GF | Functional Identifier Code | Response to a Load Tender -- identifies this group as containing 990 documents |
| GS-02 | ACME | Application Sender's Code | |
| GS-03 | WALDO | Application Receiver's Code | |
| GS-04 | 20250303 | Date | |
| GS-05 | 1506 | Time | |
| GS-06 | 52 | Group Control Number | |
| GS-07 | X | Responsible Agency Code | Accredited Standards Committee X12 |
| GS-08 | 004010 | Version / Release / Industry Identifier Code |
Transaction Set Header
ST*990*00000052~
| Position | Value | Name | Meaning |
|---|---|---|---|
| ST-01 | 990 | Transaction Set Identifier Code | Response to a Load Tender |
| ST-02 | 00000052 | Transaction Set Control Number |
Beginning Segment for Booking or Pick-up/Delivery
B1*ACME*339807*20250301*A~
| Position | Value | Name | Meaning |
|---|---|---|---|
| B1-01 | ACME | Standard Carrier Alpha Code | |
| B1-02 | 339807 | Shipment Identification Number | |
| B1-03 | 20250301 | Date | |
| B1-04 | A | Reservation Action Code | A = Reservation Accepted |
Extended Reference Information
N9*CN*ACM12345~
| Position | Value | Name | Meaning |
|---|---|---|---|
| N9-01 | CN | Reference Identification Qualifier | Carrier's Reference Number (PRO/Invoice) |
| N9-02 | ACM12345 | Reference Identification |
Transaction Set Trailer
SE*4*00000052~
| Position | Value | Name | Meaning |
|---|---|---|---|
| SE-01 | 4 | Number of Included Segments | |
| SE-02 | 00000052 | Transaction Set Control Number |
Functional Group Trailer
GE*1*52~
| Position | Value | Name | Meaning |
|---|---|---|---|
| GE-01 | 1 | Number of Transaction Sets Included | |
| GE-02 | 52 | Group Control Number |
Interchange Control Trailer
IEA*1*000000052~
| Position | Value | Name | Meaning |
|---|---|---|---|
| IEA-01 | 1 | Number of Included Functional Groups | |
| IEA-02 | 000000052 | Interchange Control Number |
There are a few things worth noting about this JSON representation.
First, not every is included: the ISA, GS, GE and IEA segments are not present. These are part of the EDI file's , which we will discuss later. What you are viewing is the JSON translation of the , which is the "meat" of the document.
Second, one of the great drawbacks of the X12 EDI format - and one of the most difficult things about dealing with it - has been resolved: the document now contains information about what the keys and the values mean.
Instead of B1 we have beginning_segment_for_booking_or_pick_up_delivery_B1. Instead of A we have reservation_accepted_A. This makes it far easier to understand. It's also lossless: if we want the original X12 keys or values, we can extract them by splitting on the underscore.
With the EDI file translated as JSON, we can use familiar patterns to find data, extract values, iterate through structures and so on.
Finding Data
To check whether this 990 was accepted or declined, we just navigate to the relevant key:
const actionCode =
doc.heading
.beginning_segment_for_booking_or_pick_up_delivery_B1
.reservation_action_code_04;
// "reservation_accepted_A"
Extracting Values
Since the translated values encode the original X12 code after the last underscore, we can extract it when needed:
const rawCode = actionCode.split("_").pop();
// "A"
const shipmentNumber =
doc.heading
.beginning_segment_for_booking_or_pick_up_delivery_B1
.shipment_identification_number_02;
// "339807"
Iteration
The 990 is a simple document, but more complex transaction sets contain : repeating groups of segments. In JSON, these become arrays that you can iterate over with standard tools:
204 View the 204 in the X12 Reference// A 204 Load Tender might contain multiple stops:
for (const stop of doc.detail.stop_off_details_S5_loop) {
const city = stop.geographic_location_N4?.city_name_01;
const state = stop.geographic_location_N4?.state_or_province_code_02;
console.log("Stop: " + city + ", " + state);
}
Try It Yourself
Paste any raw EDI content below to see it translated to JSON. Note that only the first transaction set will be shown, and the envelope will not be included. We'll discuss this more when we review how envelopes work.
Translate EDI to JSON
Paste raw X12 EDI here to see it translated to JSON. Requires JavaScript.