- 01LoadDelimiters are read from the ISA header, not assumed — a file using
| and \n parses just as well as * and ~.
- 02ReadFour views of the same interchange: the segments themselves, the structure they imply, one row per service line, and anything malformed.
- 03Configure and runShift service dates, swap a string, or both. Rules run in order, top to bottom. Creating a Limited Data Set is its own action, below them.
- 04Review, then downloadChanged segments are marked in the document and shown before and after under Changes. Nothing is written until you ask for it.
Reading a file
The four views
The Document tab is the interchange as it is: one row per segment, decoded, with an outline on the left to jump by transaction, claim or service line, and a filter that narrows by segment ID or value. Selecting a row opens the element inspector, which names every element, decodes its qualifiers, and splits composites into their parts.
The Tree tab shows the nesting the segments imply rather than their order on disk — the envelope, the HL hierarchy resolved through its parent pointers, then claims and service lines — with every group labelled by its 837P loop id. Anatomy of an 837 below is a reference for what those ids mean.
The Claims tab flattens the interchange into one row per service line — patient, date, procedure, modifiers, units, charge, diagnoses, payer — which is closer to how a claim is actually read than a list of segments is. A post-adjudicated file adds eight further columns for what was paid, adjusted and by whom; they appear only when the file carries such a transaction, since on an ordinary 837P they would be eight empty columns. Export CSV writes every row, not just the ones on screen.
The Checks tab reports what is structurally wrong with the file rather than what is in it, and carries a badge with the count so a clean file says so without being opened.
Post-adjudicated reports
An 837 is usually a claim being submitted. 005010X298 — post-adjudicated claims data reporting, PACDR — is the same transaction sent the other way: a payer reporting claims it has already paid, to a state agency collecting them. It is recognised from ST-03, or from the GS-08 above it, or failing both from BHT-06, which reads RP for a report where a submission reads CH.
Structurally it is the 837P you already know: same loops, same nesting, same ids. What changes is meaning, and two loops change names because of it. 2010BB is the data receiver — the agency being reported to, which has paid nothing — rather than the payer. The payer that actually adjudicated the claim is the 2330B inside each 2320, and there is one 2320 per payer, with a 2430 per payer per service line carrying what that payer paid on it. The Claims tab reads the payer column from there for these files, and the Tree tab labels both loops by what they mean here.
Which payer is primary comes from SBR-01, never from the order the loops appear in: a report is free to emit the secondary payer's block first, and real ones do.
835 remittance advice
005010X221A1 is a different transaction from the 837, not a variant of it: a payer telling a provider what it paid, adjusted and why, rather than a provider submitting a claim. It is recognised from ST-01, which names the transaction set outright, so there is no guide-detection question the way PACDR has one.
Its loops replace the 837's rather than reusing them. N1*PR and N1*PE — not NM1 — open the payer and payee. LX opens an optional grouping of claims (loop 2000), not a service line. CLP opens a claim (2100) and SVC a service line's payment (2110). PLB, provider-level balance, sits after every claim and before SE — a transaction-level adjustment, never inside one.
The Claims tab stays empty for an 835 by design: it flattens a provider's submission into one row per service line, and there is no submission here to flatten. Checks reads the payment instead — see below.
Reading only, in this version. Nothing here decodes a CARC or RARC reason code, and the Limited Data Set does not reach an 835's patient identifiers — NM1*QC/NM1*IL sit directly inside loop 2100, outside the loops that rule targets, so an 835 handed through Limited Data Set comes back byte-identical, not scrubbed.
What Checks looks at
Three kinds of problem, all of which are invisible until someone else rejects the file.
- Control counts and envelopes
SE-01 must equal the number of segments from ST to SE inclusive, GE-01 the number of transaction sets in the group, and IEA-01 the number of groups. Each trailer's control number must match the header that opened it. These are how a receiver detects a truncated transmission, so a file that disagrees with itself is refused before the claims are read at all.
- Claim balance
CLM-02 is compared against the charges on the claim's service lines. Amounts are compared as whole cents, so a file that balances is never reported as off by a rounding error. A line charge that isn't a number is reported on its own, and the claim total check is skipped rather than measured against a sum that can't be computed.
- Post-adjudicated claims
- Only for a PACDR transaction, and all warnings rather than errors. Each payer's
2320 AMT*D is compared against the SVD-02 amounts on its own 2430s — but only where that payer reported every line, since adjudicating at claim level alone is legal. Each 2430 has to account for something: its SVD-02 plus its CAS adjustments must come to either the line charge or a patient responsibility another payer left on the same line. And every SVD-01 must name a payer the claim identifies in a 2330B.
- Deliberately a choice of two rather than a chain from payer to payer: two payers can each adjudicate the whole charge independently, and where the only adjustment is contractual there is no patient responsibility to chain from at all. What is checked is arithmetic and cross-referencing inside the file. Nothing here validates a file against a particular recipient's companion guide — contract codes, trading partner id formats, remark codes and which payer must appear are that recipient's policy, they differ between them, and encoding one would make the app wrong for everyone else.
- 835 balancing
- Only for an 835, and all warnings. Per line,
SVC-02 minus its CAS adjustments should equal SVC-03. Per claim, CLP-03 minus every CAS on it — claim-level and line-level together — should equal CLP-04. And once BPR-03 states a credit, the total payment should equal every claim's CLP-04 minus every PLB-04 adjustment on the transaction — a positive PLB-04 reduces what was paid. A reversed claim (CLP-02 = 22) balances under the same three rules; nothing here assumes a positive amount. A blank amount stands the relevant check down silently; one that is present but unreadable is reported on its own and stands it down as well.
Selecting a finding jumps to the segment it came from. Nothing here changes the file — but if a rule ever adds or removes a segment, the control counts are corrected automatically on the way out, since every count above the change would otherwise be wrong.
Hiding identifiers on screen
The eye button in the header hides names, addresses, dates of birth, member IDs and social security numbers wherever they appear, so a real file can be browsed or screen-shared without putting identifiers in front of the room. It is a display setting only: the file you download always carries the real values, and a CSV exported while masking is on is named _masked to record which one you have. To change the file itself rather than the view, use Limited Data Set below.
Making test data
What the rules do
- Service date shift
- Moves every
DTP*472 date that sits inside a service line (loop 2400) — the ones opened by LX and closed by CLM, HL, or SE. Claim-level dates are left alone. Negative values shift backwards. Impossible dates are skipped rather than failing the file.
- Find & replace
- Rewrites element values only. Segment IDs are never touched, and neither is the fixed-width
ISA header — changing a value's length there breaks the interchange for the receiver. Scope it to specific segments to keep a common string from being rewritten everywhere.
- Anywhere matches a substring of any element. Whole element matches only when the entire element is the search text. Whole component splits composites first, so in
SV1*HC:99213:25 it can match 99213 on its own — whole element cannot, because there the element is HC:99213:25.
- Replacement text containing this file's element separator or segment terminator is rejected rather than written, because it would split the segment it landed in. The component separator is allowed, since it is legal inside an element value.
Limited Data Set
Create Limited Data Set is a separate action from the rules, and ignores whether they are switched on. It produces a HIPAA Limited Data Set (45 CFR 164.514(e)): the direct identifiers are removed, while dates and city, state and ZIP are kept.
The output is still PHI. A limited data set is not de-identified data under HIPAA. De-identification is §164.514(b) — Safe Harbor, or an expert determination — and data de-identified that way stops being PHI and carries no further HIPAA restriction. A limited data set under §164.514(e) is a weaker thing: it remains protected health information, may only be disclosed for research, public health or health care operations, and requires a data use agreement with whoever receives it. This tool is not an expert determination and none of this is legal advice.
Safe Harbor is not offered because it cannot be expressed in a valid 837 — see Dates below.
- What is replaced
- Inside the subscriber, patient and other-subscriber loops (2010BA, 2010CA, 2330A) only: names and member ids on
NM1, street address on N3, contact details on PER, social security (REF*SY) and medical record (REF*EA) numbers. Patient account numbers on CLM-01 are renumbered, keeping one fake number per real one so distinct claims stay distinct.
- What is kept
- City, state and ZIP on
N4, and every provider — billing, rendering, referring, supervising, facility. An NPI, a provider name and a tax ID are not patient information, and a file whose providers no longer exist is much less useful as test data. Targeting is by loop rather than by name shape, which is what keeps NM1*82 and NM1*DN — both real people — untouched.
- Dates
- Shifted, not removed. Each patient gets one offset of up to 180 days in either direction, applied to their date of birth and to every date inside their claims, so intervals, sequencing and timely-filing behaviour survive. Safe Harbor's year-only rule cannot be expressed in a valid 837 —
D8 is CCYYMMDD and DTP*472 is required on every service line — so it would force every date to YYYY0101 and destroy exactly what makes the file testable.
- Consistency and reversibility
- One person keeps one identity across the whole file: the mapping is keyed on the person — member id where there is one, otherwise name and date of birth — so two claims for the same member get the same fake name and the same fake member id. The mapping is drawn fresh for each run, held in memory, and never written or exported, so the run is one-way and two runs of the same file produce different people.
Reference
Anatomy of an 837
A claim file is three envelopes deep before a claim appears. ISA opens the interchange — one transmission between two trading partners — and carries the delimiters every other segment is read with. GS opens a functional group of like transactions. ST opens one transaction set: for an 837 that is one batch of claims. Each is closed by a matching trailer in reverse order, SE, GE, IEA, and each trailer repeats a count and a control number that the receiver checks before reading anything.
Inside the transaction, claims are not a flat list. HL segments build a hierarchy: the billing provider comes first, the subscriber hangs beneath it, and a patient loop appears only when the patient is someone other than the subscriber — a child on a parent's policy, say. Each HL carries its own id and a pointer to its parent's, which is what makes the nesting recoverable. CLM then opens a claim, and LX opens each service line within it.
The implementation guide numbers every one of those positions — 2010BA is the subscriber's name, 2400 a service line. The number matters because the same segment means different things in different places: NM1*82 is loop 2310B under a claim and 2420A under a service line. The Tree tab labels each group with the loop it resolved to, and the tables below are that same knowledge, listed out — including the two loops a post-adjudicated report calls something else, shown beside their 837P names.
Loops
Each loop, the segment that opens it, and where it sits. Generated from the loop tables the Tree tab resolves against.
835 loops
The remittance advice's own five loops, listed separately: several loop ids mean something different here than they do in an 837 above — 1000A is the payer, not the submitter — so relabelling under an alternate name would misdescribe the relationship rather than clarify it.
Segments
What each segment id stands for. These are the names shown beside every row in the Document tab.
Qualifier codes
Codes that change what the rest of a segment means. The element inspector decodes these in place when you open a segment.
Privacy
Where your file goes
Nowhere. It is read in this tab, edited in memory, and handed back through your browser's download. Nothing is uploaded, no server is involved, and nothing persists after you close the tab — which is also why a Limited Data Set mapping cannot be recovered once the run is done.
Using it with real data
That nothing is transmitted describes how this app works; it is not a compliance guarantee, and it is the only assurance offered. If the file you opened carries PHI, handling it stays your responsibility — every obligation that applied to it beforehand applies still, the download lands on your disk unencrypted, and masking changes only what is on screen.
One limitation worth knowing: the Limited Data Set rewrites named fields in the loops it recognises. Free-text elements — notes (NTE), file information (K3) and the like — can carry names or identifiers, and nothing here detects or removes them. Review those yourself before treating output as safe to share.
Provided as-is, without warranty of any kind. None of this is legal advice, and whether a given use is permitted is yours to decide.