X12 834 Benefit Enrollment and Maintenance

The 834 is the HIPAA transaction employers, plan sponsors, government agencies and health insurance exchanges use to enroll members in a health plan, change their coverage, or terminate it.

Each member is an INS loop (2000) with the member's name and demographics, followed by HD health coverage loops with the plan, coverage level and effective dates. Files are either full replacements of the membership or change files that only carry updates.

At a glance

Standard
X12 HIPAA
Implementation guide
005010X220A1
Functional group
BE (GS01)
Sent by
Employer, sponsor or exchange to health plan
Responses
999
ediFabric .NET template
TS834 in EdiFabric.Templates.Hipaa
OpenEDI definition
View 834 in the spec library

834 structure

The full X12 834 layout from its OpenEDI definition, the same model ediFabric uses to parse, validate and generate it: 21 loops and 76 segment positions, in file order. Loops are shaded and their segments indented; Max use is how many times a segment or loop may repeat.

Segment / loop Name Usage Max use
STTransaction Set HeaderRequired1
BGNBeginning SegmentRequired1
REFTransaction Set Policy NumberSituational1
DTPFile Effective DateSituational>1
QTYTransaction Set Control TotalsSituational3
Any orderThe loops below can appear in any orderRequired1
Loop 1000ASponsor NameRequired1
N1Sponsor NameRequired1
Loop 1000BPayerRequired1
N1PayerRequired1
Loop 1000CTPA Broker NameSituational2
N1TPA Broker NameRequired1
Loop 1100CTPA Broker Account InformationSituational1
ACTTPA Broker Account InformationRequired1
Loop 2000Member Level DetailRequired>1
INSMember Level DetailRequired1
Any orderThe loops below can appear in any orderRequired1
REFSubscriber IdentifierRequired1
REFMember Policy NumberSituational1
REFMember Supplemental IdentifierSituational13
DTPMember Level DatesSituational24
Any orderThe loops below can appear in any orderRequired1
Loop 2100AMember NameRequired1
NM1Member NameRequired1
PERMember Communications NumbersSituational1
N3Member Residence Street AddressSituational1
N4Member City State ZIP CodeSituational1
DMGMember DemographicsSituational1
ECEmployment ClassSituational>1
ICMMember IncomeSituational1
AMTMember Policy AmountsSituational7
HLHMember Health InformationSituational1
LUIMember LanguageSituational>1
Loop 2100BIncorrect Member NameSituational1
NM1Incorrect Member NameRequired1
DMGIncorrect Member DemographicsSituational1
Loop 2100CMember Mailing AddressSituational1
NM1Member Mailing AddressRequired1
N3Member Mail Street AddressRequired1
N4Member Mail City State ZIP CodeRequired1
Loop 2100DMember EmployerSituational3
NM1Member EmployerRequired1
PERMember Employer Communications NumbersSituational1
N3Member Employer Street AddressSituational1
N4Member Employer City State ZIP CodeSituational1
Loop 2100EMember SchoolSituational3
NM1Member SchoolRequired1
PERMember School Commmunications NumbersSituational1
N3Member School Street AddressSituational1
N4Member School City State ZIP CodeSituational1
Loop 2100FCustodial ParentSituational1
NM1Custodial ParentRequired1
PERCustodial Parent Communications NumbersSituational1
N3Custodial Parent Street AddressSituational1
N4Custodial Parent City State ZIP CodeSituational1
Loop 2100GResponsible PersonSituational13
NM1Responsible PersonRequired1
PERResponsible Person Communications NumbersSituational1
N3Responsible Person Street AddressSituational1
N4Responsible Person City State ZIP CodeSituational1
Loop 2100HDrop Off LocationSituational1
NM1Drop Off LocationRequired1
N3Drop Off Location Street AddressSituational1
N4Drop Off Location City State ZIP CodeSituational1
Loop 2200Disability InformationSituational>1
DSBDisability InformationRequired1
DTPDisability Eligibility DatesSituational2
Loop 2300Health CoverageSituational99
HDHealth CoverageRequired1
DTPHealth Coverage DatesRequired6
AMTHealth Coverage PolicySituational9
Any orderThe loops below can appear in any orderSituational1
REFHealth Coverage Policy NumberSituational14
REFPrior Coverage MonthsSituational1
IDCIdentification CardSituational3
Loop 2310Provider InformationSituational30
LXProvider InformationRequired1
NM1Provider NameRequired1
N3Provider AddressSituational2
N4Provider City State ZIP CodeSituational1
PERProvider Communications NumbersSituational2
PLAProvider Change ReasonSituational1
Loop 2320Coordinationof BenefitsSituational5
COBCoordinationof BenefitsRequired1
REFAdditional Coordinationof Benefits IdentifiersSituational4
DTPCoordinationof Benefits Eligibility DatesSituational2
Loop 2330Coordinationof Benefits Related EntitySituational3
NM1Coordinationof Benefits Related EntityRequired1
N3Coordinationof Benefits Related Entity AddressSituational1
N4Coordinationof Benefits Other Insurance Company City State ZIP CodeSituational1
PERAdministrative Communications ContactSituational1
Loop LSAdditional Reporting CategoriesSituational1
LSAdditional Reporting CategoriesRequired1
Loop 2700Member Reporting CategoriesSituational>1
LXMember Reporting CategoriesRequired1
Loop 2750Reporting CategorySituational1
N1Reporting CategoryRequired1
REFReporting Category ReferenceSituational1
DTPReporting Category DateSituational1
LEAdditional Reporting Categories TerminationRequired1
SETransaction Set TrailerRequired1

