45 sec
vs. 10 min for manual appeal packet assembly
12
CO denial codes mapped to appeal letter logic
2
Payment sources automated: ERA & scanned EOB
1
PM owning process design, AI training & reporting end-to-end
The Situation
A revenue cycle team buried in repetitive, high-stakes manual work.
Every denied claim required a billing staff member to manually identify the denial code, locate the right appeal letter template, retrieve the EOB (either from the system or via fax), generate the claim form, pull medical records, assemble everything into a packet, save it to the patient's chart, and update the collections record — roughly 10 minutes per claim, multiplied across hundreds of denials a day.
Payment posting carried a different but equally heavy burden. Some payments arrived as electronic remittances (ERA) that could be matched and posted directly in the system. Others arrived as scanned EOB packets, faxed weekly from facilities — sometimes dozens of EOBs in a single document, with inconsistent scan quality, payer-specific terminology, and reimbursement math that staff had to interpret and calculate by hand.
The assignment: As the sole product manager on this initiative, define the end-to-end process logic, AI training requirements, and human-in-the-loop design for two automated workflows — denial appeal packet assembly and payment posting (both ERA and scanned EOB) — for an enterprise EMR/RCM platform.
The Challenge
Two very different automation problems, both with no margin for error.
Denial Appeals
- 12 distinct CO denial codes (CO97, CO279, CO234, CO50, CO150, CO167, CO222, CO226, CO251, CO252, CO96, CO29), each mapping to a specific appeal letter template with its own logic and required language
- The EOB itself could live in two different places depending on a payment code (electronic vs. fax-retrieved) — the bot had to determine which path applied for every claim
- Medical records had multiple possible sources and formats (chart files vs. EHR, signed vs. unsigned, narrative print vs. word merge vs. PDF) — and the bot had to know exactly when records were unavailable and the packet should be blocked
- Multiple denial codes on a single claim required a defined precedence rule, and missing codes required a fallback path — both with distinct statuses
Payment Posting
- ERA payments could often be matched and posted automatically based on check number, carrier, and amount
- EOB payments were the hard problem — these arrived as scanned, faxed packets (sometimes containing dozens of patients' EOBs in one file), with inconsistent formatting, scan quality, and terminology across payers
- The bot had to be trained to read these scans, locate the right patient/visit/EOB within a multi-page packet, and correctly calculate allowed amounts, adjustments, write-offs, and patient responsibility — interpreting CARC/RARC reason codes that vary by payer
- Every payment line required the correct combination of payment code, reason code, and write-off logic — get any one wrong and the claim balance would be incorrect
The Approach
Document the logic a 10-year billing veteran knows by instinct — then teach it to a bot.
01
Process Definition
Mapped the complete denial appeal workflow: denial code identification, appeal letter logic, EOB/HCFA/medical records retrieval paths, packet assembly, and chart filing — including every blocked/needs-review condition
02
AI Training: ERA
Defined matching logic for electronic remittances — check number, carrier, and amount — to enable high-confidence auto-posting
03
AI Training: Scanned EOBs
The hardest phase — built a payer-by-payer normalization framework and global mapping rules to read inconsistent, unstructured EOB formats
04
Human-in-the-Loop & Audit
Defined exactly when the bot auto-completes vs. routes to staff (Completed / Needs Review / Blocked), and designed dual reporting
Phase 03 was the hardest part of the project. Across more than a dozen payers, the same data point — the amount the insurance allows for a service — appeared under entirely different labels: “Allowed Amount,” “Eligible Expense,” “Contract Allowance,” “Payable,” “Allowed/QPA.” The same was true for write-offs (“Provider Discount,” “Disallowed,” “Fee Reduction/Excluded,” “Not Covered”), and for the patient's portion (“Patient Liability,” “Member Owe,” “Patient Resp.,” or “Co-Pay/Co-Insurance/Deductible” as three separate fields).
I built a normalization framework — a payer-by-payer field map plus a single AI prompt with global mapping rules — that taught the bot to:
- Identify the correct carrier/payer name even when the provider's name, a third-party administrator, and the actual payer all appear on the same page
- Reconstruct stacked or vertically-printed column headers into their correct full labels without bleeding into adjacent columns
- Preserve exact formatting of check numbers (including leading zeros and trailing letters), dollar signs (including negative reversals), and dates (normalizing to MM/DD/YYYY regardless of how the payer printed them)
- Apply a zero-payment override rule — if an EOB explicitly states no payment was issued, the bot leaves the check number blank rather than guessing
- Parse multi-patient, multi-page scanned packets — faxed weekly from facilities — to locate the correct patient, claim, and service line within the document
- Calculate or cross-check allowed amounts, write-offs, and patient responsibility when a payer's EOB doesn't print all three (since two of the three can always be derived from the third)
This wasn't a one-time prompt — it was a living specification, refined payer by payer as new EOB formats surfaced. The mapping covered carriers including Aetna, Humana, UnitedHealthcare (Optum Pay), BlueCross BlueShield, Cigna, UMR, NALC, Amguard, Premera, Employee Benefit Systems, Medical Mutual, Allegiance, and Nationwide.
Aetna
Humana
UnitedHealthcare (Optum Pay)
BlueCross BlueShield
Cigna
UMR
NALC
Amguard
Premera
Employee Benefit Systems
Medical Mutual
Allegiance
Nationwide
What Was Delivered
A fully documented, trainable process — covering the easy data and the hard data.
Denial Appeal Automation
- Identifies appeal-eligible CO denial codes and selects the correct appeal letter template
- Assembles the complete packet — appeal letter, EOB, claim form, and medical records — and files it to the patient's chart
- Applies clear status logic: Completed, Needs Review (multiple codes or no code found), or Blocked (missing medical records)
- Writes a per-claim audit note to the patient's collections record and routes the visit for follow-up
ERA & EOB Payment Posting
- Auto-matches and posts electronic remittances (ERA) based on check number, carrier, and amount
- Reads scanned, multi-patient EOB packets — trained on payer-specific terminology, varying formats, and scan quality — to locate the correct patient, visit, and payment line
- Applies the correct payment codes, CARC/RARC reason codes, and write-off logic to post each line accurately
- Routes any payment line that can't be confidently interpreted to staff for manual review
Daily Productivity & Audit Reporting
- A daily report covering every claim processed: patient, visit, date of service, carrier, denial codes, components generated, and final status
- Per-claim history notes give staff a record they can search and review at any time — not just an overnight summary
The Outcomes
From 10 minutes of manual assembly to 45 seconds of AI processing — for the easy cases. For the hard cases, an AI that finally understands the paperwork.
10min → 45s
Denial appeal packet assembly time
2 for 2
Both ERA and scanned EOB payments now automated
100%
Auditable: daily reporting plus per-claim history notes
- Denial appeal packets that previously took ~10 minutes of manual assembly are now completed by the AI in approximately 45 seconds
- Electronic remittance posting is automated for high-confidence matches
- Scanned EOB packets — previously a pure manual-entry bottleneck — are now read, interpreted, and posted by a trained AI agent
- Every action is auditable: a daily productivity report plus per-claim history notes give staff full visibility and an easy way to catch and correct errors
- Clear status logic (Completed / Needs Review / Blocked) ensures ambiguous or incomplete cases are never silently mishandled — they're routed to a human, every time
Reflection
What this project taught me.
“Posting an ERA is the easy version of this problem — the data is already structured. The real work was the scanned EOB packets: faxed weekly, sometimes dozens of patients in one file, every payer using slightly different language for the same thing. Teaching the bot to find the right EOB in that packet, read it despite a bad scan, and do the math correctly — that's not a prompt, that's a process. You have to document every variation a human would recognize instinctively, because the bot won't recognize anything you didn't tell it about.”
This project reinforced that AI automation in revenue cycle isn't about replacing judgment — it's about encoding judgment so clearly that a system can apply it consistently, and flagging the moment that judgment runs out. The blocked/needs-review logic wasn't a limitation of the AI — it was the most important design decision in the whole project.