X12 Control Segments Last updated: 2026-10-09
Structure of X12 envelopes
An X12 interchange nests three envelopes. Each one opens with a header segment and closes with a trailer segment. The trailer repeats the control number from the header and counts what is inside, so the receiver can tell when something is missing or was cut off.
- Interchange, ISA to IEA. One transmission from one sender to one receiver. ISA also sets the separators.
- Functional group, GS to GE. A group holds transaction sets of one functional type, for example purchase orders.
- Transaction set, ST to SE. One business document, such as an 850 or an 837P.
Control segments and what the receiver checks
The receiver checks every header and trailer pair. Interchange errors are reported in a TA1, and group and transaction set errors in a 997 or 999. The last column links to the codes for each segment.
| Segment | Name | What must be right | Error codes |
|---|---|---|---|
| ISA | Interchange header | Fixed length, 106 characters. Sender and receiver IDs with their qualifiers, date, time, control version (ISA12), acknowledgment requested (ISA14), test or production (ISA15), and the interchange control number (ISA13), which must be unique for the sender. | TA105 2, 3, 5 to 8, 10 to 20, 25 and 27 |
| GS | Functional group header | Functional identifier code (GS01, for example PO for an 850), sender and receiver codes, the group control number (GS06) and the version (GS08). | AK905 to AK909 1, 2 and 6 in the 997 and 999 |
| ST | Transaction set header | Transaction set identifier (ST01, for example 850) and the control number (ST02), which must be unique in the group. For HIPAA, ST03 names the implementation guide. | AK502 to AK506 1, 6 and 7 in the 997, IK502 to IK506 in the 999 |
| SE | Transaction set trailer | The number of segments from ST to SE inclusive (SE01). SE02 must equal ST02. | AK502 to AK506 2, 3 and 4 in the 997, IK502 to IK506 in the 999 |
| GE | Functional group trailer | The number of transaction sets in the group (GE01). GE02 must equal GS06. | AK905 to AK909 3, 4 and 5 in the 997 and 999 |
| IEA | Interchange trailer | The number of functional groups (IEA01). IEA02 must equal ISA13. | TA105 1, 21 and 23 |
To ask the receiver for a TA1, set ISA14 to 1. To generate the acknowledgments, see Generate X12 999 for ediFabric .NET, generate acknowledgments for ediFabric Native, and 997 or 999 for ediFabric Cloud.
ISA separators and fixed length
ISA is the only fixed-length X12 segment. Every element is padded to its full width, so the segment is always 106 characters long, and the receiver reads the separators from fixed positions:
- Character 4, right after
ISA, is the data element separator. - ISA11 is the repetition separator from version 00402 onward. Older versions use ISA11 for the standards identifier, usually
U. - ISA16 is the component element separator.
- Character 106, right after ISA16, is the segment terminator.
That's why the example below pads ISA02 and ISA04 to 10 characters, ISA06 and ISA08 to 15, and ISA13 to nine digits.
Generate the ISA interchange header in C#
This method builds an ISA with ediFabric .NET. Pass a new interchange control number for every interchange, and use the same value in IEA02.
///
/// Build ISA.
///
public static ISA BuildIsa(string controlNumber,
string senderId = "SENDER1",
string senderQ = "14",
string receiverId = "RECEIVER1",
string receiverQ = "16",
string ackRequested = "1",
string testIndicator = "T")
{
return new ISA
{
// Authorization Information Qualifier
AuthorizationInformationQualifier_1 = "00",
// Authorization Information
AuthorizationInformation_2 = "".PadRight(10),
// Security Information Qualifier
SecurityInformationQualifier_3 = "00",
// Security Information
SecurityInformation_4 = "".PadRight(10),
// Interchange ID Qualifier
SenderIDQualifier_5 = senderQ,
// Interchange Sender
InterchangeSenderID_6 = senderId.PadRight(15),
// Interchange ID Qualifier
ReceiverIDQualifier_7 = receiverQ,
// Interchange Receiver
InterchangeReceiverID_8 = receiverId.PadRight(15),
// Date
InterchangeDate_9 = DateTime.Now.Date.ToString("yyMMdd"),
// Time
InterchangeTime_10 = DateTime.Now.TimeOfDay.ToString("hhmm"),
// Standard identifier
InterchangeControlStandardsIdentifier_11 = "U",
// Interchange Version ID
// This is the ISA version and not the transaction sets versions
InterchangeControlVersionNumber_12 = "00204",
// Interchange Control Number
InterchangeControlNumber_13 = controlNumber.PadLeft(9, '0'),
// Acknowledgment Requested (0 or 1)
AcknowledgementRequested_14 = ackRequested,
// Test Indicator
UsageIndicator_15 = testIndicator,
};
}Generate the GS functional group header in C#
The group control number must be unique for the sender, and GE02 repeats it. GS08 is the version of the transaction sets in the group, for example 004010 or 005010X222A1.
///
/// Build GS.
///
public static GS BuildGs(string controlNumber,
string senderId = "SENDER1",
string receiverId = "RECEIVER1",
string version = "004010")
{
return new GS
{
// Functional ID Code
CodeIdentifyingInformationType_1 = "IN",
// Application Senders Code
SenderIDCode_2 = senderId,
// Application Receivers Code
ReceiverIDCode_3 = receiverId,
// Date
Date_4 = DateTime.Now.Date.ToString("yyMMdd"),
// Time
Time_5 = DateTime.Now.TimeOfDay.ToString("hhmm"),
// Group Control Number
// Must be unique to both partners for this interchange
GroupControlNumber_6 = controlNumber.PadLeft(9, '0'),
// Responsible Agency Code
TransactionTypeCode_7 = "X",
// Version/Release/Industry id code
VersionAndRelease_8 = version
};
}X12 control segments in ediFabric .NET
Each control segment is a class in ediFabric .NET:
The examples above are part of the ediFabric .NET C# code examples.
The X12 envelope in ediFabric Native and Cloud JSON
ediFabric Native and ediFabric Cloud use the same JSON for an interchange, the X12Interchange object. In ediFabric Cloud, POST /x12/read returns an array of them, and /x12/write, /x12/validate and /x12/ack take one. In ediFabric Native, start_merge takes a full interchange in this shape and streams it back as X12.
{
"SegmentDelimiter": "~",
"DataElementDelimiter": "*",
"ISA": {
"AuthorizationInformationQualifier_1": "00",
"AuthorizationInformation_2": " ",
"SecurityInformationQualifier_3": "00",
"SecurityInformation_4": " ",
"SenderIDQualifier_5": "16",
"InterchangeSenderID_6": "SENDER1 ",
"ReceiverIDQualifier_7": "14",
"InterchangeReceiverID_8": "RECEIVER1 ",
"InterchangeDate_9": "071216",
"InterchangeTime_10": "1406",
"InterchangeControlStandardsIdentifier_11": "U",
"InterchangeControlVersionNumber_12": "00204",
"InterchangeControlNumber_13": "000000263",
"AcknowledgementRequested_14": "1",
"UsageIndicator_15": "T",
"ComponentElementSeparator_16": ">"
},
"Groups": [{
"GS": {
"CodeIdentifyingInformationType_1": "IN",
"SenderIDCode_2": "SENDER1",
"ReceiverIDCode_3": "RECEIVER1",
"Date_4": "20071216",
"Time_5": "1406",
"GroupControlNumber_6": "000000001",
"TransactionTypeCode_7": "X",
"VersionAndRelease_8": "004010"
},
"Transactions": [{
"ST": {
"TransactionSetIdentifierCode_01": "850",
"TransactionSetControlNumber_02": "0001"
},
"_comment": "... model specific content goes here ...",
"SE": {
"NumberofIncludedSegments_01": "15",
"TransactionSetControlNumber_02": "0001"
},
"Model": "EdiNation.X12.ASC.004010"
}],
"GETrailers": [{
"NumberOfIncludedSets_1": "1",
"GroupControlNumber_2": "000000001"
}]
}],
"IEATrailers": [{
"NumberOfIncludedGroups_1": "1",
"InterchangeControlNumber_2": "000000263"
}],
"Result": {
"LastIndex": 19,
"Details": [],
"Status": "success"
}
}Each control segment maps to a JSON object:
| Segment | JSON |
|---|---|
| ISA | ISA, with the separators also in SegmentDelimiter and DataElementDelimiter |
| TA1 | TA1, present only in an acknowledgment |
| GS and GE | Groups, a list of X12Group objects, each with a GS and GETrailers |
| ST and SE | ST and SE in each item of Transactions, with the transaction content between them |
| IEA | IEATrailers |
See all the X12 objects in X12 resources.