Usage follows the 005010X220A1 implementation guide: Required segments must be sent, Situational ones only when the guide's condition applies. Trading partners often add their own rules in companion guides - ediFabric templates can be adjusted to match. Open the element-level definition in the EdiNation spec library.

Sample 834 file

An enrollment for one subscriber with health coverage details. Paste it into EdiNation to see every element named and validated.

ISA*00*          *00*          *ZZ*386028429      *30*382328142      *050221*0602*U*00501*000012345*0*P*:~
GS*BE*386028429*382328142*20050221*0602*000012345*X*005010X220A1~
ST*834*12345*005010X220A1~
BGN*00*12456*19980520*1200****2~
N1*P5**FI*999888777~
N1*IN**FI*654456654~
INS*Y*18*021*20*A***FT~
REF*0F*123456789~
REF*1L*123456001~
DTP*356*D8*19960523~
NM1*IL*1*DOE*JOHN*P***34*123456789~
PER*IP**HP*7172343334*WP*7172341240~
N3*100 MARKET ST*APT 3G~
N4*CAMP HILL*PA*17011**CY*CUMBERLAND~
DMG*D8*19400816*M~
HD*021**HLT~
DTP*348*D8*19960601~
COB*P*890111*5~
HD*021**DEN~
DTP*348*D8*19960601~
HD*021**VIS~
DTP*348*D8*19960601~
SE*21*12345~
GE*1*000012345~
IEA*1*000012345~

The same 834 as JSON

ediFabric turns every loop, segment and element into a named field. This is the transaction from the sample, in the JSON that ediFabric Native and Cloud return and accept.

