? Base Standard JSON
X12 Logo

Constructing Base Standard JSON Schema Definition from X12 EDI Metadata

SEPTEMBER 2024

Abstract

A description of a methodology for constructing JSON schemas written in JSON Draft version 2020-12 from X12 EDI metadata.

1. Preface

1.1 General

This document is a Technical Report Type 4 (TR4), commonly referred to as a Clarification Paper. This TR4 was prepared under the guidance of the Accredited Standards Committee (ASC) on Electronic Data Interchange, X12. Organized under the procedures of the American National Standards Institute, X12 was charged with the development of transactions and structures for use in an Electronic Data Interchange (EDI) environment. X12 has the following subcommittees:

  • X12C Communications and Controls
  • X12F Finance
  • X12I Transportation
  • X12J Technical Assessment
  • X12M Supply Chain
  • X12N Insurance

This TR4 was developed by X12C.

1.2 Version and Release

This TR4 is not based on or dependent on any particular version/release of the X12 EDI Standards referenced. The information is useful for end users regardless of which version/release of the standards.

1.3 Comments

Comments, questions, and suggestions for improvement of this document may be submitted via email to info@x12.org.

2. Purpose and Scope

This TR4 describes a methodology to standardize the equivalent JSON Schema format for Accredited Standards Committee (ASC) X12 implementation of Electronic Data Interchange (EDI) document definitions. This TR4 advises on best practice for creation of JSON Schemas based on X12 so that implementations for purposes of API and general-purpose document formatting both stay true to the X12 standards as defined but also adjust to fully leverage this TR4 where it makes sense to do so.

2.1 Related X12 Standards

 

  • Transaction Sets (X12.1)
  • Data Element Dictionary (X12.3)
  • Interchange Control Structure (X12.5)
  • Application Control Structure (X12.6)
  • Segment Directory (X12.22)

3. Definitions and Concepts

3.1 JSON Schema version

JSON Schema 2020-12 and OpenAPI 3.1 fully support interoperability so for the purposes of this definition JSON Draft version 2020-12 is used in line with maximizing the usability of X12 JSON for REST API style exchanges. Older JSON Schema versions may still be used with the same syntax and notation, but certain compatibility issue with OpenAPI and advances use cases can be lost along the way, so this is not suggested.

3.2 JSON Schema Syntactical Notation

To achieve maximum X12 and JSON Schema parity and consistency across definitions certain notations and best practices must be established.

3.2.2 Descriptive and non-Descriptive Variations

X12 has always been a compact and concise standard for B2B and computer to computer communication with minimal need for human interaction. Modern JSON Rest API practice has moved a bit more in a descriptive direction for its definitions. Neither is clearly more correct, and each have their respective pros and cons. This X12 JSON Schema definitions seeks to balance between these options. You will see examples given in both contexts.

To keep human readable descriptions consistent the following rules should be applied:

  1. Only Alpha and Numeric characters are preserved, all others will be replaced by spaces.
  2. Multiple spaces will be consolidated.
  3. Spaces will then be removed, and the names converted to an upper camel case, meaning the first character and any subsequent character that would have followed a space will be upper case and all others will be lower case.

Note that Descriptions will not be used for definitions instead a suffix covered below will be added to the end of definitions defined using descriptive notation, this will allow for JSON Schema Definitions to have both Descriptive and non-Descriptive elements in a common definition if so desired.

3.2.3 Definition Identifiers, Prefixes, and Suffixes

The use of a short prefix was selected for two reasons. The first is that the JSON standard does not permit keys to start with non-alpha characters, this eliminates that problem. This is especially important with Document number and data element numbers as numbers only.

3.2.3.1 Definition Prefix

JSON Schema supports the ability to identify an element in one place and reference it's definition in another place to clearly delineate which is which a definition prefix of "DEF-" is used on the reference and definition names to keep them distinguished from the actual node name.

3.2.3.2 Descriptive Definition Suffix

As covered above descriptive node names are optional and when sent will have the "_Desc" suffix added to their definition name.

3.2.3.3 Message/Transaction Set Identifier

X12 Message/Transaction Set will be identified using its number as identified in Data Element 143 for instance a PO would be 850, Load Tender would be 204.

