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.
X12 envelope structure: the ISA to IEA interchange holds GS to GE functional groups, which hold ST to SE transaction sets. Each trailer repeats the header control number and counts its contents.

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,
	};
}

Object reference: ISA. The code is also on GitHub.

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
	};
}

Object reference: GS. The code is also on GitHub.

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.

Download EDI C# 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.