Automate Accounts Payable with Make.com Router and Slack
Gmail → Cryvis Invoice API → Router on amount_due → Slack alert for high-value invoices and Google Sheets for the AP log.
What we're building
Every inbound invoice is logged to Sheets. Invoices with amount_due at or above a threshold also ping Slack so AP can prioritize. Below-threshold docs stay silent except for the sheet row.
Gmail: Watch Emails (label: AP)
|
v
Gmail: Get Attachment(s) + Filter (pdf/images)
|
v
HTTP: POST https://api.cryvis.com/v1/documents/invoice
|
v
JSON: Parse JSON
|
v
Router
|
+--[Route A: amount_due >= 5000]--> Slack: Create a Message
| + Sheets: Add a Row (priority=High)
|
+--[Route B: fallback]------------> Sheets: Add a Row (priority=Normal)Threshold 5000 is an example — set it to your approval policy (same currency assumed; see production notes for multi-currency).
What you need
- Make.com, Gmail, Slack, Google Sheets
- Gmail label
AP - Slack channel
#ap-alerts(bot invited) - Sheet
AP Log - Cryvis API key — Invoice
- Two sample invoices: one under and one over the threshold
Credits: per page/image.
Create the scenario
- Gmail — Watch Emails
- Attachment download / iterator
- Filter — file type
- HTTP — Make a Request
- JSON — Parse JSON
- Router
- Route A: Filter (
amount_due≥ threshold) → Slack — Create a Message → Sheets — Add a Row - Route B: Fallback → Sheets — Add a Row
Put Sheets on both routes so every invoice is logged. Slack only on Route A.
Configure source
Watch Emails on label AP, unread preferred.
Attachment Filter:
extension in {pdf, png, jpg, jpeg, webp}Ignore threads that are payment remittances without documents. If finance forwards “FYI” threads with old PDFs, teach them a dedicated AP-Inbound address instead of Reply-All chaos.
Configure Cryvis HTTP
| Setting | Value |
|---|---|
| URL | https://api.cryvis.com/v1/documents/invoice |
| Method | POST |
| Body type | Multipart/form-data |
| Field | file = attachment binary |
| Header | Authorization: Bearer <API_KEY> |
Docs: extractInvoice.
Process response
Fields used for routing and logging:
data.amount_due— Router condition (prefer overtotal_amountwhen partial payments exist on the doc)data.total_amount,data.subtotal,data.tax_totaldata.invoice_number,data.invoice_date,data.due_date,data.currencydata.seller.name,data.buyer.name
Router Filter on Route A:
data.amount_due Greater than or equal to 5000If amount_due is empty, fall through to Route B and set Priority Review in Sheets — do not Slack-alert on nulls as zero.
Router setup detail
- Add Router after Parse JSON.
- On the first route, open the funnel Filter icon between Router and Slack.
- Condition:
amount_dueNumeric: Greater than or equal to5000(map the field; do not compare as text or"5000.00"sorts wrong). - Enable Fallback on the last route so unmatched bundles still hit Sheets.
- Clone the Sheets module onto both routes with Priority set differently — or use one Sheets module after a second Router merge if you prefer a single write (more complex; two writes is clearer).
Order modules on Route A as Sheets then Slack if you would rather log a High row even when Slack is rate-limited.
Configure destination
Slack (Route A)
Message example:
High-value invoice
Vendor: {{data.seller.name}}
Number: {{data.invoice_number}}
Amount due: {{data.currency}} {{data.amount_due}}
Due: {{data.due_date}}
From: {{gmail.from}}
Subject: {{gmail.subject}}Pin the Cryvis dashboard or Airtable/Sheets link if you have one. Keep the message short — #ap-alerts fills up fast.
Sheets (both routes)
Columns:
Processed At | Priority | Invoice Number | Vendor | Buyer | Currency | Amount Due | Total | Due Date | From | Subject | Attachment | Gmail ID
| Priority | Route |
|---|---|
High | A |
Normal | B |
Review | B when amount missing |
Filters and error handling
- Pre-HTTP MIME Filter (save credits).
- Post-HTTP: only continue if
successis true. - Error Handler on HTTP → Slack
#ap-errorswith subject + status code (separate from high-value alerts). - Error Handler on Slack should not block Sheets — if Slack fails, still log the row (reorder modules: Sheets then Slack, or use resume directives).
- Data Store dedupe:
seller.name|invoice_numberbefore Router.
Currency trap: 5000 INR ≠ 5000 USD. Options:
- Separate labels / mailboxes per currency, or
- Router with compound Filters (
currency = USD AND amount_due >= 5000) plus another route forEUR, or - Normalize via a FX module before the Router (heavier).
Error Handler sketch
Attach an Error Handler route to the HTTP module:
HTTP (Invoice)
|
+-- success --> Router (amount routes)
|
+-- error ----> Slack #ap-errors
Sheets AP Errors tab
(file name, status, body snippet)Do not put the Error Handler Slack message in #ap-alerts — ops will treat extraction failures as high-value invoices.
Test
- Label a low-amount invoice email → expect Sheets
Normal, no Slack. - Label a high-amount invoice → Slack + Sheets
High. - Corrupt/non-invoice PDF → Error Handler path, no AP Log success row.
- Duplicate send → Data Store blocks second pass.
- Invoice with
amount_dueblank buttotal_amountfilled — confirm you either map a fallbackifempty(amount_due; total_amount)in the Filter or acceptReviewpriority.
Ops playbook after go-live
- AP owns the threshold number; engineering owns the scenario. Document both in the scenario notes field.
- When Slack fires, the assignee should open the Sheets row (filter Priority = High) and the Gmail message ID, not argue in the channel.
- Monthly: sample 10 Normal rows and 10 High rows against PDFs. Track extraction misses separately from policy misses (wrong threshold vs wrong
amount_due). - If vendors send statement PDFs (many invoices in one file), this flow still creates one extraction / one Sheets row for the statement totals — line-level AP needs line items or a different document type.
Production considerations
- Threshold changes: store the number in a Data Store or scenario variable so you do not edit Filters in three places.
- Quiet hours: optional Filter on time-of-day before Slack; Sheets still writes.
- Approval workflow: Slack message is a signal, not approval. Pair with Airtable AP status if you need state transitions.
- Audit: keep Gmail message ID on every row for dispute trails.
Next steps
Line-level detail: Extract invoice line items. Vendor CRM: Extract vendor details. Error patterns: Handle API errors.