Extract Invoice Data from Dropbox PDFs into Notion
Make.com: Dropbox Watch Files → Download → Cryvis Invoice API → Notion Create Database Item. Map seller, buyer, dates, and totals.
What we're building
Finance drops vendor PDFs into a Dropbox folder. Make downloads each file, calls Cryvis, and creates a Notion database item with invoice headers. Useful when the AP tracker already lives in Notion instead of Sheets.
Dropbox: Watch Files (/Finance/Invoices/Inbox)
|
v
Dropbox: Download a File
|
v
HTTP: POST https://api.cryvis.com/v1/documents/invoice
Authorization: Bearer <API_KEY>
multipart: file
|
v
JSON: Parse JSON
|
v
Notion: Create a Database Item
Title = invoice_number + seller.name
Properties = dates, currency, amounts, parties
|
v
Dropbox: Move a File → /Finance/Invoices/ProcessedWhat you need
- Make.com with Dropbox and Notion connections
- Dropbox folders:
InboxandProcessed - Notion database (full-page database) with properties listed below
- Cryvis API key — Invoice / docs
- Sample multi-page and single-page PDFs
Credits: 1 credit per PDF page or image.
Create the scenario
- Dropbox — Watch Files (Trigger)
- Dropbox — Download a File
- HTTP — Make a Request
- JSON — Parse JSON
- Filter —
successis true - Notion — Create a Database Item
- Dropbox — Move a File (archive)
Configure source
Watch Files
- Path:
/Finance/Invoices/Inbox - Watch: files only (not folders)
- Limit: low while testing
Download a File
- Map file path / ID from Watch Files
- Ensure binary output is available to HTTP
Edge case: Dropbox Paper files and .docx must not hit the invoice endpoint. Filter:
Name ends with .pdf OR .png OR .jpg OR .jpeg OR .webpShared team folders: use the connection that owns the team space, or the Watch will see nothing.
Configure Cryvis HTTP
| Setting | Value |
|---|---|
| URL | https://api.cryvis.com/v1/documents/invoice |
| Method | POST |
| Body type | Multipart/form-data |
| Field name | file |
| Field value | Dropbox file binary |
| Header | Authorization: Bearer <API_KEY> |
Do not URL-encode the file. Do not send the Dropbox share link as text — Cryvis needs the bytes, not a URL string.
Why Download is mandatory: Watch Files metadata alone is not enough. The HTTP multipart part must be the file content. If you map a path string into file, Cryvis receives text, not a PDF, and extraction fails.
After a successful response, keep the Dropbox path and content-hash (if available) on the Notion item so you can prove which binary produced which extraction when auditors ask.
Process response
Primary fields for Notion properties:
data.invoice_numberdata.invoice_datedata.due_datedata.currencydata.seller.name,data.seller.tax_iddata.buyer.namedata.subtotal,data.tax_total,data.total_amount,data.amount_due
Notion title property cannot be empty. Build it as:
{{data.invoice_number}} — {{data.seller.name}}If invoice_number is missing, fall back to Dropbox filename + date.
line_items is an array — Notion cannot store it cleanly in one property without JSON text. Either:
- Store
line_itemsas a Code/JSON property (long text), or - Split rows in a child database with an Iterator (line items guide)
This tutorial stores a truncated JSON string in Line Items (raw) for audit only.
Configure destination
Notion database properties:
| Property | Type | Mapping |
|---|---|---|
| Name (title) | Title | invoice_number — seller.name |
| Invoice Number | Rich text | data.invoice_number |
| Invoice Date | Date | data.invoice_date |
| Due Date | Date | data.due_date |
| Currency | Select or text | data.currency |
| Vendor | Rich text | data.seller.name |
| Vendor Tax ID | Rich text | data.seller.tax_id |
| Buyer | Rich text | data.buyer.name |
| Subtotal | Number | data.subtotal |
| Tax | Number | data.tax_total |
| Total | Number | data.total_amount |
| Amount Due | Number | data.amount_due |
| Status | Select | Inbox |
| Source Path | Rich text | Dropbox path |
| Line Items (raw) | Rich text | stringify data.line_items |
Date properties: if Cryvis returns YYYY-MM-DD, map directly. If Make treats them as strings, wrap with a date parse function in the mapper.
Move a File after create: destination /Finance/Invoices/Processed/{{filename}}. Fail the move only after Notion succeeds so a Notion outage does not archive unread files.
If Processed already contains the same filename, Dropbox Move may fail. Prefix with a timestamp or invoice number:
/Finance/Invoices/Processed/{{data.invoice_number}}_{{filename}}That also makes manual lookup easier when finance digs through the archive.
Filters and error handling
- Filter: MIME / extension before HTTP.
- Filter: HTTP status 2xx and
successtrue before Notion. - Error Handler on HTTP: create a Notion item in a separate Extraction Errors database (or send Slack). Include Dropbox path and response body.
- Duplicate check: Notion has no native unique constraint. Use a Data Store keyed by
seller.name|invoice_numberor search Notion for an existing item before create (Search Objects → Filter → Create only if empty).
Test
- Upload a known PDF to Inbox.
- Run once; confirm Notion title and Amount Due.
- Confirm file moved to Processed.
- Upload a
.txt— Filter should skip Cryvis. - Upload a 3-page PDF — expect 3 credits (Credits); Notion still gets one database item for the whole document (credits track pages, Notion items track documents).
Notion-specific pitfalls
- Select vs text for Currency: if Currency is a Select, every ISO code you encounter (
USD,EUR,INR) must exist as an option or Notion rejects the write. Prefer rich text until the set stabilizes. - Date timezone: Notion dates are date-only for invoice fields; do not convert
2024-03-15through a timezone that shifts the calendar day. - Title length: very long vendor names + invoice numbers can hit Notion limits — truncate vendor to 80 chars in the title formula if needed; keep the full name in the Vendor property.
- Concurrent Watches: two scenario runs on the same file (manual + scheduled) can create duplicate Notion pages before Move completes. Use a short Data Store lock keyed by Dropbox file ID around the HTTP→Notion section.
Production considerations
- Notion API rate limits: batch large backfills overnight, not every 1 minute Watch on a cold folder of 500 PDFs.
- Property type mismatches (text into Number) fail the Notion module — coerce amounts with
parseNumber/ formatters. - Permission: the Make Notion connection needs insert access on the database, not only the parent page.
- Retention: Processed Dropbox folder lifecycle rules (delete after 90 days) keep storage down; Notion remains the system of record.
Next steps
Sheets instead of Notion: Extract invoice data. Gmail intake: Automate invoice processing. HubSpot vendors: Extract vendor details.