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

ISA

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
GS

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
ST

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
B1

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
N9

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
SE

Transaction Set Trailer

SE*4*00000052~

Position Value Name Meaning
SE-01 4 Number of Included Segments
SE-02 00000052 Transaction Set Control Number
GE

Functional Group Trailer

GE*1*52~

Position Value Name Meaning
GE-01 1 Number of Transaction Sets Included
GE-02 52 Group Control Number
IEA

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.