Last week I tested my n8n invoice extraction workflow with a batch of real invoices. Within the first run, it caught a $757 duplicate invoice that a human would have paid twice. Then it flagged a $3,696 furniture order that was 7.4× the vendor's historical average.
This isn't a demo. It's a production pipeline with error handling, audit logging, and anomaly detection. Here's exactly how it works.
The Problem
Accounts payable teams manually key invoice data from PDFs into spreadsheets. It's:
- Slow: 3-6 hours/week for a busy team
- Error-prone: Typos in amounts, wrong dates, missed line items
- Expensive: One duplicate payment ($500-$2,000) costs more than a year of automation
Most "invoice automation" tools are either enterprise software ($50K+/year) or basic OCR that dumps text into a CSV. Neither handles the full pipeline: extraction → validation → duplicate detection → anomaly flagging → audit trail → alerts.
The Architecture
My n8n workflow has 12 nodes in this flow:
Gmail Trigger → PDF Filter → AI Extraction → Validation → Duplicate Check → Anomaly Detection → Sheets Ledger → Slack Alert
1. Gmail Trigger (Watches for Invoices)
The workflow watches a dedicated Gmail inbox for emails with PDF attachments. It filters by:
- Subject line patterns ("invoice", "receipt", "bill", "statement")
- Sender domain whitelist (optional)
- Attachment type (PDF only)
2. AI Extraction (Gemini)
The PDF is sent to Google Gemini with a structured prompt:
"Extract the following fields from this invoice: vendor name, invoice number, invoice date, due date, line items (description, quantity, unit price, total), subtotal, tax amount, total amount, PO number, payment terms. Return as JSON."
Gemini handles any invoice format — scanned PDFs, digital PDFs, multi-page invoices, international formats. No template matching needed.
3. Validation
Before anything hits the ledger, the extracted data is validated:
- Required fields present (vendor, amount, date)
- Amount is a positive number
- Date is parseable
- Invoice number isn't empty
Failed validations go to a "Review" sheet with the raw extraction for human inspection. Nothing is silently dropped.
4. Duplicate Detection
This is where the $757 catch happened. The workflow checks every new invoice against the existing ledger using a composite key:
vendor + invoice_number + amount
If all three match an existing entry, it's flagged as a duplicate. The workflow:
- Logs the duplicate to a "Duplicates" sheet
- Sends a Slack alert: "⚠️ DUPLICATE: Invoice #INV-2024-0847 from Acme Corp ($757.00) matches an existing entry from 2024-03-15"
- Does NOT add it to the ledger
5. Anomaly Detection
For non-duplicate invoices, the workflow calculates the vendor's rolling average (last 10 invoices) and flags anything exceeding 2× that average:
IF amount > (vendor_rolling_avg × 2) THEN flag
The $3,696 furniture order was 7.4× the vendor's average of ~$499. The Slack alert said:
"⚠️ ANOMALY: Invoice #FURN-8821 from OfficeDepot ($3,696.00) is 7.4× the vendor average ($499.20). Review before payment."
6. Audit Trail
Every invoice — clean, duplicate, or anomalous — is logged to a Google Sheets ledger with:
- Timestamp
- Vendor, invoice #, date, amount
- Extraction confidence score
- Status (clean / duplicate / anomaly / validation_failed)
- Source email ID (for traceability)
7. Error Handling
The workflow has:
- 3× retry with backoff on the Gemini API call
- Dead-letter queue: Failed extractions go to a "Failed" sheet, never lost
- Slack alert on failure: "❌ Extraction failed for email [ID]. Check the Failed sheet."
- Idempotency: The same email processed twice won't create duplicate ledger entries (email ID is the dedup key)
Real Test Results
I ran the pipeline against a batch of 23 invoices:
| Metric | Result |
|---|---|
| Invoices processed | 23 |
| Clean entries | 19 |
| Duplicates caught | 2 (including the $757 one) |
| Anomalies flagged | 2 (including the $3,696 one) |
| Extraction failures | 0 |
| Average extraction time | 8 seconds |
| Line items extracted | 147 total (avg 6.4 per invoice) |
The $757 duplicate was a real invoice that had been emailed twice — once in March, once in June. A human processing the June email would have paid it again.
The Stack
- n8n (self-hosted) — workflow orchestration
- Google Gemini — AI extraction (free tier handles ~1,500 invoices/month)
- Gmail API — email trigger
- Google Sheets API — ledger + audit trail
- Slack API — alerts
Total API cost: ~$0.06/week for 50 invoices. The Gemini free tier covers most small businesses.
Want the Workflow?
The full n8n workflow JSON is in my open-source portfolio:
→ github.com/Sasidhar-Sunkesula/n8n-workflow-showcase
It's workflow #07 (Invoice & Document Extraction Pipeline). Import the JSON directly into n8n, add your API keys, and you're running.
I also have 14 other production workflows covering client reporting, lead scoring, customer onboarding, competitor monitoring, support triage, and more.
→ Live portfolio + case studies
If You Want This Built for You
I do done-for-you n8n automation builds. For invoice extraction specifically:
- Basic ($100): Manual upload → AI extraction → Sheets ledger
- Standard ($300): Gmail auto-watch → extraction → duplicate detection → Sheets + Slack alerts
- Premium ($600): Full pipeline + anomaly detection + ERP/QuickBooks integration + monthly retainer
Message me or reach out through the portfolio site. Happy to do a paid pilot before any ongoing arrangement.
I'm Sasidhar — a Full-Stack Developer specializing in production n8n automation. 15 workflows in production across 8 domains. I write about practical automation with real test results, not theoretical AI.
Top comments (0)