Automate Invoice Processing from Gmail with Zapier
Gmail New Attachment → Cryvis Invoice API → Google Sheets row plus Slack alert. Optional Paths for amount thresholds.
What we're building
Vendors email invoices. Zapier catches the attachment, extracts fields with Cryvis, appends a Sheets row, and posts a Slack message. Optional Paths route high-amount invoices to a review channel.
Gmail: New Attachment
|
v
Filter: MIME / filename is pdf|jpeg|png|webp
|
v
Webhooks by Zapier: Custom Request
POST https://api.cryvis.com/v1/documents/invoice
multipart: file
|
v
Filter: success is true
|
v
Paths (optional)
A: amount_due >= threshold → Slack #ap-review
B: otherwise → Slack #ap-inbox
|
+--→ Google Sheets: Create Spreadsheet Row (both paths)Drive → Sheets only: Extract invoice data. Airtable destination: Invoice to Airtable. Hub: Zapier + Cryvis.
What you need
- Zapier + Gmail connection (mailbox that receives vendor invoices)
- Gmail label or search that isolates invoice mail (recommended: label
Invoices) - Google Sheet with AP header row
- Slack workspace + channel(s)
- Cryvis API key — Invoice API
Credits: 1 per PDF page or image.
Create the Zap
- Gmail — New Attachment (Trigger)
- Filter — keep supported files
- Webhooks by Zapier — Custom Request
- Filter —
successis true - Google Sheets — Create Spreadsheet Row
- Slack — Send Channel Message
- Optional: Paths before Slack (or before Sheets) for amount branching
Configure source
New Attachment
- Account: the AP mailbox
- If the trigger supports label/search filters, scope to
label:Invoicesorhas:attachment subject:invoice - Prefer unread-only if available so you do not double-process
Filter after trigger:
Filename ends with .pdf OR .png OR .jpg OR .jpeg OR .webp
AND Size / attachment existsSkip calendar invites, logos, and signature images. One email with a PDF invoice plus a PNG logo should keep the PDF and drop the logo when you also require PDF or a minimum size.
Configure Cryvis HTTP
| Piece | Value |
|---|---|
| Method | POST |
| URL | https://api.cryvis.com/v1/documents/invoice |
| Header | Authorization: Bearer <API_KEY> |
| Body | multipart/form-data |
| Part | file = attachment binary |
Do not send the email body as JSON. The attachment binary is the only file Cryvis needs for invoice OCR.
Docs: extractInvoice. Multipart names: Send multipart form data.
Example response
{
"success": true,
"data": {
"invoice_number": "INV-2024-00142",
"invoice_date": "2024-03-15",
"due_date": "2024-04-14",
"currency": "USD",
"seller": { "name": "Acme Cloud Services" },
"buyer": { "name": "Globex Corporation" },
"line_items": [],
"subtotal": 1148.98,
"tax_total": 94.79,
"total_amount": 1193.77,
"amount_due": 1193.77
},
"meta": {}
}Sheets mapping
Headers:
Invoice Number | Invoice Date | Due Date | Currency | Vendor | Total | Amount Due | From | Subject | Message Link | Processed At
| Column | Source |
|---|---|
| Invoice Number | data.invoice_number |
| Invoice Date | data.invoice_date |
| Due Date | data.due_date |
| Currency | data.currency |
| Vendor | data.seller.name |
| Total | data.total_amount |
| Amount Due | data.amount_due |
| From | Gmail from address |
| Subject | Gmail subject |
| Message Link | Gmail message URL if available |
| Processed At | current timestamp |
Slack notification
Send Channel Message body example:
New invoice extracted
Vendor: {{data.seller.name}}
Number: {{data.invoice_number}}
Amount due: {{data.currency}} {{data.amount_due}}
Due: {{data.due_date}}
From: {{gmail.from}}
Sheet row created.Paths for amount threshold
After the success Filter, add Paths:
Path A — High value
Condition: data.amount_due (Number) greater than or equal to 5000
→ Slack channel #ap-review
→ Sheets row (Status / note: needs approval)
Path B — Standard
Fallback
→ Slack channel #ap-inbox
→ Sheets rowThreshold is business logic in Zapier — Cryvis only returns amount_due. Use Formatter to coerce the number if the mapper treats it as text.
Error handling
| Case | Action |
|---|---|
| Custom Request 401 | Fix API key; stop — do not loop |
| 400 / missing file | Attachment Filter too loose or wrong part name |
success: false | Filter stops Sheets/Slack; inspect Zap history body |
| Slack fails after Sheets | Sheets row still exists — fix Slack and replay from history if needed |
Check Zap history for the Custom Request step first when debugging. That isolates Cryvis from destination apps.
Test
- Send yourself a labeled email with one known invoice PDF.
- Run / wait for New Attachment.
- Confirm Custom Request
success: truein Zap history. - Verify Sheets columns and Slack text (currency + amount_due).
- Send a second invoice above the Path threshold and confirm
#ap-review.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Zap fires on logos | Weak MIME Filter | Require .pdf or min size |
| Empty vendor | Mapped wrong path | data.seller.name |
| Path never takes A | amount as text | Formatter → Number before Paths |
| Duplicate rows | Same email reprocessed | Mark read / archive after success; Filter unread |
Production notes
- Dedicate a mailbox or label; do not watch personal mail.
- Archive or mark processed after success so New Attachment stays quiet.
- Multi-page PDFs: 1 credit per page — see Credits.
- Keep the API key out of shared Zap templates.