Automate Expense Tracking with Make.com
Parse Gmail receipt attachments with the Cryvis Receipt API and log expenses into Airtable — merchant, date, tax, and total without manual entry.
Most expense leakage is not fraud — it is delayed entry. Receipts sit in Gmail for weeks, then get typed into a tracker from memory. This scenario watches Gmail for receipt-like mail, extracts structured fields with Cryvis, and creates Airtable Expense records the same day.
Browse other Make recipes in the Make.com hub. Drive-based ingestion is covered in extract receipt data with Make.com. For approval gates before the ledger, see employee expense workflow.
Workflow
[Gmail: Watch Emails]
criteria: has:attachment newer_than:7d
|
v
[Iterator: Attachments]
|
v
[Filter: pdf|jpeg|png|webp]
|
v
[HTTP: Make a Request]
Cryvis POST /v1/documents/receipt
|
v
[Airtable: Create a Record]
Expenses table
|
v
[Gmail: optional label "Expense/Logged"]Modules
| Step | Module | Role |
|---|---|---|
| 1 | Gmail — Watch Emails | Trigger on new matching messages |
| 2 | Iterator | Walk each attachment |
| 3 | Filter | Keep receipt MIME types only |
| 4 | HTTP — Make a Request | Cryvis Receipt extraction |
| 5 | Airtable — Create a Record | Write the expense row |
| 6 | Gmail — Add Label (optional) | Mark mail as processed |
| 7 | Router (optional) | Split retail vs travel by receipt_type |
Gmail search that works well for expense inboxes:
has:attachment (receipt OR invoice OR "order confirmation") -label:Expense/LoggedStart with -label:Expense/Logged so reprocessing is controlled. Invoice PDFs from vendors may belong in a separate Cryvis Invoice scenario — see extract invoice data with Make.com — because invoice schemas differ from receipts.
Cryvis HTTP configuration
| Setting | Value |
|---|---|
| URL | https://api.cryvis.com/v1/documents/receipt |
| Method | POST |
| Auth header | Authorization: Bearer <API_KEY> |
| Body | Multipart/form-data |
file | Attachment binary from Iterator |
One attachment = one HTTP call = one Airtable record. Do not bundle all attachments into a single multipart batch unless you also add an Iterator over results[]. Batch envelopes are documented in convert receipts to JSON.
Credits: 1 per page/image. A four-page PDF attachment costs four credits. Prefer single-page scans for email receipts.
API docs: extractReceipt. Product: Receipt API.
Fields you will map from data
data.receipt_number
data.transaction_date
data.transaction_time
data.merchant.name
data.location.city
data.payment.method
data.currency
data.subtotal
data.tax_total
data.total_amount
data.amount_paid
data.receipt_type
data.notes
data.line_items[] (optional linked table)Response mapping to Airtable
Suggested Expenses table:
| Airtable field | Type | Mapping |
|---|---|---|
Receipt Number | Single line text | data.receipt_number |
Merchant | Single line text | data.merchant.name |
Date | Date | data.transaction_date |
Amount | Currency / Number | data.total_amount |
Tax | Number | data.tax_total |
Subtotal | Number | data.subtotal |
Currency | Single select or text | data.currency |
Payment | Single select | data.payment.method |
Category | Single select | Map from receipt_type or leave blank for humans |
Source Email | URL / text | Gmail message link or Message-ID |
Attachment Name | Text | Iterator filename |
Status | Single select | Default Logged |
Employee | Collaborator / text | Parse from From: if you use a shared alias |
Airtable currency fields are single-currency per base in many setups. If you process multi-currency mail, store Amount as Number and keep Currency as text, then convert in a reporting view.
Line items
If you need SKU-level detail (rare for expense reimbursement, common for card reconciliation):
- After HTTP success, add Iterator on
data.line_items. - Airtable — Create a Record in a
Line Itemstable with a link to the parent Expense. - Map
description,quantity,unit_price,amount.
Skip this until the parent Expense flow is stable. Empty line_items arrays are normal for faded thermal receipts; parent totals still populate.
Destination specifics: Airtable
- Use Create a Record, not Update, for first-write expense logs.
- Add a unique formula or automations later; for Make-side dedupe, query Airtable for existing
Receipt Number+Datebefore Create. If both match, route to Update or Skip. - Views:
This week,Missing receipt number,Foreign currency,Needs category. - Attach the original file to an Airtable Attachment field by re-uploading the Gmail binary — useful when auditors ask for proof without digging through mail.
Employee identity: if expenses arrive from expenses+alex@company.com, parse the local-part into Employee. If everyone forwards to one inbox, require a Google Form instead (employee expense workflow).
Filters and edge cases
Filter after Iterator:
- Content-Type in
application/pdf,image/jpeg,image/png,image/webp - Filename not matching
smime|signature|logo|banner
Edge cases:
- HTML-only receipts: many retailers email HTML without a PDF. This attachment path will miss them. Add a parallel branch that saves the email as PDF via a converter, or ask vendors for PDF receipts.
- Password-protected PDFs: Cryvis cannot open them; send those to a Failures view.
- Multiple receipts in one PDF: you get one extraction pass over the document; prefer one receipt per file for clean
total_amount. - Tips: restaurant tips may appear in
notesor fold intototal_amount. Compareamount_paidvstotal_amountwhen both exist. - Forwarded threads: Watch Emails can fire on replies. Prefer
is:inbox+ label gating, or filter on Attachment count > 0 and subject keywords.
Errors
| Failure | Handling |
|---|---|
| No attachments | End branch silently |
| HTTP 401 | Break + notify admin |
Soft success: false | Create Airtable record in Failures with subject + filename |
| Airtable RATE_LIMIT | Incomplete execution / retry |
| Duplicate receipt | Filter after Airtable Search; skip Create |
Wire a Slack Error Handler only for auth and sustained 5xx — not for every logo PNG that fails the MIME filter.
Test plan
- Send yourself an email with a single JPEG receipt attached.
- Confirm Iterator yields one bundle and Filter passes.
- Inspect HTTP output:
data.merchant.nameanddata.total_amount. - Confirm Airtable row exists with Source Email populated.
- Re-run with a PNG logo attachment — Filter should drop it.
- Send a 2-page PDF; verify credit usage is 2 and totals still look right.
Gmail-specific operational notes
Shared inboxes (expenses@company.com) need a single Make connection with permission to read mail and apply labels. Avoid personal OAuth connections that break when an employee leaves.
Threading: if vendors send “receipt attached” follow-ups without new files, your Watch criteria should require attachments. Pair with filename:(pdf OR jpg OR jpeg OR png OR webp) when the provider search supports it.
When finance still wants human categorization, leave Category empty and build an Airtable Interface with a single-select. Do not invent categories from receipt_type unless you have validated mappings (e.g. fuel → Travel, grocery → Meals only if policy says so).
For approval before Airtable becomes the system of record, insert Slack between HTTP and Create a Record — same pattern as employee expense workflow, swapping Sheets for Airtable.
Production checklist
- Dedicated Gmail label workflow so humans can see what automation touched.
- Airtable interface for finance review (
Status = Logged→Approved). - API key rotation documented; Make scenario cloning for staging inbox.
- Credit alerts for mail storms (travel weeks).
- Retention: decide whether to keep Gmail originals after Airtable attachment upload.
- Separate Failures view with Subject, From, Filename, HTTP status for weekly triage.
Related guides
- Extract receipt data (Drive → Sheets)
- Extract receipt data from images
- Receipt to Google Sheets
- Make.com hub
CTA
Replace weekend expense entry with an API call. The Cryvis Receipt API accepts multipart receipt files and returns merchant, tax, totals, and line items as JSON. Read the extractReceipt documentation and wire it into Make with Bearer auth.