Parsing 837 (Healthcare Claim) Transactions

View the complete example in GitHub

Object Model

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 transactions are mapped to the appropriate properties of the business objects.

Refer to our JSON schema documentation for a complete list of objects, fields, and their mappings to X12 EDI segments and elements.

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 properties of the claim
BigDecimal billedAmount = sampleClaim.chargeAmount();
String patientControlNumber = sampleClaim.patientControlNumber();
// Providers
OrgOrPerson billingProvider = sampleClaim.billingProvider();
String providerNpi = billingProvider.identifier();
// Service lines
for (var line : sampleClaim.lines()) {
    String procedureCode = line.procedure().code();
    LocalDate serviceDate = line.serviceDateFrom();
    Integer unitCount = line.unitCount();
    UnitType unitType = line.unitType();
}

Claim is the root of the object graph when parsing 837s. It aggregates information from segments in the “Claim Information” loop, including “CLM,” all the “REF” segments, all the date segments, and so on. The Claim also contains entities from the billing provider and 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.

Enums and EDI Qualifiers

The parser translates EDI qualifiers and some codes to Java enums. For example, the patient gender code from the DMG segment is parsed as a GenderType enum. The Entity Identifier Code from NM1 is translated into an 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.subscriber();

EntityRole entityRole = patient.person().entityRole();
assertThat(entityRole).isEqualTo(EntityRole.INSURED_SUBSCRIBER);
// Use ediCode to get the actual EDI qualifier
String ediQualifierCode = entityRole.ediValue();
log.info("Entity Role: {} EDI Qualifier Code: {}", entityRole, ediQualifierCode);

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

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

Parsing in Chunks

The parser reads a file in chunks consisting of the specified number of claims. This allows the parser to process large files. 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.

try (var parser = new EdiParser(edi837File)) {
    EdiParsingResults parsingResults;
    do {
        // parse up to 100 claims at a time
        parsingResults = parser.parse(100);
        List<Claim> claims = parsingResults.claims();
        for (var claim : claims) {
            processClaim(claim);
        }
    } while (!parsingResults.isDone());
}

Please visit our GitHub repo for more examples.