3.2.3.4 Message/Transaction Set Prefix

X12 Message prefix will be "M_" followed by the message/transaction set identifier.

"M_204"
"M_204_MotorCarrierLoadTender"

These would be defined respectively like so:

"DEF-M_204"
"DEF-M_204_Desc"

3.2.4.5 Group/Loop Identifier

The X12 Group/Loop will be uniquely identifier by combining the Transaction Set Identifier, the table, and position concatenated by hyphens (-) for instance the PO Header Name/Address loop would be 850-1-3100 while the Load Tender Stop off loop would be 204-2-0100, as defined in 008010.

This format is compatible with X12 pre-004032 where position length was extended.

3.2.4.6 Group/Loop Prefix

The X12 Group/Loop Prefix will be "G_" followed by the Group/Loop Identifier. (Note: Group/Loop do not receive descriptive text.)

"G_204-2-0100"

This would be defined based on if the group contains descriptive segments or not as follows:

"DEF-G_204-1-1100"
"DEF-G_204-1-1100_Desc"

3.2.4.7 Segment Identifier

A X12 Segment will be identified using the tag name found in the X12.22 Segment Directory.

3.2.4.8 Segment Prefix

The X12 Segment Prefix will be "S_" followed by the Segment Identifier.

"S_N1"
"S_N1_PartyIdentification"

This would be defined respectively like so:

"DEF-S_N1"
"DEF-S_N1_Desc"

3.2.4.9 Composite Data Element Identifier

The X12 Composite Prefix will be "C_" followed by the Segment Identifier followed by the Reference Designator identifier.

"C_MEA04"
"C_MEA04_CompositeUnitOfMeasure"

For the given example the object definition name would be:

"DEF-C_C001"
"DEF-C_C001_Desc"

3.2.4.10 Element Data Element Identifier

The X12 Element Prefix will be "E_" followed by the Segment/Component Identifier followed by the Reference Designator identifier. In addition, Element definitions used the "DE_" prefix followed by the Data Element number defined in the Data Element Dictionary (X12.3).

"E_N101"
"E_N101_EntityIdentifierCode"
"E_C00101"
"E_C00101_UnitOrBasisForMeasurementCode"

For the given example the object definition name would be:

"DEF-DE_98"
"DEF-DE_98_Desc"
"DEF-DE_355"
"DEF-DE_355_Desc"

3.2.4.11 Code List Prefix

The identifier for a code list will be "CL_" what follows depends on the use case that is applicable. The most common use case is referencing the Code List as part of a data element "allOf" reference to a code list, as the main data element will reference the data element's data type covered below. For these references the Code list qualifier would be followed by the code list's X12 version, this allows for upgrading code list versions independent of document version like ISX, as well as the data element of the code list which should match the data element it's associated with as follows:

"DEF-CL_005010_40"
"DEF-G_214-2-0800_S_MS203_CL_005010_40"

Code lists will typically only appear as definitions not elements with one exception which is the second use case Composite code lists. Data element 103 is the primary example of this and in this scenario the Data Element will become an object with multiple objects as properties and in this scenario the Code List prefix will be followed by the data element number followed by the sequence of the Code List within the composite. That sequence also becomes part of the Code List definition for referencing.

"CL_103_1"
"CL_103_2"

These would be defined as:

"CL_008010_103_1"
"CL_008010_103_2"

3.2.4.12 Data Type Prefix

For defining Data Elements by their data type the prefix "DataType_" will be used. This is typically followed by the Data Type identifier and where applicable the min and max length. More detail on the specifics for this are covered below in section 11.

"DataType_ID2-2"
"DataType_AN1-30"
"DataType_N0_1-3"
"DataType_R"
"DataType_DT"
"DataType_TM"

3.2.4.13 External Code list definition

Many X12 elements reference external code lists that might be pulled into a Document from an outside authoritative source for these use the prefix "Ext_CL_". An example of this would be for Country Sub-Divisions as defined by ISO standards for instance, data element 1715 would be commonly seen as N407 for context:

"Ext_CL_1715_ISO3166-2_2020"

3.2.4.14 Mutually Defined

