Claude Code Boilerplate
FeaturesPricingBlogDocs
Get started →

Product

  • Features
  • Pricing
  • Skills

Compare

  • vs ShipFast
  • vs MakerKit
  • vs supastarter

Resources

  • Docs
  • Blog
  • Discord

Legal

  • License
  • Privacy Policy
  • Terms of Service
Claude Code Boilerplate

© 2026 Claude Code Boilerplate. All rights reserved.

← All posts

How to Add AI Document Processing to Your SaaS -- Extract Structured Data From PDFs and Images With Claude

September 17, 2026
nextjsclaude-codeaicloudinarysaas

The Problem With Document-Heavy SaaS Products

You have an idea for a tool that reads invoices, expense receipts, contracts, or job applications. The business case is obvious. But the build feels daunting: file uploads, AI API calls, parsing the response, storing the result, crediting the cost, handling failures.

Most tutorials show you how to call an AI API. None show you how to wire it into a production app where uploads are secure, costs are tracked, and results land in a database your users can query. That gap is what this post closes.

What You Are Actually Building

A document processing feature has four parts:

  1. The user uploads a file (PDF, image, or both)
  2. Your server sends the file to Claude with instructions for what to extract
  3. Claude returns structured JSON with the extracted fields
  4. You store the result and surface it in the UI

Every part is already handled by the Next.js SaaS boilerplate -- Cloudinary for storage, Claude for processing, Drizzle ORM for persistence, and a credit system so you know exactly what processing costs per user.

Step 1 -- Upload the File

The boilerplate ships with a protected upload endpoint that accepts a multipart form submission and returns a Cloudinary URL. Your frontend sends the file there first:

const formData = new FormData();
formData.append('file', selectedFile);
 
// Returns { url: string } -- the Cloudinary URL you pass to Claude
const { url } = await fetch('/api/upload', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}` },
  body: formData,
}).then(r => r.json());

The URL is what you pass to Claude. Cloudinary serves it over HTTPS, so Claude can fetch it directly -- no base64 encoding of a 10 MB PDF required.

Step 2 -- Tell Claude What to Extract

Claude can read images and PDFs by URL. You define the schema you want back, and Claude fills it in from the document:

// In your service layer -- never in a route handler
const response = await claude.messages.create({
  model: 'claude-opus-5',
  max_tokens: 1024,
  messages: [{
    role: 'user',
    content: [
      { type: 'document', source: { type: 'url', url: fileUrl } },
      {
        type: 'text',
        text: 'Extract vendor name, total amount, currency, and invoice date. Return JSON only.'
      }
    ]
  }]
});

No ML training. No custom model. One API call returns whatever you ask for.

Step 3 -- Track Credits and Store Results

Deduct credits before calling Claude. If the user is out, fail fast before you pay for the API call:

// Fail on insufficient credits before any AI spend
await creditService.deduct(userId, AI_CREDITS_PER_DOCUMENT);
const result = await extractFromDocument(fileUrl);
await documentRepo.create({ userId, fileUrl, result });

The result lands in Drizzle ORM. You can display it in the UI, trigger downstream actions (auto-fill a form, flag for review, generate a report), or let users export the data as CSV.

What This Pattern Unlocks

Once the pipeline is in place, the instruction to Claude is the only thing that changes per use case:

  • Expense receipts -- vendor, amount, category, date
  • Invoices -- line items, totals, payment terms, due date
  • Contracts -- parties, effective date, key clauses, renewal terms
  • Job applications -- name, email, skills, years of experience
  • Medical intake forms -- demographics, symptoms, medications (verify your compliance requirements)

You ship the first extraction type this week. Every additional one is a new instruction string and a schema update -- no new infrastructure.

The Tradeoffs to Know Before You Launch

Cost per document: Claude is not free. A one-page invoice costs roughly $0.01-0.03 to process depending on length. Price your product so AI costs are covered at any volume -- the credit system in the boilerplate makes this straightforward to track and adjust without a redeploy.

Accuracy: Claude handles clean text and well-formatted PDFs very well. Handwritten forms and low-quality scans degrade accuracy. Test with real examples from your target industry before you charge for it.

Privacy: Documents contain sensitive data. Use signed Cloudinary URLs for access, keep your storage bucket private, and delete uploaded files after processing if your compliance policy requires it. The protected file download pattern shows how to control file access across the stack.

Who Is Building This

Founders are shipping document-processing products across dozens of niches: accountants uploading receipts for auto-categorization, landlords extracting key terms from lease agreements, HR teams screening applications at scale, and logistics companies parsing shipping documents. The infrastructure -- file uploads, AI calls, credit tracking, result storage -- is identical for all of them.

If you have already built a streaming AI chat feature in your SaaS, the same Claude SDK client and credit pattern applies here. The only addition is the file upload step.

The Practical Path Forward

Document processing sounds complex and is genuinely hard to build from scratch: you need secure uploads, an AI API integration, structured output parsing, cost tracking, and a place to store results. With a boilerplate that already handles all of that, the actual work is to define your extraction schema, write the Claude instruction, and wire it to the upload flow.

The niche you pick -- invoices, applications, receipts, contracts -- is the product. The infrastructure is already done.

Get the Next.js SaaS boilerplate and launch your document processing tool this weekend.