{
  "ST": {
    "TransactionSetIdentifierCode_01": "834",
    "TransactionSetControlNumber_02": "12345",
    "ImplementationConventionPreference_03": "005010X220A1"
  },
  "BGN_BeginningSegment": {
    "TransactionSetPurposeCode_01": "00",
    "TransactionSetReferenceNumber_02": "12456",
    "TransactionSetCreationDate_03": "19980520",
    "TransactionSetCreationTime_04": "1200",
    "ActionCode_08": "2"
  },
  "AllN1": {
    "Loop1000A": {
      "N1_SponsorName": {
        "EntityIdentifierCode_01": "P5",
        "IdentificationCodeQualifier_03": "FI",
        "IntermediaryBankIdentifier_04": "999888777"
      }
    },
    "Loop1000B": {
      "N1_Payer": {
        "EntityIdentifierCode_01": "IN",
        "IdentificationCodeQualifier_03": "FI",
        "IntermediaryBankIdentifier_04": "654456654"
      }
    }
  },
  "Loop2000": [
    {
      "INS_MemberLevelDetail": {
        "InsuredIndicator_01": "Y",
        "IndividualRelationshipCode_02": "18",
        "MaintenanceTypeCode_03": "021",
        "MaintenanceReasonCode_04": "20",
        "BenefitStatusCode_05": "A",
        "EmploymentStatusCode_08": "FT"
      },
      "AllREF": {
        "REF_SubscriberIdentifier": {
          "ReferenceIdentificationQualifier_01": "0F",
          "MemberGrouporPolicyNumber_02": "123456789"
        },
        "REF_MemberPolicyNumber": {
          "ReferenceIdentificationQualifier_01": "1L",
          "MemberGrouporPolicyNumber_02": "123456001"
        }
      },
      "DTP_MemberLevelDates": [
        {
          "DateTimeQualifier_01": "356",
          "DateTimePeriodFormatQualifier_02": "D8",
          "DateTimePeriod_03": "19960523"
        }
      ],
      "AllNM1": {
        "Loop2100A": {
          "NM1_MemberName": {
            "EntityIdentifierCode_01": "IL",
            "EntityTypeQualifier_02": "1",
            "ResponseContactLastorOrganizationName_03": "DOE",
            "ResponseContactFirstName_04": "JOHN",
            "ResponseContactMiddleName_05": "P",
            "IdentificationCodeQualifier_08": "34",
            "ResponseContactIdentifier_09": "123456789"
          },
          "PER_MemberCommunicationsNumbers": {
            "ContactFunctionCode_01": "IP",
            "CommunicationNumberQualifier_03": "HP",
            "ResponseContactCommunicationNumber_04": "7172343334",
            "CommunicationNumberQualifier_05": "WP",
            "ResponseContactCommunicationNumber_06": "7172341240"
          },
          "N3_MemberResidenceStreetAddress": {
            "ResponseContactAddressLine_01": "100 MARKET ST",
            "ResponseContactAddressLine_02": "APT 3G"
          },
          "N4_MemberCity_State_ZIPCode": {
            "AdditionalPatientInformationContactCityName_01": "CAMP HILL",
            "AdditionalPatientInformationContactStateCode_02": "PA",
            "AdditionalPatientInformationContactPostalZoneorZIPCode_03": "17011",
            "LocationQualifier_05": "CY",
            "LocationIdentifier_06": "CUMBERLAND"
          },
          "DMG_MemberDemographics": {
            "DateTimePeriodFormatQualifier_01": "D8",
            "DependentBirthDate_02": "19400816",
            "DependentGenderCode_03": "M"
          }
        }
      },
      "Loop2300": [
        {
          "HD_HealthCoverage": {
            "MaintenanceTypeCode_01": "021",
            "InsuranceLineCode_03": "HLT"
          },
          "DTP_HealthCoverageDates": [
            {
              "DateTimeQualifier_01": "348",
              "DateTimePeriodFormatQualifier_02": "D8",
              "DateTimePeriod_03": "19960601"
            }
          ],
          "Loop2320": [
            {
              "COB_CoordinationofBenefits": {
                "PayerResponsibilitySequenceNumberCode_01": "P",
                "MemberGrouporPolicyNumber_02": "890111",
                "CoordinationofBenefitsCode_03": "5"
              }
            }
          ]
        },
        {
          "HD_HealthCoverage": {
            "MaintenanceTypeCode_01": "021",
            "InsuranceLineCode_03": "DEN"
          },
          "DTP_HealthCoverageDates": [
            {
              "DateTimeQualifier_01": "348",
              "DateTimePeriodFormatQualifier_02": "D8",
              "DateTimePeriod_03": "19960601"
            }
          ]
        },
        {
          "HD_HealthCoverage": {
            "MaintenanceTypeCode_01": "021",
            "InsuranceLineCode_03": "VIS"
          },
          "DTP_HealthCoverageDates": [
            {
              "DateTimeQualifier_01": "348",
              "DateTimePeriodFormatQualifier_02": "D8",
              "DateTimePeriod_03": "19960601"
            }
          ]
        }
      ]
    }
  ],
  "SE": {
    "NumberofIncludedSegments_01": "21",
    "TransactionSetControlNumber_02": "12345"
  }
}