X12 has traditionally allowed for the short-term addition of non-standardized segments, elements, and codes while the process of getting those codes officially recognized and, in the meantime, a "Z" mutually defined qualifier is used. At other times these could also be used for internal meta data extending an X12 JSON document, for instance adding a document receipt date-time for an X12 document. For JSON notation this is accomplished with a prefix "Z_". If this is not an internal use case mutually defined should only be used as a short term stand in while a formal X12 request is requested and reviewed, if accepted and added then switching that elements code list to the new version should be relatively non-impacting compared to a full X12 version upgrade in the traditional X12 space.

"Z_GenerateDateTime"
"Z_EnvelopeId"

Note: Before using a mutually defined prefix always ensure that the element you are seeking doesn't already exist somewhere else in the document and that you are using the correct X12 document for your use case.

4. JSON Header syntax

The JSON definition should contain a URI in the header "$id" tags like so:

"$id": "http://json.x12.org/008010/204#"

Note: This is a URI not necessarily a URL this allows for JSON Schemas to reference one another to build or externalize data. For instance, code lists for a document could be defined in their own document and referenced. If all the code list for an 008010 204 were defined with an $id like so:

"$id": "http://json.x12.org/008010/CL_204#"

Then the 204 document could reference them by URI like so:

"$ref": "http://json.x12.org/008010/CL_204#/$defs/DEF-CL_008010_163"

5. Root properties definition

Typically, more elements are defined within the $defs section with only the root element or elements being defined in the header "properties" like so:

"$schema": "https://json-schema.org/draft/2020-12/schema#",
"$id": "http://json.x12.org/008010/204#",
"title": "X12 - 008010 - 204",
"type": "object",
"properties": {
  "M_204": {
   "$ref": "#/$defs/DEF-M_204"
  }
},
"items": false,
"required": ["M_204"],

It is possible to also include multiple messages in a single transaction the use case for this is rare but for something like an EFT which can contain a control and remit message pair which would look like the following:

"$schema": "https://json-schema.org/draft/2020-12/schema#",
"$id": "http://json.x12.org/008010/204#",
"title": "X12 - 008010 - 204",
"type": "object",
"properties": {
  "M_831": {
   "$ref": "http://json.x12.org/008010/831#/$defs/DEF-M_831"
  }
},
  "M_820": {
   "$ref": "http://json.x12.org/008010/820#/$defs/DEF-M_820"
  }
},
"items": false,
"required": ["M_820"],

6. Restriction on additional items

For pretty much all X12 use cases no additional elements not defined within the schema should be allowed. This means pretty much every "properties" section should be followed by the following to prevent non-defined elements from being included:

"items": false,

7. Human Readability of JSON Schema

Especially when the Message, Segment, Component, and Element Name are not included in their JSON key name it can still be helpful for developers to include the name and description for these with the JSON Schema definition. For this the JSON Schema "title" should be used for the name and "description" should be used for the description like so:

"title" : "Composite Unit of Measure",
"description" : "To identify a composite unit of measure\n\n(See Figures Appendix for examples of use)",

Note: Proper JSON character escaping should be used for instance the New Line in the example description became \n which does preserve them for other uses like using a JSON combined with a JSON Schema to return Human Readable output.

8. Handling of Mandatory elements

If an element within a Message, Group, Segment, or Composite is required then they should be listed withing the "required" definition following the "properties" and "items" keys like so:

"required" : [ "E_CUR01", "E_CUR02" ]
"required" : [ "E_CUR01_EntityIdentifierCode", "E_CUR02_CurrencyCode" ]

9. The handling of Relational Conditions

Each of the scenarios defined by Application Control Structure (X12.6) ยง 3.7.3.2.3 Relational Conditions is fully supported by JSON Schema either through the use of "oneOf" or "dependencies" definitions, sometimes extended by "allOf" or "anyOf"

9.1 (R) Required

(R) Required

"At least one of the <subj_elem> specified in the <relational_cond> must be present." For this a "anyOf" is added to the Segment or Composite definition. This would look like this:

"anyOf" : [ {
  "required" : [ "E_DTM02" ]
}, {
  "required" : [ "E_DTM03" ]
}, {
  "required" : [ "E_DTM05" ]
} ],

