Nearly 1 in 5 US health insurance claims are denied, but fewer than 1% of patients ever appeal — even though appeals succeed 40–60% of the time when filed — because denial letters are written in payer jargon like CO-197 and RARC N386 that patients simply can't read, and that information asymmetry was the inspiration for DenialDecoder: a patient-facing tool that closes the gap using verified public data rather than guesses. What it does is straightforward — a patient uploads their denial letter as a PDF or image, or pastes the text, and the app extracts the claim details, decodes the CARC and RARC codes, explains the denial in plain English, produces a personalized action plan with questions to ask the insurer, and drafts an editable appeal letter that can be downloaded as a PDF. We built it as a two-person team over one week: a FastAPI + Python backend with local Tesseract OCR, PyMuPDF for searchable-PDF extraction, ReportLab for the appeal PDF, and Pydantic-validated calls to the OpenAI Responses API, paired with a React + Vite frontend using a hand-written "highlighter" design system (Fraunces serif, one marker-yellow accent used only as text highlights on the phrases that matter). Critically, the whole system runs on a trust boundary — deterministic Python and bundled CMS/X12 reference data control every fact (code meanings, dollar amounts, dates, denial categories), while GPT-5.6 is only used for language (extraction from messy documents, plain-English translation, and appeal-letter drafting) and is never given the raw document, only a compact verified payload; Codex was our primary implementation partner throughout, scaffolding the backend and driving the OCR pipeline. The challenges we ran into were real and instructive: a five-round Windows Tesseract debugging saga that turned out to be a subtle shlex.split(config, posix=False) bug preserving literal quotation marks in the tessdata path (the CLI worked because PowerShell silently stripped the quotes; Python didn't); resisting the temptation to just hand the whole letter to GPT, and instead building the deterministic reference-data layer, validator, and "unrecognized codes" flow that make hallucination structurally impossible; a PDF-layout lesson where two-column tables broke our label-aware regex parser and had to be re-emitted as inline Label: Value paragraphs; and an early inadvertent API-key exposure that we treated as compromised immediately — revoked, rotated, and verified with git check-ignore that the new key never entered version control. The accomplishments we're proud of are 263 passing backend tests covering every path including OCR failure modes and deterministic GPT fallback; a design identity that doesn't look like the default AI-app template (no purple gradients, no glassmorphism, one deliberate marker highlight); honest UI states that surface "Not found in your letter" and unrecognized codes rather than hiding gaps; and a Windows one-click launcher with PID-scoped shutdown that refuses to blanket-kill unrelated processes. What we learned is that deterministic layers are cheaper than they look and LLM safety layers are expensive if you skip them, that Codex is dramatically better with tight, high-context prompts than with sprawling "build me a backend" asks, and that agreeing on a shared API contract on Day 1 is the single highest-leverage decision a two-person team can make. What's next for DenialDecoder is expanding beyond our curated 30-code set to the full X12 CARC/RARC universe (the loader already validates any conforming dataset), adding payer-specific appeal templates, deadline tracking with local reminders, multilingual support for patients whose primary language isn't English, and — because every technical piece works but a live URL doesn't yet — a hosted version so anyone can decode a denial letter without cloning the repo.

Built With

Share this project:

Updates