Parse and validate an 834 file

Read the file into typed objects with ediFabric .NET, convert it to JSON in process with the ediFabric Native bindings for Python, Java and C, or post it to the ediFabric Cloud REST API from any language.

using EdiFabric.Templates.Hipaa5010;

License.SetSerial("YOUR_SERIAL_KEY");

using (var stream = File.OpenRead(@"C:\edi\BenefitEnrollment.txt"))
using (var reader = new X12Reader(stream, "EdiFabric.Templates.Hipaa"))
{
    var items = await reader.ReadToEndAsync();
    foreach (var transaction in items.OfType<TS834>())
    {
        if (transaction.IsValid(out MessageErrorContext errors))
            Console.WriteLine($"{transaction.ST.TransactionSetControlNumber_02} is valid");
        else
            Console.WriteLine(string.Join(Environment.NewLine, errors.Flatten()));
    }
}
import json
import edifabric_x12 as ef

serial = "YOUR_SERIAL_KEY"
ef.load_library()
ef.set_serial(serial)
ef.set_map(json.dumps({"default": serial, "maps": {}}))

edi = open("BenefitEnrollment.txt", "rb").read()
output, offset = ef.parse(edi, ef.ParseMode.JSON_VALIDATE)
transactions = output[:offset]
report = json.loads(output[offset:])
print(report["errors_count"])
import com.edifabric.nativex12.EdiFabricX12;
import com.edifabric.nativex12.ParseMode;
import com.edifabric.nativex12.ParseResult;

String serial = "YOUR_SERIAL_KEY";
EdiFabricX12.loadLibrary();
EdiFabricX12.setSerial(serial);
EdiFabricX12.setMap("{\"default\":\"" + serial + "\",\"maps\":{}}");

String edi = Files.readString(Path.of("BenefitEnrollment.txt"));
ParseResult result = EdiFabricX12.parse(edi, ParseMode.JSON_VALIDATE);
System.out.println(result.getTransactions());
System.out.println(result.getReport());
#include "edifabric_x12.h"

const char *serial = "YOUR_SERIAL_KEY";
ef_parse_result result;

if (ef_load_library(NULL) != 0)
    return 1;
ef_set_serial(serial);
ef_set_map("{\"default\":\"YOUR_SERIAL_KEY\",\"maps\":{}}");

char *edi = read_file("BenefitEnrollment.txt", NULL);   /* helper in example_all_functions.c */
if (ef_parse(edi, EF_PARSE_JSON_VALIDATE, NULL, &result) == 0) {
    /* transactions = output[0 .. offset), report = output[offset .. length) */
    fwrite(result.output.data, 1, (size_t)result.output.length, stdout);
    ef_free(result.output.data);
}
curl -X POST 'https://api.edination.com/v2/x12/read' \
-H 'Ocp-Apim-Subscription-Key: YOUR_SERIAL_KEY' \
-H 'Content-Type: application/octet-stream' \
--data-binary '@BenefitEnrollment.txt'

Generate an 834 file

Populate a TS834 object in .NET, or pass JSON in the shape shown above to ediFabric Native or ediFabric Cloud, and get a valid 834 file back.

using EdiFabric.Templates.Hipaa5010;

License.SetSerial("YOUR_SERIAL_KEY");

var transaction = new TS834();

//  Used to indicate the start of a transaction set and to specify a transaction set control number.
transaction.ST = new ST();
transaction.ST.TransactionSetIdentifierCode_01 = "834";
transaction.ST.TransactionSetControlNumber_02 = "0001";

//  This is an original transaction uniquely identified by the sender with reference #12456. The transaction was created on 5/20/1998 at 12:00 Noon.
transaction.BGN_BeginningSegment = new BGN_BeginningSegment();
transaction.BGN_BeginningSegment.TransactionSetPurposeCode_01 = "00";
transaction.BGN_BeginningSegment.TransactionSetReferenceNumber_02 = "12456";
transaction.BGN_BeginningSegment.TransactionSetCreationDate_03 = "19980520";
transaction.BGN_BeginningSegment.TransactionSetCreationTime_04 = "1200";
transaction.BGN_BeginningSegment.ActionCode_08 = "2";

//  Occurrence of N1 Loops in any order
transaction.AllN1 = new All_N1_834();

//  Begin 1000A Loop
transaction.AllN1.Loop1000A = new Loop_1000A_834();

// ... set the remaining loops and segments the same way

// SegmentBuilders is in the Common project of the example repository
using (var stream = new MemoryStream())
{
    using (var writer = new X12Writer(stream))
    {
        writer.Write(SegmentBuilders.BuildIsa("1"));
        writer.Write(SegmentBuilders.BuildGs("1", "SENDER1", "RECEIVER1", "005010X220A1"));
        writer.Write(transaction);
    }
    Console.WriteLine(Encoding.UTF8.GetString(stream.ToArray()));
}
import json
import edifabric_x12 as ef

serial = "YOUR_SERIAL_KEY"
ef.load_library()
ef.set_serial(serial)
ef.set_map(json.dumps({"default": serial, "maps": {}}))

# the transactions JSON returned by ef.parse, edited or produced by your application
transactions = open("BenefitEnrollment.json", "rb").read()
edi = ef.build(transactions, postfix="\r\n")
print(edi)
import com.edifabric.nativex12.EdiFabricX12;

String serial = "YOUR_SERIAL_KEY";
EdiFabricX12.loadLibrary();
EdiFabricX12.setSerial(serial);
EdiFabricX12.setMap("{\"default\":\"" + serial + "\",\"maps\":{}}");

// the transactions JSON returned by parse, edited or produced by your application
String transactions = Files.readString(Path.of("BenefitEnrollment.json"));
String edi = EdiFabricX12.build(transactions, "\r\n");
System.out.println(edi);
#include "edifabric_x12.h"

ef_buffer edi;

if (ef_load_library(NULL) != 0)
    return 1;
ef_set_serial("YOUR_SERIAL_KEY");
ef_set_map("{\"default\":\"YOUR_SERIAL_KEY\",\"maps\":{}}");

/* the transactions JSON returned by ef_parse, edited or produced by your application */
char *transactions = read_file("BenefitEnrollment.json", NULL);
if (ef_build(transactions, "\r\n", &edi) == 0) {
    fwrite(edi.data, 1, (size_t)edi.length, stdout);
    ef_free(edi.data);
}
# the JSON returned by /read, edited or produced by your application
curl -X POST 'https://api.edination.com/v2/x12/write' \
-H 'Ocp-Apim-Subscription-Key: YOUR_SERIAL_KEY' \
-H 'Content-Type: application/json' \
--data-binary '@BenefitEnrollment.json' \
-o 'BenefitEnrollment.txt'

834 questions

What is the difference between a full and a change 834 file?

BGN08 tells the receiver how to apply the file. 2 means change (update) and carries only additions, changes and terminations. 4 means verify, and RX means replace - the file is the complete membership.

How is a member added, changed or terminated?

INS03 carries the maintenance type code: 021 addition, 001 change, 024 cancellation or termination, 030 audit or compare. INS04 gives the reason.

Does the plan send a business response to an 834?

HIPAA only defines the 999 acknowledgment. Many plans return discrepancy reports or their own 834 audit files by trading partner agreement.

How do I parse and generate X12 834 files in .NET, Python, Java and C?

In .NET, install EdiFabric and EdiFabric.Templates.Hipaa, read the file with X12Reader into TS834 objects and write them back with X12Writer. From Python, Java or C, use ediFabric Native, which converts 834 files to JSON and JSON back to X12 inside your process. From any other language, post the file to the ediFabric Cloud REST API.

Related transactions

Parse your first 834 in five minutes

The Community plan is free forever and needs no credit card. It includes ediFabric .NET, Native and Cloud.