I spent the last couple of months building Reclaim — an AI job-search agent for engineers, done solo, taking up nights and weekends. It reads your résumé, scores it honestly, and matches you against real open roles. It's live at reclaim.careers (free scan, no signup).
This isn't a launch post — it's a breakdown of the stack and, more usefully, the things that broke. Here's how it's built.
The stack
Frontend — Next.js on Vercel. App Router, server components where it made sense. Vercel for hosting because the deploy-on-push loop is frictionless and I was optimizing for solo velocity, not infra control.
Backend — FastAPI on Render. I split the Python backend out rather than doing everything in Next API routes, because the heavy lifting (résumé parsing, the matching pipeline, scraping) is Python-native and I wanted it isolated from the frontend's request lifecycle.
Database — Supabase + Prisma. Postgres under the hood. Prisma for the schema and type-safe queries; Supabase for the managed Postgres and some auth-adjacent data.
Auth — Clerk. Handles sign-up, sessions, the whole identity layer. More on Clerk below, because it's where I lost the most hours.
Payments — Stripe. Live mode, subscription tiers with a trial. Lookup keys drive tier resolution in the webhook so pricing changes don't require code changes.
The actual "AI" — Gemini. This is the interesting part, so it gets its own section.
Gemini does the real work
The thing I care about most: the AI isn't a chatbot bolted on the side. Gemini makes the actual product decisions.
Résumé reading: parse the PDF, extract real structure, and score it — not against keyword density, but against whether the claims are substantiated. The whole premise is honesty: most AI résumé tools keyword-stuff to beat the ATS, which backfires the second you're in an interview and can't back up your own résumé. Reclaim does the opposite — it flags where you're genuinely strong and where you're stretching.
Matching: scores the résumé against a corpus of 3,000+ real open roles (scraped across hundreds of companies' boards — Greenhouse, Lever, Ashby, Workday), and surface where your actual skills line up vs. where you'd be overreaching.
One real engineering decision: I route different tasks to different Gemini model tiers based on how much reasoning each needs, to keep per-user cost sane. The free scan runs on a cheaper, faster model; the heavier parse/match work uses a stronger one. Cost per full onboarding lands around five cents, which means cost was never the constraint — distribution and conversion are (a lesson worth its own post).
What broke (the useful part) The Clerk webhook trailing-newline bug. Production cutover, webhooks silently failing signature verification. The cause: a trailing newline on the signing secret when it got into the environment. Byte-for-byte the secret looked right; it wasn't. Hours lost to something invisible. Lesson: when signature verification fails and the secret "looks correct," check for whitespace first.
A P2002 unique-constraint collision on the webhook path. Stacked webhook events racing to create the same user record, tripping Prisma's unique constraint. Had to make the handler idempotent — upsert semantics instead of naive create.
A silent money leak. A scoring path was calling Gemini for users who weren't entitled to it — burning API spend on people who'd never pay. It "worked" (no errors, correct output), which is exactly why it was dangerous: nothing surfaces a cost bug except reading the logs and the bill. Gated it behind the entitlement check. Lesson: a feature that works but shouldn't run is a bug that costs money and throws no error.
Takeaways
Split the Python out. If your AI work is Python-native, don't force it into your JS framework's request cycle. A separate FastAPI service was worth the extra deploy target.
Lookup keys > hardcoded price IDs. Stripe pricing changes shouldn't require a deploy.
The scary bugs are the ones that don't throw. Trailing newlines, cost leaks, race conditions — they all "work." Reading logs and bills catches what your error handler won't.
Cost wasn't the hard part. At ~$0.05/onboarding, the real problem was never the AI bill — it was getting the right people to the site. Building is the easy 20%.
It's live at reclaim.careers if you want to see it — the résumé scan is free, no signup. Genuinely happy to answer anything about the stack, the Gemini routing, or the scraping in the comments.