Inspiration
US hospitals receive an estimated $260–300B in claim denials annually — and roughly 65% are never appealed. Not because appeals fail (they carry a ~3:1 ROI), but because the manual process is brutally slow: download the denial, look up reason codes, pull the chart, write a payer-specific letter, submit, track in a spreadsheet. Each appeal takes 45–60 minutes. A 500-bed hospital gets 500–1,000 denials a month and can only touch 20–30% before timely-filing deadlines pass. The constraint isn't viability — it's bandwidth.
California's SB 1120 (Physicians Make Decisions Act, effective Jan 1 2025) added a regulatory dimension: every medical-necessity determination must be made by a licensed clinician, not an algorithm. That's both a compliance mandate and a design constraint that funded competitors (payer-side tools like Cohere Health) can't satisfy by construction.
We built Ctrl+Appeal to close that gap.
What it does
Ctrl+Appeal is an agentic denial management and appeals automation system built entirely on UiPath Cloud. It ingests denials from any source, classifies each into one of five routes, handles each route end-to-end, and keeps a physician in the loop for every medical-necessity determination.
The five denial routes handled:
- Medical Necessity (CO-50, CO-151) — RAG over the payer's own medical policy → AI-drafted appeal citing criteria the reviewer missed → physician sign-off via Action Center
- Eligibility (CO-27, CO-31) — Re-verify eligibility at date of service → resubmit or move to patient responsibility
- Coding Error (CO-4, CO-11) — Coder corrects CPT/ICD → resubmit corrected claim
- Duplicate (CO-18) — ICN-first composite-key claims history match → close if true duplicate, else appeal as distinct service
- Timely Filing (CO-29) — Deadline math against payer filing-limit table → file exception with proof of timely submission, or write-off
The seven-phase process:
- Ingestion — 835 ERA files, payer portal RPA, and faxed denial letters via Document Understanding/OCR, all normalized into a single Data Fabric entity
- Classification & Routing — LangGraph classification agent maps CARC/RARC codes to a deterministic route in under a second
- Medical Necessity Appeal — LangChain RAG over the payer's medical policy (e.g. Meridian MP-114 §4.2), mapping each criterion to chart evidence, surfacing what the reviewer missed
- Human Review — Billing specialist sees the AI-drafted appeal side-by-side with the denial in a UiPath App; physician attestation required for medical necessity (SB 1120 gate)
- Submission — X12 835 resubmission, fax, or payer portal RPA depending on payer capability
- Response Tracking — Long-running tracking agent with 30/60/90-day timer events; handles approved, partial, pended, and re-denied outcomes
- Analytics & Learning Loop — Win-rate by payer and denial type feeds back into the appeal template library
Hero case: David Okafor, sepsis inpatient, CO-50 denial from Meridian. The system RAGs MP-114 §4.2, finds criteria the reviewer missed, drafts the appeal letter, routes to physician attestation in Action Center — appeal approved.
How we built it
The entire system runs on UiPath Cloud — no desktop dependencies, no on-prem Orchestrator.
| Component | Role |
|---|---|
| Maestro BPMN | 5-branch exclusive gateway, 7-phase orchestration, long-running timer events |
| Agent Builder | Ingestion Agent, Classification Agent (LangGraph), Appeal Drafter Agent |
| Data Fabric | IngestionData entity, classification persistence, payer policy store |
| Action Center | Specialist review queue, physician attestation tasks (SB 1120 gate) |
| Studio Web | All process logic and Data Fabric R/W — zero desktop activities |
The classification agent is a LangGraph coded agent (adapted from UiPath's starter template) deployed via Agent Builder, running Claude Haiku via UiPath's Bedrock wrapper. Pattern: prepare → react_agent → postprocess. It reads CARC/RARC/DOS/billed/denied/paid from Data Fabric, applies a deterministic CARC→route table with RARC refinement and partial-denial detection, and returns record_id, denial_classification, and requires_human. Guardrails: confidence floor of 0.70 → human; medical_necessity → always human (SB 1120); unknown/conflicting CARC → defaults to eligibility + human. Write is decoupled from the agent — a downstream Maestro step persists the result for reliability.
External agentic coded logic was built with Claude Code (Anthropic), qualifying for the external coding agent judging bonus.
The test dataset covers 3 fictional payers (Meridian/Medicare Advantage, Atlas/Commercial PPO, BlueRiver/Medicaid MCO) and one fictional provider (Lakeview Regional), with 88 gold-labeled denials for routing accuracy measurement, plus fully wired X12 835 files, denial letter PDFs (clean and scanned/OCR), payer policy PDFs, and appeal templates.
Challenges we ran into
- Write reliability in agentic flows — Early versions had the classification agent writing results directly to Data Fabric, which created race conditions with downstream Maestro steps. Decoupling write from the agent and handling persistence in a dedicated Maestro activity resolved this.
- LangGraph + UiPath Bedrock wrapper — Adapting the starter template to use Claude Haiku via UiPath's Bedrock wrapper required careful prompt engineering to maintain deterministic CARC routing while still leveraging the ReAct pattern for edge-case resolution.
- SB 1120 compliance by architecture — Ensuring the medical necessity gate is enforced structurally (not just by convention) meant building the Maestro BPMN so that
requires_human = trueis the only path out of that branch, with no bypass. - Synthetic test data fidelity — Building a test dataset realistic enough to validate routing accuracy (internally consistent X12 835 files, multi-payer denial letters, payer policy PDFs) without using real PHI was a significant upfront investment.
Accomplishments that we're proud of
- SB 1120 compliant by construction — The physician is structurally in the loop, not optionally. No bypass exists in the BPMN.
- Policy-RAG appeal generation — The system cites the payer's own medical policy criteria back to them, specifically the ones their reviewer missed. That's a qualitatively different appeal than a template.
- Working classification agent — The LangGraph agent is deployed and returning correct
denial_classificationvalues against our gold-label test set. - Full-stack synthetic dataset — 88 labeled denials, X12 835 files, denial letter PDFs, payer policy documents, and appeal outcomes — a complete evaluation artifact.
- Provider-side positioning — Every funded competitor in this space is payer-side. We are explicitly not.
What we learned
- Agentic reliability requires decoupling: agents should read and reason, not write. Persistence belongs in the orchestration layer.
- RAG over structured policy documents (with section references like §4.2) requires careful chunking strategy — naive sentence splitting loses the criterion-level granularity that makes the appeal defensible.
- UiPath Maestro's BPMN exclusive gateway is a genuinely powerful construct for denial routing — the visual clarity of the branch logic maps almost 1:1 to how revenue cycle teams mentally model the work.
What's next for Ctrl+Appeal
- Expand payer policy RAG to cover more payers and policy documents beyond Meridian MP-114
- Add real-time payer portal integration for automated response tracking
- Build the analytics dashboard for win-rate tracking by payer, denial type, and appeal argument
- Explore expanding to additional denial types as routing accuracy data matures
Built With
- aws-bedrock
- claude-code
- claude-haiku-(anthropic)
- document-understanding
- langchain
- langgraph
- ocr
- python
- uipath-action-center
- uipath-agent-builder
- uipath-data-fabric
- uipath-maestro
- uipath-studio-web
- vb.net
- x12-835

Log in or sign up for Devpost to join the conversation.