"anyOf" : [
{
  "required" : [ "E_DTM02_Date" ]
}, {
  "required" : [ "E_DTM03_Time" ]
}, {
  "required" : [ "E_DTM05_DateTimePeriodFormatQualifier" ]
} ],

Note: If a Segment or Component has more than one "Required" condition the "anyOf" sections need to be wrapped in a parent "allOf" section.

9.2 Handling overlapping of Relational Condition

All Relational Conditions excluding the "Required" condition will use the JSON Schema "dependencies" it is important for JSON Schema best practice to only list a triggering dependency only once so within a dependency a Component/Element should only be listed once and then all applicable Relational Conditions should be listed within the "allOf" array.

9.3 (P) Paired or Multiple

"If any <subj_elem> specified in the <relational_cond> is present, then all of the <subj_elem> specified must be present." This is implemented via dependencies where all elements in the rule are listed and reference all other members of that Pair/Multiple accept themselves as required when present. The L11 rule of P0102 would look like the following:

"dependencies": {
  "E_L1101": {
    "allOf": [
      {
        "required": [ "E_L1102" ]
      }
    ]
  },
  "E_L1102": {
    "allOf": [
      {
        "required": [ "E_L1101" ]
      }
    ]
  }
}
"dependencies": {
  "E_L1101_ReferenceIdentification": {
    "allOf": [
      {
        "required": [ "E_L1102_ReferenceIdentificationQualifier" ]
      }
    ]
  },
  "E_L1102_ReferenceIdentificationQualifier": {
    "allOf": [
      {
        "required": [ "E_L1101_ReferenceIdentification" ]
      }
    ]
  }
}

The above is carry over from 2019-09 and earlier, starting with 2020-12 the schema would be more compact and better aligned with standard if "dependentRequired" is used instead this would look like the following:

"dependentRequired": {
  "E_L1101": [ "E_L1102" ],
  "E_L1102": [ "E_L1101" ]
}

" dependentRequired ": {
  "E_L1101_ReferenceIdentification": 
[ "E_L1102_ReferenceIdentificationQualifier" ],
  "E_L1102_ReferenceIdentificationQualifier": 
[ "E_L1101_ReferenceIdentification" ]
}

9.4 (E) Exclusion

"Not more than one of the <subj_elem> specified in the <relational_cond> may be present." This is implemented via dependencies these are implemented like Paired/Multiple but with a "not" condition to invert the required check. A N4 segment rule of E0207 would look like the following.

Note: The N407 also has a C0704 rule so the N404 reference is part of another condition.

"dependencies": {
  "E_N402": {
    "allOf": [
      {
        "not": {
          "required": [ "E_N407" ]
        }
      }
    ]
  },
   "E_N407": {
     "allOf": [
       {
         "not": {
           "required": [ "E_N402" ]
         }
       },
       {
         "required": [ "E_N404" ]
       }

     ]
   }, 
}
"dependencies": {
  "E_N402_StateOrProvinceCode": {
    "allOf": [
      {
        "not": {
          "required": [ "E_N407_CountrySubdivisionCode" ]
        }
      }
    ]
  },
   "E_N407_CountrySubdivisionCode": {
     "allOf": [
       {
         "not": {
           "required": [ "E_N402_StateOrProvinceCode"  ]
         }
       },
       {
         "required": [ "E_N404_CountryCode" ]
       }
     ]
   },
}

9.5 (C) Conditional

"If the first <subj_elem> specified in the <relational_cond> is present, then all other <subj_elem> must be present. However, any or all of the <subj_elem> NOT specified as the FIRST <subj_elem> in the <relational_cond> may appear when the first <subj_elem> is not present. The order of the <subj_elem> in the <relational_cond> does not have to be the same as the order of the data elements in the data segment." For this the dependency will be listed only under the first element listed and reference all others. A N4 segment with rule C0704 would look list the following.

Note: The N407 also has a E0207 rule so the N402 reference is part of another condition.

