Inspiration

[Replace with your own reason — e.g. "A friend of mine lost their entire security deposit last year over a clause they never read." Keep it one or two sentences and keep it true; judges can tell.]

The wider problem is simple: everyone signs things they haven't read. Not out of laziness — leases, freelance contracts and terms of service are long, deliberately dull, and written by the side with more power. The person who loses the deposit or gets trapped in an auto-renewal is almost never the person who could afford a lawyer to check first.

I noticed that every AI tool aimed at this problem summarises the document. That's the wrong output. You don't need to know what the contract says — you need to know what it does to you, and which exact sentence to argue about.

What it does

You paste any contract. Fine Print reads it clause by clause and returns every term that can hurt you, ranked severe → low. For each one:

  • Plain English — what the clause actually does, addressed to you
  • What it costs you — the concrete bad outcome, using the document's own numbers
  • What's normal — how far this term sits from a fair version
  • Ask for this — a ready-to-send message requesting the change, one click to copy

Click a finding and the exact sentence lights up in your original document. Click a highlight and its explanation opens. The two panes stay in sync.

How I built it

Next.js 16 with the App Router, TypeScript, Tailwind v4, deployed on Vercel. Analysis runs on Google Gemini's free developer tier.

The document goes to a server route handler, so the API key never reaches the browser. Gemini reads it under a system prompt that instructs it to work for the person signing and to judge every clause by the worst outcome it legally permits — not the likely outcome.

One Zod schema is the single source of truth: it generates the JSON Schema that constrains the model's output, and it validates the response at runtime. So the shape is guaranteed rather than parsed out of prose.

Challenges I ran into

Hallucinated clauses. The real danger in a tool like this isn't a missed finding, it's a confidently invented one — telling someone their lease says something it doesn't. I solved it structurally rather than by prompting harder: every quote the model returns is checked against the actual document, and any finding whose quote isn't genuinely there is deleted before it's ever displayed. A fake clause can't be highlighted, so it never gets shown.

Quotes that wouldn't match. My first highlighter failed constantly. The model copies a clause correctly, but whitespace never survives the round trip — line wraps, double spaces, stray tabs. Naive string matching found almost nothing. The fix was to match against a whitespace-collapsed, lowercased copy of the document while keeping an index map back to the original string, so I can slice at true offsets and preserve the document's real formatting. Match rate went from unreliable to 100% on both test documents.

The newest model was unusable. I built against Gemini 3.7 Flash and hit constant 503s on the free tier. So I benchmarked three models properly — and found 3.5 Flash-Lite was both the fastest (8s vs 44s) and the most thorough (14 findings vs 11). I now default to it and walk a three-model fallback chain on 503, so an overloaded model can't take the app down mid-demo.

The model's judgement needed correcting. It rated a forced-arbitration and class-action waiver as "low" severity — badly wrong, since that's a right you can never get back. I added explicit calibration to the prompt. It also only loosely obeyed "order by severity", so I stopped trusting it and sort server-side.

Accomplishments I'm proud of

Measured on the built-in samples: 9 seconds, 14 risks found, 14 of 14 highlighted correctly on the lease; 7 seconds, 9 of 9 on the freelance contract.

But mostly the verification layer. It's the difference between a demo and something a person could actually rely on.

What I learned

That the prompt is the product. I spent more time on the system prompt than any other file, and the biggest quality jumps came from telling the model who it works for rather than what format to output.

And that you should verify the model's output structurally wherever you can. Any claim the model makes that you can check against ground truth, you should check — prompting it to "be accurate" is not a control.

What's next

Scanned-PDF support via OCR, side-by-side comparison against a known-fair template for common contract types, and a shareable link so you can send an analysis to the person you're negotiating with.

Built With

Share this project:

Updates