DEV Community

Cover image for The Overhead Ratio Is Lying to You — I Built an AI Tool to Prove It
Hassan Imam
Hassan Imam Subscriber

Posted on

The Overhead Ratio Is Lying to You — I Built an AI Tool to Prove It

DEV Weekend Challenge: Generosity Edition Submission 💜

This is a submission for Weekend Challenge: Generosity Edition

What I Built

GlassPocket — a tool that argues against the "overhead ratio," the dominant heuristic people use to judge charities (what % of donations go to "programs" vs. "overhead" like staff and infrastructure). That heuristic punishes exactly the investment that makes a charity effective, and it drives what nonprofit finance people call the "starvation cycle" — orgs under pressure to look lean end up under-staffed and under-resourced.

You search a US 501(c)(3), and instead of a single overhead percentage, GlassPocket pulls their IRS Form 990 history (via ProPublica's Nonprofit Explorer API) and shows:

  • Reserve months — how long the org could run on savings alone (low reserves = fragile, not "lean")
  • Operating margin trends across up to 13 years of filings
  • Staff-investment share — reframed as capacity, not waste
  • Fundraising cost per dollar raised — a narrower, more honest efficiency metric than the classic ratio
  • A peer-percentile chart against ~70 similar organizations in the same category
  • A Gemini-written "myth-buster" card pairing each overhead-ratio assumption with what the numbers actually show
  • A grounded chat box — ask follow-up questions about that specific org's finances, answered only from its own filing data

Demo

Live app: https://glasspocket.vercel.app/

GlassPocket demo — searching GiveDirectly, the myth-buster card, trend and peer-percentile charts, and the grounded chat answering a follow-up question

Code

GitHub logo hassan-2050 / glasspocket

Overhead-ratio myth buster for US charities — Form 990 data via ProPublica, Gemini narrative generator

GlassPocket — Overhead Myth Buster

Live: glasspocket.vercel.app Category: Overall Winner + Best Use of Google AI (Gemini-powered narrative generator and chat)

The Hook

Most charity-rating tools reinforce the harmful "overhead ratio" myth. This contrarian tool argues against that dominant heuristic by reframing efficiency around outcomes and reserves.

What It Does

You search a US charity by name, and it pulls their IRS Form 990 history to generate a plain-English context-aware financial explainer that debunks the overhead myth and shows why a high program-expense ratio can actually indicate starved infrastructure. Instead of the overhead ratio, it surfaces reserve months, operating margin trends, staff-investment share, fundraising cost-per-dollar, and how the org compares to ~70 peers in its category. A Gemini-backed "myth-buster" card writes the narrative (with a one-click regenerate), and a grounded chat box lets you ask follow-up questions about that org's numbers specifically — it only answers from the org's own…

How I Built It

The interesting part of this build wasn't the UI — it was discovering that the premise of the "overhead ratio" is shakier than I expected, right down at the data layer.

The data problem is the thesis. I went in planning to compute the classic program/management/fundraising expense split and rank charities by it. ProPublica's own API docs say that breakdown is "formtype dependent" across the different 990 variants (990 vs. 990-EZ vs. 990-PF) — meaning you can't reliably compute the overhead ratio from clean, normalized filing data in the first place. That's not a workaround I found around a limitation; it became the actual argument. Instead I built five metrics from fields ProPublica does normalize consistently: reserve months, operating margin, staff-investment share (officer comp + wages + payroll tax as % of spending), fundraising cost per dollar (from the actual "professional fundraising fees" line item), and revenue concentration.

Peer percentiles, built at build-time. To compare an org against similar ones, I sample ~75 organizations per NTEE major category (10 categories total) via ProPublica's search API, compute each one's latest-year metrics, and cache the resulting distributions as static JSON. That means percentile lookups are instant at request time and don't depend on ProPublica's API being up during a demo.

Gemini does the writing, not the arithmetic. The narrative card hands Gemini 2.5 Flash a fully pre-computed set of numbers and a strict JSON response schema — its job is phrasing and framing, never inventing a figure. I hit a real bug here: Gemini 2.5 Flash spends hidden "thinking" tokens out of the same maxOutputTokens budget by default, which was silently truncating longer prompts mid-JSON. Disabling thinkingConfig.thinkingBudget: 0 fixed it instantly — this is pure formatting, not a reasoning task, so there was nothing to think about anyway.

The chat needed the opposite fix. For the free-form chat feature, I first tried the same thinkingBudget: 0 setting and got a subtle but real bug: the model would cite our exact, correct numbers but draw wrong conclusions from them — e.g. claiming a year had a "negative operating margin" when it actually had a +25% margin and falling reserves for an unrelated reason (expenses scaling up faster than reserves). Chat questions require live arithmetic across multiple derived fields, not just rephrasing a precomputed conclusion, so I left thinking enabled there and added explicit guardrails in the prompt about not conflating reserve-month drops with deficits. The chat is scoped to one org's filing data via a dossier built from the same computed metrics, and it's instructed to say "I don't know" rather than invent anything about a charity's programs, leadership, or controversies — none of which is in the data.

Two smaller bugs worth mentioning, because they're the kind that only show up when you actually test the numbers instead of trusting that the code "looks right": ProPublica's fuzzy name search resolved "charity: water" and "ACLU Foundation" to unrelated same-ish-named orgs (I hardcoded the correct EINs after verifying against Charity Navigator), and a percentile field for "fundraising cost" was showing a spurious "100% more efficient than peers" for orgs that report zero professional fundraising fees, because a value of exactly 0 was being treated as a real 0th-percentile cost instead of "not applicable."

Stack: Next.js 16 (App Router) + TypeScript + Tailwind + Recharts, deployed on Vercel, with a small Node build script that fetches and caches the ProPublica data and peer cohorts ahead of time so the demo never depends on a live third-party API mid-presentation.

Prize Categories

Submitting for Best Use of Google AI — Gemini 2.5 Flash powers both the myth-buster narrative generator (strict JSON schema, zero invented numbers, deterministic rubric-engine fallback if the API is ever unavailable) and the grounded multi-turn chat.

Solo submission.

Top comments (0)