Invoice Processing Workflow¶
Automate invoice data extraction from uploaded PDFs and save to your accounting system or spreadsheet.
Use Case¶
Problem: Manual data entry from invoices is time-consuming and error-prone.
Solution: Automatically extract invoice details (number, date, total, vendor, line items) and send to Google Sheets or accounting software.
Time Saved: ~5 minutes per invoice → Seconds
Workflow Overview¶
graph LR
A[Email with Invoice] --> B[Email Trigger]
B --> C[Filter: Has PDF]
C --> D[DeepTagger Extract]
D --> E[Google Sheets]
E --> F[Slack Notification]
Prerequisites¶
- DeepTagger Setup:
- Trained invoice extraction project
- Project ID (e.g.,
fo_1759714105892
) -
API key configured in n8n
-
n8n Nodes Required:
- Email Trigger (IMAP) or Webhook
- DeepTagger (community node)
- Google Sheets or Airtable
-
Slack (optional, for notifications)
-
Accounts:
- Email account for receiving invoices
- Google/Airtable account
- Slack workspace (optional)
Step-by-Step Setup¶
Step 1: Create the Workflow¶
- Open n8n
- Click "+" to create a new workflow
- Name it:
Invoice Processing Automation
Step 2: Add Email Trigger¶
- Add node: Email Trigger (IMAP)
- Configure:
- Test: Send yourself a test email with PDF attachment
Step 3: Add Filter Node (Optional but Recommended)¶
- Add node: Filter
- Configure:
This prevents processing emails without invoices.
Step 4: Add DeepTagger Node¶
- Add node: DeepTagger
- Select credential: Your DeepTagger API credential
- Configure:
!!! tip "Attachment Property"
Email nodes name attachments as attachment0
, attachment1
, etc.
- Test: Execute the node to verify extraction works
Step 5: Add Google Sheets Node¶
- Add node: Google Sheets
- Authenticate with Google account
- Configure:
Operation: Append Row Document: Invoice Tracker (create this spreadsheet) Sheet: Sheet1 Columns: - Invoice Number: {{$json["invoice_number"]}} - Date: {{$json["date"]}} - Vendor: {{$json["vendor"]}} - Total: {{$json["total"]}} - Email From: {{$node["Email Trigger"].json["from"]}} - Processing Date: {{$now}}
Step 6: Add Slack Notification (Optional)¶
- Add node: Slack
- Configure:
Step 7: Activate the Workflow¶
- Click "Active" toggle (top-right)
- Workflow is now running automatically!
Complete Workflow JSON¶
You can import this workflow directly:
{
"nodes": [
{
"name": "Email Trigger",
"type": "n8n-nodes-base.emailReadImap",
"position": [250, 300],
"parameters": {
"mailbox": "INBOX",
"options": {
"downloadAttachments": true
}
}
},
{
"name": "Filter PDF",
"type": "n8n-nodes-base.if",
"position": [450, 300],
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json[\"attachments\"] !== undefined && $json[\"attachments\"].length > 0}}",
"value2": true
}
]
}
}
},
{
"name": "DeepTagger",
"type": "n8n-nodes-deeptagger.deepTagger",
"position": [650, 300],
"parameters": {
"operation": "extractData",
"projectId": "fo_1759714105892",
"inputType": "file",
"binaryProperty": "attachment0"
},
"credentials": {
"deepTaggerApi": "DeepTagger Production"
}
},
{
"name": "Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [850, 300],
"parameters": {
"operation": "append",
"sheetId": "YOUR_SHEET_ID",
"range": "Sheet1",
"options": {},
"columns": {
"mappings": [
{
"key": "Invoice Number",
"value": "={{$json[\"invoice_number\"]}}"
},
{
"key": "Date",
"value": "={{$json[\"date\"]}}"
},
{
"key": "Vendor",
"value": "={{$json[\"vendor\"]}}"
},
{
"key": "Total",
"value": "={{$json[\"total\"]}}"
}
]
}
}
},
{
"name": "Slack",
"type": "n8n-nodes-base.slack",
"position": [1050, 300],
"parameters": {
"channel": "#accounting",
"text": "New invoice processed!\nInvoice #: {{$json[\"invoice_number\"]}}\nVendor: {{$json[\"vendor\"]}}\nTotal: {{$json[\"total\"]}}"
}
}
],
"connections": {
"Email Trigger": {
"main": [[{"node": "Filter PDF", "type": "main", "index": 0}]]
},
"Filter PDF": {
"main": [[{"node": "DeepTagger", "type": "main", "index": 0}]]
},
"DeepTagger": {
"main": [[{"node": "Google Sheets", "type": "main", "index": 0}]]
},
"Google Sheets": {
"main": [[{"node": "Slack", "type": "main", "index": 0}]]
}
}
}
Testing the Workflow¶
- Send test email:
- Email yourself with a sample invoice PDF
- Subject: "Test Invoice"
-
Attachment: invoice.pdf
-
Watch execution:
- Go to Executions tab
- Click on the running execution
-
Monitor each node's output
-
Verify results:
- Check Google Sheets for new row
- Verify data accuracy
- Check Slack for notification (if enabled)
Expected Output¶
DeepTagger Node Output¶
{
"invoice_number": "INV-2025-001",
"date": "2025-01-15",
"vendor": "Acme Corporation",
"total": "$1,234.56",
"subtotal": "$1,100.00",
"tax": "$134.56",
"line_items": [
{
"description": "Professional Services",
"quantity": "10",
"unit_price": "$100.00",
"amount": "$1,000.00"
},
{
"description": "Consulting",
"quantity": "2",
"unit_price": "$50.00",
"amount": "$100.00"
}
]
}
Google Sheets Output¶
Invoice Number | Date | Vendor | Total | Email From | Processing Date |
---|---|---|---|---|---|
INV-2025-001 | 2025-01-15 | Acme Corporation | $1,234.56 | vendor@acme.com | 2025-01-15 10:30:00 |
Advanced Enhancements¶
1. Error Handling¶
Add an IF node after DeepTagger to handle extraction failures:
// Check if extraction succeeded
{{$json["error"] === undefined && $json["invoice_number"] !== undefined}}
Success branch: Continue to Google Sheets
Failure branch: Send error notification, log to error database
2. Data Validation¶
Add a Code node to validate extracted data:
const data = $input.first().json;
// Validation rules
const errors = [];
if (!data.invoice_number || data.invoice_number.length < 3) {
errors.push("Invalid invoice number");
}
if (!data.total || !data.total.match(/\$[\d,]+\.\d{2}/)) {
errors.push("Invalid total format");
}
if (!data.date || !data.date.match(/\d{4}-\d{2}-\d{2}/)) {
errors.push("Invalid date format");
}
return {
json: {
...data,
validation_passed: errors.length === 0,
validation_errors: errors
}
};
3. Duplicate Detection¶
Add a Google Sheets lookup before appending:
1. Google Sheets (Lookup Rows)
- Search column: Invoice Number
- Search value: {{$json["invoice_number"]}}
2. IF Node
- If found: Skip or update existing
- If not found: Append new row
4. Multi-Attachment Processing¶
If emails can have multiple invoices, add a Loop node:
Then process each attachment through DeepTagger.
5. Archive Processed Emails¶
Add an Email node to move processed emails:
6. Accounting Software Integration¶
Instead of Google Sheets, integrate with:
- QuickBooks (via API)
- Xero (via n8n node)
- FreshBooks (via HTTP Request)
- Stripe (for billing)
Example for QuickBooks:
{
"Line": [
{
"Amount": "{{$json[\"total\"]}}",
"DetailType": "SalesItemLineDetail",
"SalesItemLineDetail": {
"ItemRef": {
"value": "1"
}
}
}
],
"CustomerRef": {
"value": "{{$json[\"vendor_id\"]}}"
}
}
Troubleshooting¶
No data extracted¶
Problem: DeepTagger returns empty object {}
Solutions: - Check Project ID is correct - Verify project is trained with similar invoices - Check invoice quality (is it readable?) - Test the project in DeepTagger dashboard first
Wrong attachment processed¶
Problem: Processing wrong file or no file
Solutions:
- Check attachment naming in Email node output
- Adjust Binary Property: try attachment1
, attachment2
, etc.
- Add Filter to only process first PDF attachment
Duplicate entries in spreadsheet¶
Problem: Same invoice processed multiple times
Solutions: - Implement duplicate detection (see Advanced #3) - Move processed emails to different folder - Check email trigger is not re-processing old emails
Data format doesn't match spreadsheet¶
Problem: Dates, numbers in wrong format
Solutions: - Add formatting in Google Sheets node expression:
// Format date
{{$json["date"].split("-").reverse().join("/")}}
// Format currency
{{$json["total"].replace("$", "").replace(",", "")}}
Real-World Results¶
Case Study: Small Accounting Firm¶
Before: - Processed 200 invoices/month manually - 5 minutes per invoice = 16.7 hours/month - Error rate: ~5%
After (with this workflow): - Automated processing: 200 invoices/month - Review time: 30 seconds per invoice = 1.7 hours/month - Error rate: <1%
Time Saved: 15 hours/month
ROI: Paid for DeepTagger subscription in 1 week
Next Steps¶
- Email Receipts Example - Process expense receipts
- Batch Processing Example - Handle bulk documents
- Form Extraction Example - Extract from text forms
- Troubleshooting Guide - Common issues
Share Your Workflow¶
Built something cool with DeepTagger? Share it!
- n8n Community Forum
- DeepTagger Discord (coming soon)
- Email us: support@deeptagger.com