Automating Reconciliation: Processing Line-Level 835s Alongside Instant Payments
A deposit tells you how much. It does not tell you what for.
That distinction is survivable when money moves on ACH and the remittance advice has been sitting in your clearinghouse mailbox for two days. It stops being survivable the moment you shorten settlement. Once funds are final and available within seconds of a payer releasing them, the X12 835 becomes the long pole, and every hour it lags is an hour of cash you cannot post, cannot apply to a patient ledger, and cannot report on.
For an independent practice this is not a banking project. It is a parsing project. This article covers why the arrival gap opens, what the 835 carries below the claim level, one synthetic remittance where a $78.68 deposit sits against $74.56 in claim payments, and what a pipeline needs before you let it post without a human watching.
When the money lands before the explanation
Adjudication produces two artifacts on two independent pipes. The payment instruction goes to the payer's payment vendor and out to a bank. The 835 goes to your clearinghouse mailbox on its own schedule. Nothing coordinates them, and nothing ever did — ACH just hid the problem by being slower than the file.
Instant rails also remove the mechanism that used to close the loop. Under the CAQH CORE reassociation rule, a payer sending EFT via ACH carries the TRN02 trace number in the CCD+ addenda record, so the credit on your bank statement literally contains the key that binds it to a remittance [verify current CORE rule version]. That addenda record is small — on the order of 80 characters of payment-related data — and the ISO 20022 messages behind FedNow and RTP carry a comparably thin unstructured remittance field, roughly 140 characters [verify field lengths with your financial institution]. Either way you receive a reference, not a remittance. The reference is enough to match against, and nothing more.
So the matching has to happen in your system, from the file, at the line. Which means the file has to be parsed correctly first.
The 835 below the claim: what claim-level posting throws away
An 835 is a nested envelope, and the nesting carries the meaning:
- Transaction header —
BPR(amount, method, routing),TRN(reassociation trace),DTM*405(production date),N1*PR/N1*PEpayer and payee loops - Loop 2100 — claim —
CLP(your patient control number, claim status, total charge, paid, patient responsibility, payer ICN), claim-levelCAS,MOA/MIA,LQremark codes - Loop 2110 — service line —
SVC(adjudicated procedure, line charge, line paid, units), line-levelCAS,REF*6Rline item control number,DTM*472service date - `PLB` — provider-level adjustments that sit entirely outside the claims
Three balancing identities hold in a well-formed file, and each is a test you can execute rather than a convention you trust:
- Line:
SVC02=SVC03+ the sum of that line'sCASamounts - Claim:
CLP03−CLP04= the sum of all claim- and line-levelCASamounts - Transaction:
BPR02= the sum of allCLP04− the sum of allPLBamounts
Most practice management systems auto-post CLP04 and discard loop 2110. That is not a bug; it is a design choice made when the ledger only needed to know that a claim closed. Its cost is that every line-level denial, bundle, and downcode inside a claim that paid something becomes invisible, and identity #3 never gets run — which is why "the deposit doesn't match" becomes a monthly chore instead of an exception.
Worked example: a 78.68 deposit against 74.56 in claim payments
One remittance. Three CLP loops covering two encounters, four service lines, one interest adjustment. All identifiers, dates, and dollar figures are synthetic and contain no patient data. The component separator is :, as declared in ISA16.
BPR*I*78.68*C*ACH*CCP*01*091000019*DA*0001234567*1932847561**01*021000021*DA*9876543210*20260813~
TRN*1*20260812B7740318*1932847561~
DTM*405*20260812~
CLP*PCN-90417*22*-310.00*-129.12*-32.28*12*ICN-2026-0715-2210*11*1~
SVC*HC:99215*-310.00*-129.12**-1~
DTM*472*20260629~
CAS*CO*45*-148.60~
CAS*PR*2*-32.28~
REF*6R*L-90417-01~
CLP*PCN-90417*1*310.00*94.24*67.16*12*ICN-2026-0812-6631*11*1~
SVC*HC:99215*310.00*94.24**1~
DTM*472*20260629~
CAS*CO*45*148.60~
CAS*PR*1*43.60~
CAS*PR*2*23.56~
REF*6R*L-90417-01~
CLP*PCN-90512*1*307.00*109.44*27.36*12*ICN-2026-0812-6632*11*1~
SVC*HC:99214*285.00*109.44**1~
DTM*472*20260731~
CAS*CO*45*148.20~
CAS*PR*2*27.36~
REF*6R*L-90512-01~
SVC*HC:36415*22.00*0.00**1~
DTM*472*20260731~
CAS*CO*97*22.00~
REF*6R*L-90512-02~
PLB*1932847561*20261231*L6:ICN-2026-0611-8842*-4.12~Every line balances — SVC02 = SVC03 + the sum of that line's CAS:
- 99215, reversed —
-310.00 = -129.12 + (-148.60 CO-45) + (-32.28 PR-2)✓ - 99215, reprocessed —
310.00 = 94.24 + 148.60 (CO-45) + 43.60 (PR-1) + 23.56 (PR-2)✓ - 99214 —
285.00 = 109.44 + 148.20 (CO-45) + 27.36 (PR-2)✓ - 36415 —
22.00 = 0.00 + 22.00 (CO-97)✓
Each claim ties out. PCN-90417 reversal: -310.00 − (-180.88) = -129.12 ✓. PCN-90417 reprocessed: 310.00 − 215.76 = 94.24 ✓. PCN-90512: 307.00 − 197.56 = 109.44 ✓.
And the transaction ties out — the identity claim-level posting never runs. Claim payments sum to -129.12 + 94.24 + 109.44 = 74.56. BPR02 is 78.68. The $4.12 difference is the PLB: an L6 interest adjustment on a June claim. The amount is negative, so it increases the deposit. A pipeline that assumes PLB always reduces a payment will be off by twice the amount, in the wrong direction.
Three things here exist only at the line:
A reversal and a reprocess in the same file. CLP02 = 22 marks a reversal of a previous payment; the following CLP is the corrected adjudication of the same PCN-90417, under a new ICN. Post both as receipts and you double-count. Post only the second and you never claw back the first. The net effect on the payer's payment is -129.12 + 94.24 = -34.88.
A retroactive deductible, and the arithmetic that reveals it. The reprocess added PR-1 of $43.60 — a deductible the payer applied after the fact. But coinsurance recalculated against the smaller remaining allowed amount, dropping from $32.28 to $23.56. Net new patient responsibility is -32.28 + 67.16 = $34.88, not $43.60. It matches the payer's payment reduction exactly, because the contractual write-off never moved: the payer shifted $34.88 of liability from itself to the patient and changed nothing else. Billing the patient $43.60 overstates the balance by $9.72. This is the figure that should drive initiating secure requests-for-payment for remaining patient balances — computed from the reversal pair, not read off one segment.
A zero-paid line inside a claim that paid. 36415 was denied CO-97 (bundled into another adjudicated service). CO is contractual obligation — provider liability. It is not billable to the patient, and at claim level it is indistinguishable from a line that was never submitted.
Architecting the zero-touch pipeline
"Zero-touch" does not mean no humans. It means the pipeline has exactly one human-facing output — an exception queue with an owner and an age report — and everything else posts itself.
Matching runs as an ordered sequence of keys, each with a defined fallback and a defined failure state. Deposit to remittance: TRN02 against the rail's reference field, with BPR02 as a check on that match rather than a key. Claim to claim: CLP01 plus CLP07, storing the payer ICN on first receipt so reversals and replays resolve to the original encounter. Line to charge: the REF*6R you echoed on the 837, falling back to SVC01 + units + charge — and flagging the claim when it does, because repeated CPTs collide on bilateral procedures and repeat labs. Provider adjustment to prior claim: the PLB03 composite reference, which points at a claim that may already be closed on your books.
Two invariants make this safe unattended. Idempotency: derive a posting key from payer ID, CLP07, CLP02, TRN02, and the line control number, so a re-sent file posts nothing twice — and note that CLP02 is part of the key, which is what keeps a reversal from colliding with its own correction. Suspense before certainty: an instant credit with no matched 835 lands in unapplied cash and never touches a patient ledger. No statement, no balance, no phone call.
Against the file above, the difference between the two designs is concrete:
| Event in the remittance | Claim-level auto-posting records | Line-level pipeline records | Consequence of the gap |
|---|---|---|---|
CLP02*22 reversal, -$129.12 | A negative receipt, often as an unexplained adjustment | Reversal bound to ICN-2026-0715-2210, prior posting backed out | Encounter shows a phantom credit balance |
Reprocessed claim, +$94.24 | $94.24 received | Net -$34.88 vs. original, tied to the same PCN | Two receipts logged for one encounter |
New PR-1 $43.60 | Patient responsibility $67.16 | Net new balance $34.88 after netting the reversal | Patient billed $9.72 over |
36415 denied CO-97 | Nothing — claim paid | Zero-paid line, CO group, not patient-billable | Bundling pattern never surfaces for review |
PLB L6 -$4.12 | Not read | Interest income, referencing a June claim | Deposit is permanently "off by $4.12" |
BPR02 $78.68 | Not reconciled to claims | 74.56 − (−4.12) = 78.68 ✓ | Tie-out becomes manual, monthly |
Before you let any of this run unattended, get four things true: the pipeline rejects a file that fails any of the three balancing identities rather than posting a partial; reversals and corrections are handled as a matched pair, not two independent receipts; unmatched credits sit in a real suspense account with an aging report; and every heuristic line match is flagged rather than silently accepted.
FAQ
Our payer sends reversals and corrections in the same file. Do we post both, or just the net? Post both, and net them in the ledger — do not net them in the parser. The reversal carries the original ICN and the correction carries a new one; you need both stored to answer "what happened to this encounter" six months from now, and to appeal if the reprocess was wrong. Netting at parse time destroys the audit trail and makes the transaction-level tie-out unverifiable. In the example above, the ledger should show a -$129.12 reversal and a +$94.24 posting against PCN-90417, with a derived net of -$34.88.
The deposit was larger than the sum of our claim payments. Where did the extra money come from? Almost always a PLB with a negative amount — most commonly L6 interest owed on a late-adjudicated claim, though the reason code list changes and your payer's companion guide governs [verify the current PLB reason code list]. Negative PLB amounts increase the deposit; positive ones (WO overpayment recovery, FB forwarding balance) reduce it. A parser that takes absolute values of PLB or CAS amounts will corrupt the tie-out in a way that looks like a rounding error and is not.
What has to be true before we stop reviewing every posting? Run the pipeline in shadow mode against files you have already posted by hand, and compare. You are looking for three specific disagreements: lines your current system never recorded, deposits where BPR02 did not equal claim payments net of PLB, and patient balances that differ from what you actually billed. When the pipeline's exception queue is the only place a human is needed and its contents are genuinely ambiguous rather than merely unimplemented, you are there. Measure this on your own remittances rather than accepting a vendor figure — including a vendor's.
Run it against your own remittance
The shteg.ai sandbox accepts a de-identified 835 and returns the parse: service-line balancing validated on every SVC (SVC02 = SVC03 + CAS), claim tie-out against CLP03 − CLP04, transaction tie-out of BPR02 against claim payments net of PLB with signs preserved, reversal and correction pairs matched by payer ICN, the PR-group total isolated as the billable patient amount, and every line that resolved by heuristic because REF*6R was absent.
Bring a file containing a reversal, and a file where the deposit didn't equal the claim payments. Those two will tell you more about your current posting logic than a clean month ever will.
[Open the shteg.ai sandbox →](/sandbox) [verify link target before publish]
Educational content for physicians, practice administrators, and revenue-cycle staff. Not legal, billing, coding, or compliance advice. All segment values, claim identifiers, control numbers, dates, and dollar figures in this article are synthetic illustrations and contain no patient data. X12 835 specifications, CARC and RARC code lists, PLB reason codes, CAQH CORE operating rules, Nacha rules, and FedNow and RTP message capabilities change over time — verify current specifications with your clearinghouse, payers, and financial institution before making operational decisions. Patient billing and balance-billing restrictions are governed by your payer contracts and by applicable state and federal law; consult counsel for your jurisdiction.
Draft notes: ~1,720 words. H1 + 6 H2s (4 body + FAQ + CTA), inside the 4–6 spec. Covers all five outline items from fast-payment-mssl22mx.md §Brief 2 — async arrival, 835 anatomy, algorithmic deposit↔claim-ID matching, denials/adjustments/patient responsibility, zero-touch pipeline architecture — with items 3 and 5 merged into one H2 to hold the section count. Carries the brief's prescribed 2→3 link with the specified anchor text, placed in the patient-responsibility discussion as directed.
Worked example is arithmetically closed and independently checkable: SVC02 = SVC03 + CAS on all four lines including the sign-reversed pair, claim tie-out on all three CLPs, transaction tie-out 74.56 − (−4.12) = 78.68. The load-bearing construction is the reversal/reprocess pair where net patient responsibility ($34.88) ≠ the new PR-1 ($43.60) because coinsurance recalculated — that invariant (Δpaid = −ΔPR when the contractual write-off is unchanged) is what makes line-level netting non-optional rather than merely tidy. Single comparison table, mapping each event in the file to both posting designs.
Six [verify] flags. No statistics asserted; the FAQ explicitly declines a vendor figure. PR-vs-CO billability guardrail stated for the CO-97 line. No weekday claims made, so no calendar exposure.
Differentiation check: deliberately disjoint from fast-payment-2-mssks75l.md (written against the superseded mssjoj9x brief) — that draft uses a WO recoupment that reduces the deposit, a settlement timeline, and a matching-key table; this one uses a reversal pair plus negative-PLB interest that increases it, no timeline, and a design-comparison table. Shared surface is the 835 anatomy list and the three identities, which are unavoidable primitives. If both ship in the same cluster, one should be retired — they answer the same query intent.
Blocking before publish: needs a named revenue-cycle or billing reviewer for the reversal-netting and PLB sign claims. Both link targets (/blog/hipaa-safe-request-for-payment-patient-balances, /sandbox) are guesses at eventual slugs.
Want me to save this to examples/seo-presence/workspace/drafts/fast-payment-2-<id>.md? The pipeline uses a short base-36 timestamp slug — give me one, or say the word and I'll generate it.
<!-- generated_by: claude-draft-1 -->