Invoice Processing Automation
B2B SaaS · 8-person company · Finance team of 2 · ~200 invoices/month
140h
freed per month
45 → 3 min
per invoice
99.2%
accuracy rate
$7k
monthly savings
Platform · n8n
Invoice email → QuickBooks in ~3 minutes
B2B SaaS team: three intake sources, AI extraction, validation, auto-post or Slack exception.
Why n8n
- ·AP / AR automation
- ·Multi-system orchestration
- ·Webhook & email triggers
- ·Fast iteration on finance ops
Workflow preview
Representative of the production environment we deployed. Select any node to review configuration parameters and sample output, or use the guided tour.
Click any node to see parameters and sample output
The situation
The company received invoices from roughly 40 active vendors. Delivery methods were inconsistent: most came via email as PDF attachments, some vendors uploaded to a shared portal that required manual download, and one EDI-connected supplier sent structured files. All of it landed in the same AP inbox.
The AP clerk's process was to open each invoice in a PDF viewer, read the fields, and manually type them into QuickBooks: vendor name, invoice number, date, due date, each line item with its description and amount, the GL code, and any associated purchase order number. Simple pass-through invoices (single line, familiar vendor) took around 8 minutes. Multi-line invoices with PO matching took 30–45 minutes. At 200+ invoices per month, this consumed the equivalent of nearly one full-time employee.
Errors showed up regularly. Duplicate invoices occasionally slipped through and were only caught during bank reconciliation. PO mismatches — where the invoiced amount didn't match the open PO balance — sometimes weren't noticed until the vendor followed up on a short payment. The close cycle was delayed because AP wasn't finished until day 7 or 8 of the following month.
What we built
We set up an N8N workflow with three separate trigger nodes, each handling one of the three invoice sources.
The first trigger monitors the AP inbox via IMAP, polling every 2 minutes. When a new email arrives with a PDF or image attachment, the node extracts the attachment and passes it downstream. The second trigger polls a Google Drive folder every 15 minutes — this is the folder where the vendor portal PDFs are manually dropped by the clerk once downloaded. The third is a webhook endpoint registered in the EDI system, which fires whenever a new document is pushed.
All three paths converge at the extraction step. The PDF or image is sent to Claude (claude-3-5-sonnet) with a structured prompt. The prompt asks Claude to return a JSON object with: vendor name, invoice number, invoice date, due date, currency, an array of line items (each with description, quantity, unit price, and line total), subtotal, tax amount, and total. The prompt also embeds the company's full chart of accounts as a reference table and asks Claude to suggest the most likely GL code for each line item based on the vendor name and item description.
After extraction, the workflow runs three validation checks. First, it sums the line item totals and checks that they match the stated total within a $0.01 rounding tolerance — this catches cases where Claude misread a digit. Second, it queries the QuickBooks vendor list to confirm the vendor name matches a known vendor. Third, if a PO number is present on the invoice, it calls the QuickBooks purchase orders endpoint to verify the PO exists, is in an open status, and that the invoice amount doesn't exceed the remaining PO balance.
Duplicate detection runs before bill creation: the workflow queries QuickBooks for existing bills from the same vendor with the same invoice number in the past 90 days. If a match is found, the invoice is flagged rather than posted.
All processed documents — regardless of pass or fail — are logged to a Google Sheet with a timestamp, extraction output, validation result, and the final QuickBooks bill ID if created. The original file is moved to a "Processed" subfolder in Drive.
Technical details
- •N8N self-hosted on a $10/month DigitalOcean droplet (1 vCPU, 1GB RAM — sufficient for this workload)
- •IMAP node polls every 2 minutes; Google Drive node polls every 15 minutes
- •Claude API call takes 3–6 seconds per invoice; average cost is approximately $0.003 per invoice processed
- •QuickBooks Online REST API v3 for vendor lookup, PO verification, and bill creation
- •Slack webhook for error notifications — messages include the full extracted JSON so the reviewer can see exactly what Claude read from the document
- •Google Sheets logging via the Sheets API — one row per invoice, retained indefinitely for audit
Edge cases handled during build
Multi-page invoices were the first issue we hit during testing. Claude only sees what's in the first API call, and some invoices have line items that run across pages. We handled this by checking whether the sum of extracted line items is within 2% of the stated total. If not, the workflow fetches additional pages and sends them in a follow-up prompt asking Claude to find any remaining line items.
Foreign currency invoices from two vendors were out of scope for automatic posting — the company's currency conversion process involves a manual rate lookup step. These are detected by checking the currency field Claude extracts against "USD" and routed to a separate Slack alert for manual handling.
One vendor sends invoices formatted as Excel files rather than PDFs. We added a conversion step using a LibreOffice CLI call on the server to render the file to PDF before it hits the extraction step.
Occasionally Claude returns a vendor name with slight differences from the QuickBooks master (e.g. "Acme Corp." vs "Acme Corporation"). We added fuzzy matching using a simple Levenshtein distance check before flagging a vendor as unrecognised — this reduced false positives significantly without requiring exact string matches.
Results
| Metric | Before | After |
|---|---|---|
| Time per invoice | 8–45 min (manual) | 3 min (automated + review) |
| Accuracy rate | 87% (manual entry) | 99.2% |
| Monthly AP hours | 140h | ~8h (exceptions only) |
| Duplicate invoices posted | ~2–3/month | 0 since go-live |
| Month-end close timing | Day 7–8 | Day 3 |
| Cost per invoice | ~$35 (labour) | ~$2.10 (automation + review) |