← Back to blog

Extract Invoice Data into Google Sheets with Make.com

Build a Make.com scenario: Drive Watch Files → Cryvis Invoice API → Google Sheets. Map invoice_number, dates, seller, and totals.

What we're building

A Drive folder drops PDFs or images. Make downloads each file, posts it to Cryvis, and appends one Sheets row with header fields — number, dates, vendor, totals. No line-item expansion; one document → one row.

Google Drive: Watch Files (folder)
        |
        v
Google Drive: Download a File
        |
        v
HTTP: Make a Request
  POST https://api.cryvis.com/v1/documents/invoice
  multipart field: file
        |
        v
JSON: Parse JSON
        |
        v
Google Sheets: Add a Row
  invoice_number | invoice_date | due_date | currency
  seller.name | buyer.name | subtotal | tax_total
  total_amount | amount_due | file name

What you need

  • Make.com account
  • Google Drive folder for inbound invoices (shared with the Make connection)
  • Google Sheet with a header row (columns listed in step 7)
  • Cryvis API key — Invoice API, docs at /docs/api/extractInvoice
  • Sample invoice PDF or JPEG/PNG/WebP

Credits: 1 per PDF page or image. See Credits.

Create the scenario

New scenario → add modules in this order:

  1. Google Drive — Watch Files (Trigger)
  2. Google Drive — Download a File (Action)
  3. HTTP — Make a Request (Action)
  4. JSON — Parse JSON (Action)
  5. Google Sheets — Add a Row (Action)

Optional later: Error Handler on the HTTP module, Filter after Watch Files for MIME type.

Configure source

Watch Files

  • Connection: your Google account
  • Select the inbound folder
  • Watch for: all files, or limit to application/pdf if your Drive connection exposes MIME filters
  • Limit: start with 1–2 files while testing

Download a File

  • File ID: map from Watch Files → File ID
  • Output: binary data Make can attach as multipart

Edge case: Drive sometimes delivers Google Docs mime types. Stick to uploaded PDFs/images. If a file is a Docs export, convert to PDF first or filter it out.

Configure Cryvis HTTP

HTTP — Make a Request

SettingValue
URLhttps://api.cryvis.com/v1/documents/invoice
MethodPOST
Body typeMultipart/form-data
Request contentField name file, map binary from Download a File
HeadersAuthorization = Bearer <API_KEY>

Do not set Content-Type manually — Make sets the multipart boundary. Forcing application/json will break the upload.

Accepted MIME: pdf, jpeg, png, webp. Up to 20 files per request if you batch later; this tutorial sends one file per run.

Timeout: set the HTTP module timeout high enough for multi-page PDFs (60–120s is safer than the default on large scans). Parse response as JSON when Make offers the option; otherwise keep JSON — Parse JSON as the next step.

If the module returns a string body, Confirm success is boolean true, not the string "true", before you trust the mapper.

Process response

Cryvis returns roughly:

{
  "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", "tax_id": "US12-3456789" },
    "buyer": { "name": "Globex Corporation" },
    "line_items": [],
    "subtotal": 1148.98,
    "tax_total": 94.79,
    "total_amount": 1193.77,
    "amount_due": 1193.77
  },
  "meta": {}
}

JSON — Parse JSON: feed Data / body string from HTTP if Make did not already parse it. Then map:

  • data.invoice_number
  • data.invoice_date
  • data.due_date
  • data.currency
  • data.seller.name
  • data.buyer.name
  • data.subtotal
  • data.tax_total
  • data.total_amount
  • data.amount_due

Nested objects (seller, buyer) need dotted paths. Do not write the whole seller object into a single cell unless you want raw JSON.

Configure destination

Sheet headers (row 1):

Invoice Number | Invoice Date | Due Date | Currency | Vendor | Buyer | Subtotal | Tax | Total | Amount Due | Source File | Processed At

Add a Row mapping:

ColumnSource
Invoice Numberdata.invoice_number
Invoice Datedata.invoice_date
Due Datedata.due_date
Currencydata.currency
Vendordata.seller.name
Buyerdata.buyer.name
Subtotaldata.subtotal
Taxdata.tax_total
Totaldata.total_amount
Amount Duedata.amount_due
Source FileDrive file name
Processed Atnow (Make formula)

Leave line_items for a dedicated flow — see Extract invoice line items.

Filters and error handling

Filter after Watch Files (recommended):

  • Continue only if file name ends with .pdf, .jpg, .jpeg, .png, or .webp

Error Handler on HTTP:

  • On 4xx / 5xx, write a row to an “Errors” sheet: file name, status code, response body snippet
  • Or break the scenario and notify Slack (pattern in Automate accounts payable)

Check success === true with a Filter before Add a Row so failed extractions do not create blank finance rows.

Test

  1. Drop one known invoice into the Drive folder.
  2. Run once (or wait for the Watch interval).
  3. Confirm HTTP status 200 and success: true.
  4. Verify Sheets columns match the PDF header — especially currency and amount_due vs total_amount.
  5. Re-run the same file only if you accept duplicate rows; otherwise move processed files to an archive folder as a second Drive module.

Troubleshooting

SymptomLikely causeFix
401 / 403Bad or missing Bearer tokenRecreate the key; header must be Authorization: Bearer … with a single space
415 / validation errorWrong body typeMultipart field name must be file, not document or attachment
Empty Sheets rowMapping from top-level instead of dataUse data.invoice_number, not invoice_number on the envelope
Duplicate rowsWatch re-fires on same fileMove to Processed after success; add Data Store dedupe
Credits higher than expectedMulti-page PDFEach page = 1 credit — see Credits

Run the HTTP module in isolation with “Run this module only” and inspect the raw JSON before wiring Sheets. That separates API issues from mapping bugs.

Production considerations

  • Archive after success: Google Drive — Move a File to /Invoices/Processed so Watch Files does not re-pick the same PDF.
  • Scheduling: shorten Watch interval only if credit burn and API rate limits are fine.
  • Multi-page PDFs: each page costs 1 credit; huge statements will add up.
  • Idempotency: store invoice_number + vendor in a Data Store and Filter duplicates before Sheets.

Next steps

Need AP status fields and Gmail intake instead of Drive? Use Automate invoice processing. For Notion as the destination: Extract invoice data from PDFs.

API reference: extractInvoice · Product page: Invoice · Hub: Make.com + Cryvis.