Inspiration

We started with a simple question: what happens when someone gets a legal document they don't understand?

The answer is usually nothing. They don't respond, they miss the deadline, they lose by default. About 90% of tenants face eviction without a lawyer. Most insurance denials are never appealed even though over half get overturned when someone actually fights back. Over $60 billion in government benefits go unclaimed every year because the paperwork is designed for lawyers, not for the people it affects.

We wanted to build something that reads those documents for you, checks the claims against real law, and helps you respond. Not a chatbot that guesses. A tool that cites or stays silent.

What it does

You upload a legal document (eviction notice, insurance denial, benefits termination letter) as a PDF, image, or text file. FairNotice runs a four-stage AI pipeline:

  1. Parses the document and extracts raw text (with OCR for scanned images)
  2. Extracts every claim, deadline, demand, and dollar amount into structured data
  3. Searches a curated database of 39 real California statutes and checks each claim against actual law
  4. Generates a plain-language explanation, a deadline timeline, a confidence score, and a draft response letter with statute citations baked in

When the AI can't find a relevant statute, it says so. When the situation is too serious for an automated tool (criminal charges, child custody, immigration), the system refuses to analyze and routes you to professional legal help instead.

The whole thing runs in 30-90 seconds. Documents are processed in memory and never stored.

How we built it

The frontend is Next.js 16 with React and Tailwind CSS. The landing page uses a dark editorial theme and the app pages use a light warm-paper theme to feel less intimidating when someone is reading about their legal situation.

The backend is four API routes chained together. Each one has a typed contract so if something fails, the pipeline tells you exactly which step broke and why. The LLM calls go through Groq running Llama 3.3 70B.

The statute retrieval is a keyword-based search over curated JSON files. We deliberately chose this over vector embeddings because with a small, hand-curated statute set, keyword matching is more predictable and every retrieval decision is inspectable. We wrote 39 statute entries covering California tenant law (17), insurance law (12), and benefits law (10), each with the real statute number, the key provisions, and a plain-language summary.

The confidence scoring engine starts at 100 and deducts points for specific factors (no statute match for a claim, out-of-state jurisdiction, referral needed) and shows every deduction to the user. The score is never an opaque number.

We deployed on Vercel.

Challenges we ran into

The biggest was the correctness trap. Every "AI does legal advice" project sounds great in a pitch and falls apart when someone asks "but is it right?" We spent a lot of time on the architecture to make sure the AI only reasons about what's in front of it (the uploaded document + retrieved statutes) and never pulls legal claims from its training data. We literally put "do NOT cite any statute from your own training data" in the system prompt.

Rate limiting on Groq's free tier was a real problem. The pipeline makes multiple LLM calls per document, and we kept hitting the tokens-per-minute and tokens-per-day caps during testing. We added retry logic with backoff and sequenced the calls to spread token usage across a wider time window.

PDF parsing broke silently in the dev environment because the bundler was trying to bundle pdf-parse's worker files instead of loading them at runtime. It took a while to track down. We fixed it by externalizing pdf-parse, pdfjs-dist, and tesseract.js from the bundler.

Getting the LLM to extract multiple granular claims instead of lumping everything into one was another challenge. Our first prompt produced a single claim per document. We had to add explicit guidance telling the model to break documents into 4-8 individual claims and err on the side of extracting more rather than fewer.

Accomplishments that we're proud of

The "cited or silent" architecture actually works. Every claim in the analysis links to a real statute, and when no statute applies, the system genuinely says so instead of making something up. We tested this with real documents and the citations hold up.

The confidence scoring system is something we haven't seen in other legal AI tools. It doesn't just give you an answer. It tells you how much to trust that answer, shows you why, and tells you when to stop trusting it and talk to a human instead.

The safety refusal system detects criminal charges, custody matters, and immigration cases and refuses to analyze them. A tool that knows what it doesn't know is more useful than one that always has an answer.

From the sample eviction notice, the analysis correctly flags bundled admin fees as potentially invalid, catches a miscounted 3-day deadline that ignores weekends, identifies improper service methods, and surfaces the right to cure. These are real legal defects that a tenant without a lawyer would never catch.

What we learned

The most important lesson was that the AI's honesty matters more than its capability. We could have built a tool that confidently analyzes any document from any state. It would have been impressive in a demo and dangerous in practice. Scoping to one jurisdiction and building the refusal system was harder but the right call.

We also learned that prompt engineering for structured output is its own discipline. Getting consistent, parseable JSON from an LLM across different document types took more iteration than we expected. Small changes in prompt wording produced very different extraction granularity.

And we learned that rate limits are a real engineering constraint, not just a billing issue. Designing a pipeline that stays within free-tier token limits while still producing high-quality analysis required real architectural decisions (sequential vs parallel calls, inter-step delays, retry logic).

What's next for FairNotice

More jurisdictions. The statute store is plain JSON. Adding a new state's tenant law doesn't require any ML work, just careful legal research. We want to open this up to community contributions.

Court e-filing integration. Right now FairNotice drafts a response letter. The next step is helping someone actually file it.

A mobile app for document scanning. Someone gets a notice taped to their door. They pull out their phone, take a photo, and get an analysis on the spot.

Partnerships with legal aid organizations. When the confidence score is low and FairNotice routes you to "get professional help," that referral should go somewhere specific. A warm handoff to a real advocate, not a generic phone number.

Built With

Share this project:

Updates