"dependencies": {
   "E_N407": {
     "allOf": [
       {
         "not": {
           "required": [ "E_N402" ]
         }
       },
       {
         "required": [ "E_N404" ]
       }
     ]
   }, 
}
"dependencies": {
   "E_N407_CountrySubdivisionCode": {
     "allOf": [
       {
         "not": {
           "required": [ "E_N402_StateOrProvinceCode" ]
         }
       },
       {
         "required": [ "E_N404_CountryCode" ]
       }
     ]
   }, 
}

The above is carry over from 2019-09 and earlier, starting with 2020-12 the schema would be more compact and better aligned with standard if 'dependentRequired' is used instead this would look like the following:

"dependentRequired": {
  "E_N407": [ "E_N404" ],
},
"dependencies": {
   "E_N407": {
     "allOf": [
       {
         "not": {
           "required": [ "E_N402" ]
         }
       }
     ]
   }
}
"dependentRequired": {
  "E_N407_CountrySubdivisionCode": 
[ "E_N404_CountryCode" ],
},
"dependencies": {
   "E_N407_CountrySubdivisionCode": {
     "allOf": [
       {
         "not": {
           "required": [ "E_N402_StateOrProvinceCode"  ]
         }
       }
     ]
   }
}

9.6 (L) List Conditional

If the first <subj_elem> specified in the <relational_cond> is present, then at least one of the remaining <subj_elem> must be present. However, any or all of the <subj_elem> NOT specified as the FIRST <subj_elem> in the <relational_cond> may appear when the first <subj_elem> is not present. The order of the <subj_elem> in the <relational_cond> does not have to be the same as the order of the data elements in the data segment." For this the dependency will be listed only under the first element listed and reference all others in an "anyOf" grouping. A PO3 segment with rule L040305 would look like the following:

Note: The N407 also has a E0207 rule so the N402 reference is part of another condition.

"dependencies": {
   "E_N407": {
     "allOf": [
       {
         "not": {
           "required": [ "E_N402" ]
         }
       },
       {
         "required": [ "E_N404" ]
       }
     ]
   }, 
}
"dependencies": {
   "E_N407_CountrySubdivisionCode": {
     "allOf": [
       {
         "not": {
           "required": [ "E_N402_StateOrProvinceCode" ]
         }
       },
       {
         "required": [ "E_N404_CountryCode" ]
       }
     ]
   }, 
}

10. Best Practices for Object and Array notation

In general, do not assume that an X12 typing will determine it's typing in JSON as an Object or Array. For example, a Groups with a max use of one must be defined as an object not an array. Also don't assume an Element that can never repeat in more resent X12 version the DMG (Demographic) segment's 5th element is both a composite element and a repeating element making it an array and not an object. Always look to the maximum usage and if one then defines as object and if greater than one defines as an array.

11. Defining Data Types for Data Elements

To some degree X12 and JSON have a high amount of compatibility in how they are defined. However, to maximize compatibility with the JavaScript notation that makes up JSON without requiring developers accustomed to working with JSON objects certain Data Type definitions should be tweaked to eliminate the need to convert X12 JSON data for processing. Where possible though X12 Data Typing and JSON data typing are aligned.

11.1 Numeric

X12 Numeric definitions are handles in two distinct ways. N0 numeric definitions are handled more like integers where applicable. While non-zero numeric definitions are defined as numbers but with fixed max precision in their definition.

11.1.1 Numeric as N0

X12 Numeric definitions are handles in two distinct ways. The first is for N0 use cases here the JSON data type is defined as an "integer" and the max length is used to set an upper limit. For the sake of simplicity and consistency exclusiveMinimum and exclustiveMaximum should be used and Scientific e notation should be used. For instance, an N0 with max of digits would look like this:

"DEF-DataType_N0_1-5" : {
    "type" : "integer",
    "exclusiveMinimum" : -1.0E5,
    "exclusiveMaximum" : 1.0E5
},

If a N0 exceeds a JSON integer limit based on the number of bits JSON data will be process in then it is possible to use a "type" of "number" with a "multipleOf" of 1 like the following:

"DEF-DataType_N0_1-15" : {
    "type" : "number",
    "multipleOf" : 1,
    "exclusiveMinimum" : -1.0E15,
    "exclusiveMaximum" : 1.0E15
},

If a N0 has a minimum length then the multiple of may also be used to enforce this in JSON notation like so:

