Parsing 837 (Healthcare Claim) Transactions

The parser returns regular business objects (POJOs) such as Claim, Payment, ServiceLine, Subscriber, and so on. All X12 EDI segments and elements from 837/835 have been mapped to the appropriate properties of the business objects.

The parser’s object model provides an excellent level of abstraction so that developers don’t need to deal with X12 EDI artifacts, such as segments and loops.

Here is a simple example:

var parser = new EdiParser(ediFile837p);
// Parse all claims in the file; alternatively you can parse in chunks
List<Claim> claims = parser.parse837(-1);
assertThat(claims).isNotEmpty();

Claim sampleClaim = claims.get(0);
// get some key attributes of the claim
BigDecimal billedAmount = sampleClaim.chargeAmount();
String patientControlNumber = sampleClaim.patientControlNumber();
// Providers
OrgOrPerson billingProvider = sampleClaim.billingProvider();
String providerNpi = billingProvider.identifier();
assertNotNull(billedAmount, patientControlNumber, providerNpi);
// Service lines
for (var line : sampleClaim.lines()) {
    String procedureCode = line.procedure().code();
    LocalDate serviceDate = line.serviceDateFrom();
    Integer unitCount = line.unitCount();
    UnitType unitType=line.unitType();
    
    assertNotNull(procedureCode, serviceDate, unitCount, unitType);
}

Claim is the root of the object graph when parsing 837s. It aggregates information from segments from the “Claim Information” loop, including “CLM,” all the “REF” segments, all the dates segments, and so on. The Claim also contains entities from the billing provider and the subscriber loops.

As expected, a claim contains a list of service lines, and each line contains line-level data, such as CPT codes, amounts, and providers, obtained from the appropriate segments in the “Service Line Number” loop.

The parser translates EDI qualifiers and some of the codes to Java enums. For example, the patient gender code from the DMG segment is parsed as GenderType enum. Entity Identifier Code from NM1 is translated into EntityRole enum.

Similarly, the Place of Service (CLM05 element) is translated into the PlaceOfServiceType enum.

Below are examples of enums:

List<Claim> claims = parser.parse837(-1);
Claim claim = claims.get(0);
PlaceOfServiceType pos=claim.placeOfServiceType();
assertThat(pos).isEqualTo(PlaceOfServiceType.OFFICE);

PatientSubscriber patient = claim.patient();

EntityRole entityRole=patient.person().entityRole();
assertThat(entityRole).isEqualTo(EntityRole.SUBSCRIBER);

EntityType entityType=patient.person().entityType();
assertThat(entityType).isEqualTo(EntityType.INDIVIDUAL);

GenderType genderType=patient.person().gender();
assertThat(genderType).isEqualTo(GenderType.MALE);

To parse large files, the parser can read a file in chunks consisting of the specified number of claims. The client’s application can then process each chunk in parallel if needed. For example, claims from each chunk can be persisted using reactive drivers provided by Spring Boot.

var parser = new EdiParser(ediFile);
while (true){
    // parse two claim at a time. In real life, use 200-500 as the optimal batch size
    var claims = parser.parse837(2);
    if(claims.isEmpty()){
        break;
    }
    // Do something with each claim
    for(var claim :claims){
        // your logic goes here
    }
}

Please visit our GitHub repo for more examples.

Register below to get access to the parser: