Inspiration

Every December, people buy heating pads they do not need to burn down an FSA balance, and still lose most of it. Workers forfeited about $3 billion of their own FSA money in 2019 and $4.2 billion in 2020, and employers legally keep it. In 2022, 52% of account holders forfeited an average of $441.

The money is not lost because people lack medical needs. It is lost because nobody knows what the card is allowed to buy, and the store does not tell them. We pulled 711 health products from walmart.com. Walmart tagged 1 of them as FSA/HSA eligible on its search tiles. Our classifier, reading the IRS rules, found 468 eligible and 107 more eligible with a doctor's note.

And it is real money. FSA dollars skip federal income tax and FICA, so for someone in the 22% bracket every covered dollar keeps about 30%. With $412 left in December, spending it well keeps about $124 of tax; letting it expire loses all $412.

We wanted the answer to show up where people already shop, without opening anything.

What it does

FSA Copilot is a Chrome extension that lives on walmart.com.

  • A dock that appears on its own. Land on Walmart and a panel opens in the corner with one line: "$412 left / 68 days / ~$124 tax you keep". Tabs: Shop, Cart, Notes, Plan, Ask.
  • Badges with a reason. A green check on any product your card can pay for, in search results, product pages and the cart, with the IRS rule one hover away. A red cross only when an item is not eligible and we found an eligible swap. A faint ? on items that need a doctor's note.
  • Ask, the copilot. "What else for a kid's cold?" Claude answers in a few sentences and returns up to 6 product chips, each a real Walmart item that is green for you, with Add and View.
  • Cart-aware banner. Add Children's Tylenol and the cart says "Looks like a cold, you could add: Thermometer". A beach umbrella and a beach ball suggest sunscreen. Claude infers the situation; a rules engine decides which items may appear.
  • Notes. Add "chronic sinusitis" once and every humidifier that applies flips green. One click drafts the letter of medical necessity.
  • Cart Split + Cart Toggle. Benefit-card vs. regular-card totals with a visible hold, verify, capture, reverse log. "Show FSA cart" strips Walmart's real cart to the eligible lines so you check out with the benefit card, then restores the rest.
  • Plan + See your year. A forfeit forecast with a weekly pace ("spend $52/week to use it all"), then a one-page site with your year: contributions, spent through the card, tax you kept, what is left, and what Walmart missed.

How we built it

Chrome extension (Manifest V3). chrome.sidePanel.open() only fires from a user gesture, so "appears on its own" cannot be a side panel. The content script injects a Shadow DOM dock into every walmart.com page so Walmart's CSS and ours never touch. A MutationObserver handles Walmart's virtualized search grid; a shadow cart in chrome.storage.local records every Add click so the Cart tab updates before you open /cart.

Two-pass classifier (FastAPI). Every title first hits an exact/fuzzy match against an eligibility list scraped from FSAstore. Misses and gray-zone items go to Claude, which reads the title against IRS Publication 502 and the IRS wellness FAQ (chunked in Supabase) and returns state, confidence, rule source and a one-line reason. Confidence under 0.90 is treated as not eligible. The whole 711-item catalog is pre-classified so badges render from cache.

Copilot and recommender. POST /chat is Claude with server-side tool use: search_catalog, classify, recommend, walmart_search_url. POST /recommend sends the whole cart to Claude for a scenario and 3 to 6 categories; plain Python keeps only green, not-in-cart, affordable candidates; Claude picks at most four and names the cart item each pairs with.

Rules engine (no model). The card split and the hold, verify, capture, reverse state machine are deterministic Python. Flow: walmart.com tab -> content script -> FastAPI /api/v1 -> Supabase (products, eligibility_list, rules_chunks, notes, stats, events) -> Claude API -> back to the dock.

Data and surfaces. Apify scrapers for the Walmart catalog and the FSAstore list, a live fallback scrape for unknown products, and a published Apify Actor (fsa-eligibility-checker). Stats website in Next.js, Tailwind and shadcn/ui on Vercel. PDFs with reportlab. One tokens.css design system shared by the dock and the site.

Testing. 20 hand-labeled edge cases (SPF 8 vs SPF 30, prenatal vs daily multivitamin, Fitbit per IRS FAQ Q15), 104 offline backend tests, and two Playwright harnesses that load the unpacked extension against saved real Walmart HTML and fail on any console error.

Challenges we ran into

  • Chrome will not open a side panel by itself, so we built our own dock inside someone else's page.
  • Retailers bot-wall automated browsers. Walmart served about thirty pages to a driven Chrome before stalling. We refused to automate past bot checks, so verification runs on saved real HTML and the live site is a manual walk.
  • Walmart's search grid is virtualized and renders titles before prices. We classify on the title immediately and fill prices through a MutationObserver. Our scanner also only read the first of three grids: 3 badges became 50 once fixed.
  • A blocked event loop. Rule lookups were blocking calls inside async code. Moving them to a thread pool, running Claude batches concurrently and sending tiles in groups of 8 took the worst request under load from 16 s to 3 s.
  • The gray zone is where the interesting products are. A cervical support pillow and a lavender sleep pillow are one word apart and on opposite sides of the rule, so "needs a note" became a visible state instead of a hidden one.
  • A copilot that cannot make things up. Ours may only return items that came back from our catalog and are green (or a labeled hint) for this user.

Accomplishments that we're proud of

  • Coverage Walmart does not show: 1 of 711 tagged by Walmart; 468 eligible plus 107 conditional found by us.
  • A number worth caring about: "$412 left" becomes "~$124 tax you keep", and the site shows the whole year.
  • 20/20 edge cases correct with a cited rule against the live backend.
  • A UI that shows up by itself on a third-party site without breaking it.
  • A trust story that is architectural: the model never moves a dollar, low confidence defaults to your regular card, every badge shows its source.
  • It works on the real Walmart site with no retailer partnership and no Visa API.

What we learned

  • The surface is a constraint, not a choice. Chrome decides when a side panel may open.
  • Most of a retailer's catalog is irrelevant to an FSA, so the quiet default is no badge at all. Red had to earn its place by offering something better.
  • The cart is a better signal than the product. Two non-health items told us more than any single health item did.
  • "When unsure, say no" is the most persuasive sentence we have for a payments company.
  • Give a model tools and a narrow allowlist and it stops inventing; give it a catalog and it gets useful.

What's next for FSA Copilot

  • Visa Direct / Acceptance sandbox for the hold-and-capture flow we currently simulate.
  • IIAS for everyone: expose the classifier to merchants who are not IIAS-certified, so benefit cards stop being declined at small pharmacies.
  • Target, Amazon and CVS: same engine, a new selectors.json per retailer.
  • Real logins on the stats site and balances pulled from the plan administrator.
  • A receipt camera for retroactive HSA reimbursement, and an issuer dashboard of declines avoided and spend recovered.

Built With

Share this project:

Updates

Submission history