-
-
Monte: what each card earned, minus its fee and interest.
-
Where it went: a year of Jordan's spending by store and category.
-
The Receipt: rewards + perks − fees − interest. Jordan's three cards net −$427.03.
-
Leaks: $735 a year in interest on the Apple Card, with the fix.
-
Replay: the same purchases moved to the right card in his wallet. $104 back.
-
Tap: the best card at the register. Here the Amex Gold earns 4x at Sweetgreen.
-
Pay this first: which balance to pay down first, and how long the $2,800 takes to clear.
-
Every purchase: all 576, each showing the card used and the right one.
-
Keep or cancel: each annual fee against the value the card adds.
-
Next year ×1,000: as paid vs. on the right card, over 1,000 simulated years.
-
Trace a purchase: rule, arithmetic, issuer source and date for every dollar.
-
Wrapped: Jordan's year in eight cards.
-
Real vs. simulated: what is real on the page and what is demo data.
-
Monte vs. the rest: card pickers choose a card; Monte counts fees and interest too.
-
Apply: the next card, ranked on Jordan's spending, not referral fees.
Inspiration
Rewards apps count points. They don't subtract annual fees or interest.
Jordan, 24, has three cards. Last year he earned $552.69 in rewards and $80.00 in perks, and paid $325.00 in annual fees and $734.72 in interest on a $2,800 balance at 26.24% APR. Net, his cards cost him $427.03.
What it does
Monte reads a year of purchases and computes each card's net: rewards + perks used − fees − interest.
- Receipt: that net, per card and in total.
- Where it went: spending by store and category, month by month.
- Leaks: interest, fees that don't pay for themselves, recurring charges, each with its fix.
- Replay: the same year on the best card already in the wallet. Jordan gets $104.14 back.
- Every purchase: the card used vs. the right card, for all 576 of Jordan's purchases.
- Tap: the best card at a store, counting this quarter's caps. Never a card carrying a balance.
- Pay this first: which balance to pay down first, and how long it takes.
- Keep or cancel: each annual fee against the value the card adds over the next-best card.
- Apply: the next card, ranked on your spending, not on referral fees.
- Next year ×1,000: each plan run over 1,000 simulated years.
- Wrapped: the year in eight cards.
How we built it
No language model touches the math. The engine is deterministic, and every dollar traces to a card rule and the purchases behind it.
- Card catalog: 29 cards. Each term has the issuer's source URL and the date we checked it (17 Oct 2026).
- Rules engine: earn rates, spending caps, shared cap pools, pick-a-category cards, quarterly rotations, statement credits, cash vs. travel point values.
- Monte Carlo: resamples your own months into 1,000 years and reruns the engine on each, so caps reset every year. Seeded. 19–313 ms.
- Solver check: a linear program assigns the whole year at once. It proves the card-by-card routing optimal on all three test wallets (gap $0.00), and on a hand-built cap trap it finds $33.00 where card-by-card gets $30.00.
- Provenance: click any dollar to see its rule, the arithmetic (purchase × earn rate × point value), the source and the date.
- Input: statement CSVs (Chase, Amex, Capital One), parsed in the browser; Plaid sandbox for transactions, APR and balances.
- Backend (branch
m/backend, commit 6c50418; built and tested, not yet deployed): Supabase Postgres with row-level security on every table, and no card numbers stored. Seeded with the 29 cards and their sources, plus Jordan's 576 purchases and cap state./api/syncwalks your history once and caches how much of every card's spending cap is used;/api/tapreads that cache instead of replaying the year. Same card and same reward to the cent on every test purchase, in about 3 microseconds instead of 3 milliseconds (scripts/cap-cache-check.ts). A review pass caught the new endpoints trusting a user id from the request; they now take the user from the signed-in session token. - One model, one job (on
m/backend): Claude Haiku 5.5 cleans messy bank merchant strings and assigns one of our 20 categories ("SQ *BLUE BOTTLE COF 0417 LOS ANGELES CA" → Blue Bottle Coffee, dining; "COSTCO WHSE #0479" → Costco, wholesale clubs). 8 of 8 correct in a live test. It never computes a dollar. - Speed: a year of 576 purchases routes in about 1 ms; 1,000 simulated years in about 58 ms.
- Stack: Next.js 16, TypeScript, React, Tailwind, D3, Supabase/Postgres, Claude Haiku 5.5 (merchant names only), javascript-lp-solver, Plaid (sandbox), Claude Haiku 5.5 (merchant names only), Vercel. 36 tests, including hand-computed cases.
Adrian built the interface and brand. Michael built the backend: Plaid, the solver, the Monte Carlo engine and the tests.
Challenges we ran into
- Caps. Citi Custom Cash shares one $500 cap a billing cycle across categories, BofA Customized Cash one combined $2,500 a quarter, and Blue Cash Everyday has a separate $6,000 a year per category. Getting the pool keys right, and making the engine, the solver and the Monte Carlo use the same keys, took several passes.
- Caps broke our first Monte Carlo. Resampling monthly reward totals overstates capped cards, because a month is worth less once earlier months have used the cap. We switched to rerunning the engine on every simulated year, and wrote a script that measures the difference.
- Greedy can waste a cap on an early small purchase. We needed to know whether that cost anyone money, which is why the solver exists.
- Interest overrides rewards. A card with a balance gets no new spending, and Monte never suggests a new card while you carry one.
What we learned
Interest decides most of the answer: Jordan's best move is paying down his balance, not a better rewards card. And when a system has limits like caps, you have to simulate the system, not the totals it produced. A cheap greedy is fine as long as you can prove it.
Real vs. simulated
- Real: the card terms and sources, the engine, Monte Carlo, the solver check, every number on the receipt, CSV upload, the Plaid code.
- Simulated: the five demo people (Jordan, Maya, the Parks, Sam, Rosa) and their purchases. Tap is a web demo, not NFC. Plaid runs in sandbox.
- Built, not deployed: the Supabase backend and the merchant-name model, on
m/backend. The live site runs the engine in the browser. - Flagged: 11 of the 29 cards are marked unverified and badged in the app. Jordan's cards are all verified.
What's next for Monte
- Merge and deploy the backend, so Tap runs on real synced data and merchant cleanup puts more purchases in the right category.
- Production Plaid, and a background job that updates the cap cache as new purchases post.
- Confirm the 11 unverified cards and add published rotating categories for other quarters.
- Payoff planning: which balance to pay first, and when it is safe to open a new card.
Built With
- anthropic
- claude-code
- d3.js
- framer-motion
- javascript-lp-solver
- matter.js
- next.js
- plaid
- postgresql
- react
- supabase
- tailwindcss
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.