Every month, a mid-sized agency I work with was spending roughly 40 person-hours processing invoices — downloading PDFs from email, re-typing vendor names and amounts into their accounting system, categorizing expenses, and chasing approvals. The error rate on manual data entry hovered around 3–5%, which meant a non-trivial percentage of invoices had wrong amounts, wrong vendors, or wrong GL codes.
That's the problem I built this workflow to solve.
I run n8n in production for clients, and I've built enough document-processing pipelines to have strong opinions about what works. This post is the technical walkthrough of an automated invoice processing system — Gmail as the inbox, n8n as the orchestration layer, and Claude for the extraction step — that cut that agency's invoice processing time from 40 hours to ~4 hours a month. I'll show you the exact architecture, the n8n node-by-node build, what Claude's prompt looks like, and what it costs to run.
The Problem: Manual Invoice Processing Costs More Than You Think
Before automation, the agency's AP process looked like this:
- A project manager receives an invoice PDF via email
- They open the PDF, read the amount, vendor, invoice number, and due date
- They type those fields into QuickBooks
- They assign the right expense category and project code
- They file the PDF in a shared Drive folder
- They Slack the client for approval if it's above a threshold
That workflow — entirely manual — took ~4–6 minutes per invoice at roughly 200 invoices per month. One full work week per month, gone, on data entry. And that's before you account for the error rate: a 2024 Institute of Finance & Management (IOFM) benchmark found that organizations relying on manual AP processes see error rates of 3–7%, compared to 0.2–0.5% for automated systems. For a mid-market firm, those errors translate to late-payment penalties, duplicate payments, and hours of reconciliation work downstream.
| Metric | Before automation | Industry benchmark (automated) |
|---|---|---|
| Time per invoice | 4–6 min | 30–60 sec |
| Monthly AP labor | ~40 hours | ~4 hours |
| Data entry error rate | 3–5% | 0.2–0.5% |
| Late payment penalties | ~$800/yr | ~$50/yr |
| Invoice processing cost per invoice | $6–12 | $1–3 |
The fix didn't need a custom backend or a $30K enterprise document-processing platform. It needed three tools wired together the right way.
The Architecture: Gmail → n8n → Claude → Storage
The core insight is that you don't need an OCR engine or a document AI platform. Claude's vision and text-reasoning capabilities can read an invoice PDF as accurately as a human can — often more accurately, and certainly faster. The architecture is a simple pipeline with four stages:
Gmail (watch for invoice emails)
→ n8n (orchestrate + route)
→ Claude (extract structured fields from PDF)
→ Google Sheets + Slack + Drive (store, notify, file)
Every stage runs inside n8n — no external services, no webhook bridges, no middleware. The entire system is one n8n workflow with ~12 nodes and zero custom code beyond the Claude prompt.
Step 1: Setting Up the Gmail Trigger
The workflow starts with n8n's Gmail Trigger node, which polls the inbox for new email matching specific criteria. The configuration is straightforward:
- Poll interval: Every 5 minutes (n8n's Gmail trigger uses the Gmail API's
historyendpoint, so it's efficient — it only fetches what changed since the last poll) - Search filter:
has:attachment filename:pdf subject:(invoice OR "payment due" OR "statement")— this catches invoice emails and silently ignores everything else - Action:
Mark as readafter processing (to avoid re-processing on the next poll) - Only fetch attachments: Strip the email body — we only need the PDF
The search filter is the most important decision in this node. Too narrow and you miss invoices from unfamiliar senders. Too broad and you trigger on every PDF email. Over a few weeks, I tuned the subject-line keywords based on real data — the three terms above cover roughly 95% of invoice emails from the agency's vendors without generating false positives.
When a match fires, n8n outputs a payload containing the email metadata and the attachment binary. The next node unpacks it.
Step 2: Extracting and Routing the PDF Attachments
n8n's Read Binary Files node (configured to read from the incoming attachment data — no disk write needed) converts the PDF attachment into a base64-encoded string that can be sent to Claude's API.
A Switch node then classifies the attachment. I use n8n's expression language to check:
// Quick check: file size and type
$json.attachment.mimeType === "application/pdf" && $json.attachment.fileSize > 100
This filters out empty PDFs, corrupted files, and anything that's not actually an invoice. The default route sends valid PDFs to the Claude extraction node; the fallback route logs the email to a "Needs Review" sheet in Google Sheets for manual handling.
Step 3: Extracting Invoice Data with Claude
This is the step that does the real work. I use n8n's HTTP Request node to call the Anthropic Messages API with the PDF encoded as a base64 image content block — Claude can read PDF text content natively when sent as a document media type.
The request body looks like this (simplified):
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "You are an invoice data extraction assistant. Extract the following fields from the invoice PDF and return ONLY valid JSON — no explanation, no preamble, no markdown wrappers. Use these exact field names: invoice_number, vendor_name, vendor_email (if visible), invoice_date, due_date, subtotal, tax_amount, total_amount, currency, line_items (array of {description, quantity, unit_price, amount}), payment_terms, notes (any other relevant info). If a field is not found, return null for that field."
}
],
"messages": [
{
"role": "user",
"content": [
{
"type": "document",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": "{{ $json.attachment_data }}"
}
},
{
"type": "text",
"text": "Extract the invoice data from this document as JSON."
}
]
}
]
}
Three things to note:
-
The system prompt is explicit about output format. "Return ONLY valid JSON — no explanation, no preamble, no markdown wrappers." Without this instruction, Claude sometimes wraps the JSON in a markdown code fence that n8n then has to strip. One sentence eliminates the parsing step entirely.
-
Claude Sonnet 4.6 handles PDF documents natively via the
documentcontent block. No OCR pipeline, no PDF-to-text conversion, no intermediate step. The model reads the text content from the PDF and extracts the fields in a single inference pass. -
Prompt caching is on. I put
"cache_control": {"type": "ephemeral"}on the system block, and since this workflow processes invoices in batches (15–20 per check), the cached prefix — the system prompt — is reused across every extraction in the batch. As I covered in the prompt caching post, this cuts the input-token cost by roughly 70% on warm calls.
The response from Claude is parsed via n8n's Code node with a simple JSON.parse() — the structured invoice record is now available as n8n items for the downstream nodes.
Step 4: Storing, Notifying, and Filing
Once the invoice data is extracted, the workflow splits into three parallel paths:
Google Sheets — the record of record. Each extracted invoice becomes a row in a master invoice tracker with columns for invoice number, vendor, date, amount, status, and a link to the source PDF. This gives the finance team a real-time dashboard they can query, filter, and export without touching any automation UI.
Slack — the approval trigger. If the total amount exceeds a configurable threshold (the agency set theirs at $2,500), the workflow posts a message to an #approvals channel with the invoice summary and a link to view the PDF in Drive. A thumbs-up reaction from a manager auto-approves it via n8n's Slack reaction trigger.
Google Drive — the filing cabinet. The original PDF is uploaded to a dated folder structure (Invoices/2026/07/) with the invoice number and vendor name as the filename. This replaces the manual drag-and-drop filing that people inevitably forget to do.
The three paths run concurrently inside n8n — the workflow doesn't serialize them, so the total wall-clock time after Claude responds is about 1–2 seconds.
Cost Breakdown: What This Runs On
One of the best parts of this system is how cheap it is to run. Here's the monthly cost at 200 invoices:
| Component | Usage | Monthly cost |
|---|---|---|
| n8n self-hosted (VPS) | 720 executions/month | ~$6 |
| Claude Sonnet 4.6 via API | ~15K input tokens/invoice, 5-min cache warm | ~$8–12 |
| Gmail API | 400 API calls/month | Free |
| Google Sheets + Drive | 200 rows + PDF storage | Free |
| Slack | ~60 approval notifications + reactions | Free (existing plan) |
| Total | ~$14–18/month |
Compare that to the $1,200–2,400/month in labor cost the agency was spending on manual AP processing (40 hours at $30–60/hr blended). The system pays for itself roughly 70× over in the first month. Even the enterprise document-processing platforms — Abbyy, Rossum, Hypatos — start at $500–1,500/month for this volume. The n8n + Claude approach is cheaper by an order of magnitude and gives you full control over the extraction schema and the routing logic.
Real Results: Before and After
After three months running in production, the agency's numbers tell the story:
- 40 hours/month → 3.5 hours/month on invoice processing. The remaining time is entirely exception handling — invoices that didn't match the subject filter, corrupted PDFs, or vendor-specific quirks the extraction prompt didn't cover.
- Error rate dropped from 4% to under 0.5%. The errors that remain are almost always edge cases where the PDF was scanned rather than born-digital (Claude handles most scans well via its vision capabilities, but very poor scans still cause misreads).
- Late payment penalties went to zero. Every invoice is now logged at the time it arrives in the inbox. The finance team gets a weekly "coming due" Slack digest generated by a companion workflow.
- The vendor onboarding pipeline improved. Because the invoice tracker has clean, structured vendor data, the team built a secondary workflow that cross-references new vendors against their approved vendor list and flags discrepancies before processing.
The system has processed ~580 invoices since launch with four incidents — three caused by attachment parsing edge cases (invoices embedded inside .eml forwarding chains) and one by an API outage. All were resolved within the same day without data loss.
How Smart AI Workspace Approaches Document Processing
The invoice pipeline I just walked through follows the same structural pattern I use for document-heavy automation:
Start with the trigger, not the model. Most people start with "which AI model should I use?" The right first question is "what's the trigger?" — an email arrival, a webhook, a file landing in a folder. The trigger determines cost, latency, and failure mode more than the extraction model does.
Prompt design is the lever. I see document-extraction projects that spend weeks evaluating models and hours writing the prompt. The ratio should be inverted. I ship Claude every time because its instruction-following on structured output is the tightest in the market — but even the best model fails with a sloppy prompt. Be explicit about field names, null behavior, and output format.
Plan for the exceptions, not the happy path. The workflow described above handles ~85% of invoices fully automatically. The remaining 15% hit human-in-the-loop flows — a Slack message, a "Needs Review" sheet row, a weekly exception report. Building for that 15% up front is what keeps the system reliable in production, not the extraction accuracy on the easy ones.
This pattern scales across document types. The same Gmail → n8n → Claude pipeline, with a different system prompt, processes purchase orders, delivery receipts, and client statements for other clients. The architecture is the same; only the extraction schema changes. And the Upwork gigs I ship — like the B2B Lead Gen & Outreach Automation and the AI Lead Qualification Bot — all follow the same philosophy: trigger → prompt → route, with the model doing the reasoning step that no-code nodes can't handle.
Build Your Own or Let Me Build It For You
If you're processing 50+ invoices a month (or any document that arrives by email), the economics of this pipeline are hard to argue with. The n8n workflow, the Claude prompt, and the Google Sheets schema from this post will get you 80% of the way there. The last 20% — your specific vendor formats, your approval chain, your accounting system's API quirks — is what determines whether it ships in a day or a week.
If you'd rather hand me the problem and get back to running your business, I'll build the workflow on infrastructure you own, wire it to your tools, and hand you the keys. No monthly platform fees, no vendor lock-in, just a production n8n workflow that turns invoice emails into structured data.
See how Smart AI Workspace builds document automation →
Want us to build this for you? Get in touch →
Sources: Anthropic Messages API Docs — Prompt Caching · Institute of Finance & Management (IOFM) AP Benchmarks 2025 · n8n Gmail Trigger Node Docs · Claude Document Processing Capabilities (Anthropic) · PYMNTS: Invoice Processing Automation Cost Data