Skip to content
Shafin Zaman

LLM apps & APIs

Structured data extractor

Turn messy unstructured text like invoices, emails, and resumes into clean JSON that matches a schema you define and validate.

Beginner A weekendFree stack

Copy or download the full plan and paste it into your AI coding agent to build it.

Why build it

A huge share of business data arrives as free-form text that humans then retype into forms and spreadsheets. LLMs are unreasonably good at reading that text and pulling out the fields you care about, but only if you constrain them: without a schema they invent keys, change formats, and occasionally return prose instead of JSON. The real skill is defining a schema, forcing the model to fill exactly that shape, and validating the result so bad output is caught, not shipped. This is the backbone of countless production AI features, from parsing receipts to enriching CRM records, and it teaches you structured output and validation, which you will reuse in almost every serious LLM app.

Who it's for: Your entry point to LLM-powered automation. If you can define a JSON shape and call an API, you can build this.

What you'll build

Core (MVP)

  • Define a target schema for each document type with typed, required fields
  • Accept pasted text or an uploaded file
  • Prompt the LLM to return only JSON matching the schema
  • Validate the response against the schema and surface exactly which fields failed
  • Automatically retry with the validation errors fed back to the model
  • Show the extracted fields in a table and offer a JSON download

Stretch

  • Support multiple document types with a schema picker
  • Flag low-confidence fields for human review
  • Batch-process a folder of files into one CSV
  • Add a diff view so a human can correct fields and export the fix

Step-by-step build

  1. 1

    Define the schema first

    Before any prompting, write the Zod schema for one document type, for example an invoice with vendor, invoice number, date, line items, and total, marking required fields and types. This schema is the contract the whole app enforces and doubles as your validation.

  2. 2

    Set up input handling

    Build a page that accepts pasted text or an uploaded file. For PDFs, run pdf-parse to get clean text; for plain text and emails, use the input directly. Normalize whitespace so the model sees tidy input.

  3. 3

    Prompt for structured output

    Send the text to Groq with a system prompt that includes the schema and says to return only JSON matching it, using null for anything not present rather than guessing. Use JSON mode so the response is guaranteed to parse. Never let the model invent a value that is not in the source text.

  4. 4

    Validate against the schema

    Parse the model's JSON with your Zod schema. If it passes, you have trustworthy data. If it fails, capture exactly which fields were wrong or missing rather than throwing the whole result away.

  5. 5

    Add a self-correction retry

    On a validation failure, send the model a second message containing its previous output and the specific validation errors, asking it to fix only those fields. One retry catches most format slips and is far cheaper than a human re-doing the work.

  6. 6

    Render and export

    Show the validated fields in a readable table and provide a download for the raw JSON. For fields the model set to null, make that visible so a human knows what still needs filling rather than assuming it was found.

  7. 7

    Handle multiple document types

    For the stretch goal, add a picker that swaps in a different schema and prompt per document type. Keep each schema in its own file so adding a new type is a small, isolated change.

  8. 8

    Test on real messy inputs

    Run it on genuinely messy examples: a forwarded email chain, a scanned-then-OCR'd invoice, a two-column resume. Confirm required fields are found, absent fields come back null, and nothing is fabricated. Ship once the ugly cases behave.

Done when

  • Ten real documents extract into JSON that passes schema validation on the first or second try.
  • When a field genuinely is not in the text, the output is null rather than an invented value.
  • A validation failure triggers a retry that fixes the offending fields instead of crashing.
  • A new document type can be added by dropping in one schema file and prompt.
  • The live URL extracts correctly for a file the app has never seen.

Ship it

Deploy the Next.js app to Vercel on the free tier with your Groq key as an environment variable. Ship a live URL and a README that shows a messy input on the left and the clean validated JSON on the right for two or three document types. Include a note on how the schema and retry loop guarantee the output shape.

What it proves: You can make an LLM produce reliable, schema-validated structured output with a self-correction loop, the exact pattern behind production document and data-extraction features and a skill you will reuse in nearly every LLM app.

Hand it to your AI agent

Paste this into Cursor, Claude, or ChatGPT and build it step by step.

You are my senior AI engineer pair. Help me build "Structured data extractor" step by step. The goal is turning unstructured text into JSON that matches a schema I define, where a schema is a typed contract for the output shape and validation is checking the model obeyed it. Stack: Next.js (upload UI + API route), Groq (Llama 3.3 70B) for extraction, Zod for the schema and validation, JSON mode for parseable output, pdf-parse for PDF text.

Requirements:
1. Define a Zod schema per document type (start with an invoice) with typed required fields.
2. Accept pasted text or an uploaded file; extract text from PDFs with pdf-parse.
3. Prompt the model to return ONLY JSON matching the schema, using null for missing fields and never inventing values.
4. Validate with Zod; on failure, retry once feeding the exact validation errors back to the model.
5. Show the validated fields in a table with a JSON download, making null fields visible.

Work in this order: define the schema, then input handling, then the structured-output prompt, then validation, then the self-correction retry, then the render/export, then a second document type. Give me the commands and code for each step and STOP after each so I can test. Do not write the whole app at once.

More in LLM apps & APIs

Building this? I post a new AI project plan on LinkedIn most weeks. Follow along and share what you ship.