X12

Read the money out of an 835 without a TR3 open on your desk.

@cosyte/x12 decodes the HIPAA 005010 transaction sets into typed models, keeps every amount in exact decimal arithmetic, and reports each vendor deviation it tolerated with a stable code instead of failing or guessing.

@cosyte/x12
npm install @cosyte/x12

Need it integrated? Talk to us.

The standard

X12 5010 is how US claims, payments and eligibility move.

  • HIPAA required HHS to establish national standards for electronic health care transactions, and they apply to all HIPAA covered entities. Source: CMS, Adopted Standards and Operating Rules
  • The adopted standards include ASC X12N 837 for claims, 270/271 for eligibility, 276/277 for claim status, 278 for prior authorization and referrals, 834 for enrollment and 835 for claim payment, each at version 5010. Source: CMS, Adopted Standards and Operating Rules
  • X12 developed the implementation guides adopted under HIPAA for exchanging administrative data between payers, providers and related organizations. Source: X12, health care

@cosyte/x12

Typed models for the transaction sets, exact to the cent.

Reading an X12 transaction correctly normally means buying its TR3 implementation guide and hand-mapping element positions no compiler checks. This library does that mapping once, with tests, for the engineer who has one 835 to post or one 271 to answer.

  • Typed read for 270, 271, 276, 277 and 277CA, 278 request and response, 820, 834, 835, 837P, 837I and 837D, 999 and TA1.
  • Every amount in exact decimal arithmetic, never a binary float.
  • Vendor deviations become warnings with stable codes. Built-in profiles record whose companion-guide deviation they accept.
  • Your own profiles, through the same public defineProfile() API the built-ins use.
  • The base 006020 structure of the two claims attachments transactions: the 277 request for additional information and the 275 that answers it.
  • X12_TR3_CONFORMANCE states, in code, which implementation guide each transaction set follows.
  • Zero runtime dependencies.
read-an-835.tsts
import { parseX12, get835 } from "@cosyte/x12";

const raw = `ISA*00*          *00*          *ZZ*MEDICARE       *ZZ*SUBMITTER      *260601*1200*^*00501*000000001*0*P*:~
GS*HP*MEDICARE*SUBMITTER*20260601*1200*1*X*005010X221A1~
ST*835*0001~
BPR*I*450.00*C*ACH*CCP*01*123456789*DA*987654321*1512345678**01*111111111*DA*222222222*20260601~
TRN*1*0012345*1512345678~
DTM*405*20260601~
N1*PR*MEDICARE PART A~
N3*123 PAYER WAY~
N4*BALTIMORE*MD*21244~
PER*BL*JANE COORDINATOR*TE*5551234567~
N1*PE*SAMPLE CLINIC INC~
N3*456 PROVIDER LN~
N4*CLEVELAND*OH*44113~
REF*TJ*123456789~
LX*1~
CLP*PT-ACCT-001*1*500.00*450.00*50.00*MC*PAYER-CLAIM-001*11*1~
NM1*QC*1*PATIENT*TEST*A***MI*MEMBER001~
NM1*82*2*RENDERING PROVIDER INC*****XX*1234567890~
DTM*232*20260501~
DTM*233*20260501~
SVC*HC:99213*500.00*450.00**1~
DTM*472*20260501~
CAS*PR*1*50.00~
REF*6R*LINE-CTRL-001~
SE*23*0001~
GE*1*1~
IEA*1*000000001~`;

const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "835");
if (tx === undefined) throw new Error("no 835 in this interchange");
const remit = get835(ix.delimiters, tx);
if (remit === undefined) throw new Error("not an 835");

// The payment, the claim's split, and who owes the difference and why.
const claim = remit.claims[0];
const adjustment = claim?.serviceLines[0]?.adjustments[0];
console.log("paid", remit.payment.totalActualPayment?.toString(), "by", remit.payment.method);
console.log("claim", claim?.patientControlNumber, "charged", claim?.totalChargeAmount?.toString());
console.log("patient owes", claim?.patientResponsibilityAmount?.toString());
console.log("reason", adjustment?.groupCode, adjustment?.reasonCode, adjustment?.reasonDescription);
console.log("warnings", ix.warnings.length);

// The values printed above, which the test suite asserts on every run:
remit.payment.totalActualPayment?.toString(); // => "450.00"
claim?.totalChargeAmount?.toString(); // => "500.00"
claim?.patientResponsibilityAmount?.toString(); // => "50.00"
adjustment?.groupCode; // => "PR"
adjustment?.reasonCode; // => "1"
adjustment?.reasonDescription; // => "Deductible Amount"
ix.warnings; // => []

From the @cosyte/x12 README on GitHub, verbatim. Every value in it is synthetic.

Limits

What it does not do.

Its README states what is not covered, deliberately:

  • A byte-exact round trip is not guaranteed in general. Line breaks between segments, for one, are absorbed on parse.
  • The two attachments transactions are typed at the base structure only; no implementation-guide usage is checked for them.
  • Healthcare transaction sets only. 850, 856, 810, 204 and EDIFACT are out of scope.
  • No transport: AS2 and SFTP are out of scope.
  • No revisions before 005010.

The full status and limits, in the README

Alternatives

What else you could use.

Each description comes from the project’s own documentation or listing, linked below.

Node.js library

node-x12

A general ASC X12 parser, generator, query engine and mapper for Node.js, MIT-licensed, with stream support. Its latest npm release dates from April 2022.

Source: npm, node-x12

Node.js library

x12-parser

An MIT-licensed X12 parser built on Node.js streams, for very large files, with no production dependencies.

Source: npm, x12-parser

Python library

pyx12

A BSD-licensed HIPAA X12 parser, validator and converter for Python. It validates a file against a representation of the X12 implementation guidelines and can create a 999 acknowledgement for 5010.

Source: PyPI, pyx12

EDI toolkit

EdiFabric

A toolkit for translating EDI inside your own applications, covering ten EDI standards, from X12 and HIPAA to EDIFACT, HL7 and NCPDP.

Source: EdiFabric

Clearinghouse

Stedi

A clearinghouse you integrate with through APIs. A clearinghouse reaches payers; a library such as @cosyte/x12 works with the transactions inside your own code but connects you to no one.

Source: Stedi documentation

Works with

  • NCPDPPharmacy claims use NCPDP Telecom rather than X12: @cosyte/ncpdp.
  • De-identification@cosyte/deid applies a HIPAA Safe Harbor policy to an X12 interchange.
  • @cosyte/synthGenerates synthetic 837P, 837I, 837D, 835 and 271 transactions for your tests.

Try @cosyte/x12 on your own messages.

It is free and MIT-licensed. If it saves you a day, a star on GitHub helps other engineers find it.

Need it integrated? Talk to us, or see what our integration services cover.