"DEF-DataType_N0_3-8": {
    "type": "integer",
    "multipleOf": 100,
    "exclusiveMinimum": -1.0E8,
    "exclusiveMaximum": 1.0E8
},

11.1.2 Non-N0 Numeric definitions

Here X12's fixed decimal position can be emulated without need for JSON post processing by applying the "multipleOf" definition to a "type" of "number". For the sake of simplicity and consistency exclusiveMinimum and exclustiveMaximum should be used and Scientific e notation should be used. Note that the assumed decimal placement influences this in the definition in the example below the min-max is E13 not E15 because the fixed precision of X12 translated to JSON shifts the max by 2. An example of this follows:

"DEF-DataType_N2_1-15": {
    "type": "number",
    "multipleOf": 0.01,
    "exclusiveMinimum": -1.0E13,
    "exclusiveMaximum": 1.0E13
},

11.2 Decimal Number

Where a Decimal Type symbol of "R" is sent then the data type is simply defined as follows:

"DEF-DataType_R" : {
    "type" : "number"
},

Here the instinct to set a maximum or minimum based on the X12 defined max a minimum would seem to make sense until you realize that R in X12 support scientific E notation and the enforcement for this is only the maximum number of digits in the field. This mean in theory there is no real maximum for such values in X12 today. Not all numbers though can be converted down if converting from X12 JSON to traditional X12 notation, so caution needs to be exercised in development if conversion between X12 JSON and traditional X12 is planned.

11.3 Identifier

Identifiers are typically just defined as Strings with a set minimum and maximum. The code list is then referenced separately but the Data Element definition, or an external code list matching this definition might be referenced as well. These most commonly will look like this:

"DEF-DataType_ID2-2" : {
    "type" : "string",
    "minLength" : 2,
    "maxLength" : 2
},

There is an additional consideration though that if descriptiveness within the JSON Schema definition is extended past just keys but also to enumerated code lists then IDs may need to simply be defined as "type" of "string" more generically because code list descriptors can be very long. This is not encouraged or preferred but can be supported and would simply look like the following:

"DEF-DataType_ID" : {
    "type" : "string"
},

11.4 String

A string with min and max length pretty much matches JSON notation and appears like the following:

"DEF-DataType_AN1-30" : {
    "type" : "string",
    "minLength" : 1,
    "maxLength" : 30
},

11.5 Date

This is one area where JSON and X12 notations do not align as JSON prefers and expect Date and Times to comply with RFC 3339, section 5.6 and this is a place where X12 gives way to JSON formatting to optimize for compatibility and development. These elements would be defined as follows:

"DEF-DataType_AN1-30" : {
    "type" : "string",
    "minLength" : 1,
    "maxLength" : 30
},

As of JSON Schema 2020-12 the "format" functions as an annotation but JSON Schema parsers may be configured to treat these more as enforceable assertions. The assertion path is suggested for X12 JSON Schema enforcement where available.

Also note that for just Data Element 373 it would be ideal to suppress or override the standard X12 description that covers traditional X12 notation.

11.6 Time

As noted for Date JSON and X12 notations do not align with respect to Time this alignment is a bit more pronounced because compatibility with JSON Schema's RFC 3339, section 5.6 (time notation) means that a Time can include not just time, but a GMT offset. From an X12 JSON Schema implementation standpoint this means that Time as data element 337 and Time Code as data element 623 may in many cases need to be combined to eliminate the possibility for conflicting details to be sent. This definition is ultimately quite simple and would appear as follows:

"DEF-DataType_TM" : {
    "type" : "string",
    "format" : "time"
},

As of JSON Schema 2020-12 the "format" functions as an annotation but JSON Schema parsers may be configured to treat these more as enforceable assertions. The assertion path is suggested for X12 JSON Schema enforcement where available.

Also note that for just Data Element 337 it would be ideal to suppress or override the standard X12 description that covers traditional X12 notation.

In a few places with X12 which would have the effect of merging associated Time and Timecode elements into one element for instance:

"E_DTM03-04" : {
    "$ref" : "#/$defs/DEF-DE_337"
},
"E_DTM03-04_Time-Timecode" : {
    "$ref" : "#/$defs/DEF-DE_337"
},

A complete list of these merged element points is listed below as well as Conditional Requirements that they would eliminate. Also consider several places that only have a Time will in X12 JSON notation be capable of sending GMT offsets with their times that they can't presently do today. This is a consideration if there is a plan to convert X12 JSON into traditional X12 but otherwise in a global real time B2B space precision Time definitions are an improvement to accuracy and consistency without assumptions.

11.7 Binary

For this the segments that hold Binary data will get a transformation align to JSON Schema's implementation of Binary (non-JSON) data encoding.

For the BDS the 01 and 02 are dropped and for the BIN the 01 element is dropped then the BDS03 and BDS02 will use the following definition:

{
  "DEF-DE_782": {
    "type": "object",
    "title": "Binary Data",
    "properties": {
      "E_782_contentMediaType": {
        "title": "Mime as defined in RFC 2046",
        "type": "string"
      },
      "E_782_quoted-printable": {
        "title": "Binary Data - quoted-printable format",
        "description": "X12 No Filter (NOF)",
        "type": "string",
        "contentEncoding": "quoted-printable"
      },
      "E_782_base16": {
        "title": "Binary Data - base16",
        "description": "X12 No Filter (NOF)",
        "type": "string",
        "contentEncoding": "base16"
      },
      "E_782_base32": {
        "title": "Binary Data - quoted-printable format",
        "description": "X12 No Filter (NOF)",
        "type": "string",
        "contentEncoding": "base32"
      },
      "E_782_base64": {
        "title": "Binary Data - quoted-printable format",
        "description": "X12 Base 64 (B64)",
        "type": "string",
        "contentEncoding": "base64"
      }
    },
    "oneOf": [
      {
        "required": [
          "E_782_quoted-printable"
        ]
      },
      {
        "required": [
          "E_782_base16"
        ]
      },
      {
        "required": [
          "E_782_base32"
        ]
      },
      {
        "required": [
          "E_782_base64"
        ]
      }
    ],
    "items": false
  }
}

This definition maximized compatibility between X12 and JSON definitions and supporting all the JSON Schema supported non-JSON content encodings and allowing for MIME type to be defined along side the Binary field definition.

12. Code Lists

The implementation of X12 of as a JSON Schema can already make for some very large and complex JSON Schema specifications so it is ideal the codes for code lists be kept compact for development as simple enumerated lists like the following:

"DEF-CL_008010_1073" : {
   "enum" : [ "C", "E", "F", "M", "N", "R", "U", "W", "Y" ]
},
"DEF-CL_008010_1073" : {
   "enum" : [ "C", "E", "F", "M", "N", "R", "U", "W", "Y" ]
},

If a code list however is trigged and a developer wants to share those codes with human readable descriptions this could be done using the following notation:

"DEF-M_214_S_B1007_CL_005010_1073": {
    "oneOf": [
        {
            "enum": [ "N" ],
            "title": "No"
        },
        {
            "enum": [ "Y" ],
            "title": "Yes"
        }
    ]
},

From a technical implementation standpoint these both accomplish the same thing just in different ways.

The other use main use case for the Code List qualifier is not a definition only use case but a use case that appears in JSON keys and centers around the rare but present X12 Composite Code list like Packing Code, data element 103, which has two distinct code lists. In this use case code list prefix is followed but the data element number but also the sequence/ordering number of the code lists. The inclusion of the code list sequence/ordering number also extends to the definition names used to reference these code lists uniquely.

"DEF-DE_103" : {
  "title" : "Packaging Code",
  "description" : "Code identifying the type of packaging; Part 1: Packaging Form, Part 2: Packaging Material; if the Data Element is used, then Part 1 is always required",
  "type" : "object",
  "properties" : {
    "CL_103_1" : {
      "$ref" : "#/$defs/DEF-CL_008010_103_1"
    },
    "CL_103_2" : {
      "$ref" : "#/$defs/DEF-CL_008010_103_2"
    }
  }
},

12.1 Descriptiveness and code lists

