Published 23rd September, 2026

How to Automate Parsing PDFs from Email

Learn how to build an automated PDF parsing system. Receive PDFs via email, extract data with AI, store in PostgreSQL, and let users access their documents. A practical guide with minimal code.

WebhooksPDF ProcessingEmail AutomationAI ExtractionPostgreSQL
How to Automate Parsing PDFs from Email

TLDR

Users email PDFs to your service. Your system catches the email (via webhook), sends the PDF to an AI service like Document AI for extraction, stores the extracted data in a database tagged with the user's organization, and lets that user see all their parsed documents in a dashboard.


Step 1: How It Works — The Big Picture

Here's the flow:

  1. Email arrives — User sends a PDF to abccompany@mail.yourwebsite.com
  2. You catch it — Email provider webhooks let you receive the email in real-time
  3. Send to AI — You pass the PDF to a service like Document AI to extract structured data
  4. Store in database — You save the extracted data tagged with the user's organization ID
  5. User sees it — User logs in and sees all their PDFs parsed and organized

That's it. No complex retry logic, no dead-letter queues, no distributed systems. Just: email in → AI extraction → database storage → dashboard access.

PDF Pipeline Guide


Step 2: Catch All Emails via Webhook

What You Need

We use Resend, which sends webhooks for all incoming emails:

  1. Set up an inbox endpoint via an email webhook service (i.e. Resend): abccompany@mail.yourwebsite.com → POST to https://yourapi.com/webhooks/email
  2. When someone emails that address, Resend sends you the email as JSON
  3. You store it or process it immediately

This gives you the PDF to work with

{
  "from": "user@example.com",
  "to": "docs@yourdomain.com",
  "subject": "Invoice from Acme Corp",
  "html": "...",
  "attachments": [
    {
      "filename": "invoice.pdf",
      "content": "base64-encoded-pdf-here"
    }
  ]
}

Step 3: Send PDFs to AI for Extraction

You have the PDF. Now extract the data.

Send to a PDF Parsing Endpoint

Services like Google Document AI or Claude's vision API can read PDFs and return structured data:

Input: PDF of an invoice
Output: {
  "vendor": "Acme Corp",
  "date": "2026-09-23",
  "amount": "1500.00",
  "invoice_number": "INV-12345"
}

Keep It Simple

  • Resend gives you the PDF as base64
  • Send it to Document AI or Claude's vision API
  • Get back structured JSON
  • Store the JSON in your database

That's one API call. No queues, no retries for now—just send and store.

PDF Extraction Example


Step 4: Database Design

You need to store:

  1. The extracted data from the PDF
  2. Which organization it belongs to (so users only see their own)
  3. The PDF itself (optional: store or delete after extraction)

Simple Schema

Two tables. That's it.

Table 1: Email Addresses (used by webhook)

CREATE TABLE allowed_emails (
  email VARCHAR PRIMARY KEY,
  org_id VARCHAR NOT NULL
);

When the webhook gets an email, it checks this table. If the email exists, parse it. If not, ignore it.

Table 2: Documents (used by teams)

CREATE TABLE documents (
  id BIGSERIAL PRIMARY KEY,
  org_id VARCHAR NOT NULL,
  data JSONB
);

Store the parsed result here. Teams query by org_id to see their documents.


Step 5: User Login & Access Control

When a user logs in, they should only see their documents.

At this point, you should be using an authentication system like Kinde, Supabase Auth, or Clerk.

How It Works

User logs in with email: alice@acme.com
Your auth system knows: alice belongs to org_id = "org_9f1c2d5e"
Query: SELECT * FROM documents WHERE org_id = 'org_9f1c2d5e'
Return: All PDFs from that organization

Query their documents

SELECT * FROM documents WHERE org_id = user_org_id;

One rule: Before showing any document, check that the user's org_id matches the document's org_id. That's all the access control you need.


Step 6: Putting It Together

Here's the complete flow:

1. User emails PDF to abccompany@mail.yourwebsite.com
   ↓
2. Resend webhook fires
   ↓
3. You receive {from, subject, attachments}
   ↓
4. Extract org_id from the sender's email or header
   ↓
5. Send PDF to Document AI (or Claude)
   ↓
6. Get back {vendor, date, amount, etc.}
   ↓
7. INSERT INTO documents (org_id, email_from, extracted_data, ...)
   ↓
8. User logs in to your dashboard
   ↓
9. SELECT * FROM documents WHERE org_id = user.org_id
   ↓
10. Display all parsed PDFs in a table

Done.


Conclusion

That's the whole system:

  • ✅ Email provider catches PDFs (Resend webhook)
  • ✅ You send to AI for extraction (Document AI, Claude, etc.)
  • ✅ Store in PostgreSQL with org_id isolation
  • ✅ User logs in and sees their documents

No message queues, no complex retry logic, no fancy distributed systems. Just: receive email → extract → store → display.

Start here. Add complexity only when you need it (high volume, failed extractions, etc.). Most teams don't need it.


The End Result

Your team gets a shared queue. Every PDF that arrives lands here automatically, parsed and ready to process — no manual uploads, no coordination needed.

Email Queue Result