B2B standard are that their peak when their content is most efficiently produced and consumed by systems without human intervention with minimum "free form" content that introduces aspects of human error or evolutions in technology and even standard convention. For instance, with data element 235 the qualifier EN is used for qualifying 13-digit item numbers. In version 005010 the description for this qualifier is "EAN/UCC - 13" while by 008010 the description has been updated to "GTIN-13" after the consolidation of the EAN & UCC into GS1 GTIN standards. This is but one example of how descriptions for code list items can affect values over time if descriptions are included.

Up till this point all descriptiveness items have been strictly kept to JSON keys name while JSON values have stayed values it would be possible to do something like "EN_Gtin13" but it's highly discouraged as part of this specification to extend description to JSON values. (If people need the data to be more readable a cross reference between the JSON and JSON Schema is possible and relatively easy.)

13. Available JSON Schema extensibility

There are some things that are not technically part of X12 but inferred but X12 by certain qualifiers. For instance, in an PO1, IT1, or LIN a UP (GTIN-12) qualifier should always be followed by a 12-digit number as issued by GS1 the same applies for EN (GTIN-13) and UK (GTIN-14). Alternatively, if you look to a MAN segment with a GM (SSCC + Application Identified) qualifier the following element (MAN02) should contain a 20-digit number starting with two leading zeros. These types of checks can be added over the X12 JSON format to provide additional Standards specific formatting checks, and would look like the following:

"allOf": [
  {
    "if": {
      "properties": {
        "E_PO106_ProductServiceIdQualifier": { "const": "IN" }
      }
    },
    "then": {
      "properties": {
        "E_PO107_ProductServiceId": {
          "pattern": "^[0-9]{9,9}$"
        }
      }
    }
  },
  {
    "if": {
      "properties": {
        "E_PO106_ProductServiceIdQualifier": { "const": "UP" }
      }
    },
    "then": {
      "properties": {
        "E_PO107_ProductServiceId": {
          "pattern": "^[0-9]{12,12}$"
        }
      }
    }
  },
  {
    "if": {
      "properties": {
        "E_PO106_ProductServiceIdQualifier": { "const": "EN" }
      }
    },
    "then": {
      "properties": {
        "E_PO107_ProductServiceId": {
          "pattern": "^[0-9]{13,13}$"
        }
      }
    }
  },
  {
    "if": {
      "properties": {
        "E_PO106_ProductServiceIdQualifier": { "const": "UK" }
      }
    },
    "then": {
      "properties": {
        "E_PO107_ProductServiceId": {
          "pattern": "^[0-9]{14,14}$"
        }
      }
    }
},

14. Known JSON-to-X12 detail losses

14.1 JavaScript Times (inclusion of time zones)

As referenced above in 11.5 (Date) and 11.6 (Time) we are including the JSON Schema 'format' of 'date' and 'time' respectively which allows most Java Script consumption to recognize dates and times without conversion, this is a positive for anyone coding against a JSON output.

The opportunity with using JSON Schema's RFC 3339, section 5.6 (time notation) is that JSON times can support time in the context of a time zone. For many places in X12 this one element can be mapped to both Time (DE: 337) and Time Code (DE: 623) with the time mapping to time and time zone mapping to a Time Code value between 01-29 or UT that corresponds to the appropriate UTC offset or UTC. (Note: At the time of writing certain rarer time zone offsets are missing [+03:30, +04:30, +5:45, +6:30, +8:45, +12:45, +13:00, +13:45, +14:00].)

For the most common scenarios like DTM the lossless JSON-to-X12 is possible. However, many X12 Time data elements (DE:337) are present without Time Code (DE: 623) companions meaning the loss of a time zone could be problematic if a pre-agreed upon offset is not agreed upon in advance.

14.2 X12 Real numbers with fixed min-max sizing

Because X12.6 in its definition of 3.5.1.2 Decimal Number defines a Decimal Number's (R) length as follows:

The length of a decimal type data element does not include the optional minus signs, decimal point, or trailing exponent indicator "E".

Then for a Decimal Number with a max length of 9 could contain the following and remain valid:

9E10000000

This is an insanely huge number, yet valid for an X12 Decimal Number with a max length of 9 ("9" = 1 and "10000000" = 8 for 1+8=9). The rule for lossless JSON-to-X12 is that the decimal precision length + exponential offset length cannot be greater than the X12 max length.