← Back to blog

Convert PDFs to JSON in Make.com with Custom Extractors

Turn non-standard PDFs into JSON in Make.com: create a Cryvis custom extractor, POST multipart file, map data into Google Sheets.

Standard invoices and receipts already have Cryvis built-ins. Everything else—utility bills, packing lists, inspection reports, vendor scorecards—needs a custom extractor: you define the JSON Schema once, then Make posts the PDF to POST https://api.cryvis.com/v1/custom-extractors/:slug.

There is still no generic PDF-to-JSON dump endpoint. Custom extractors are how you get a stable JSON contract for documents Cryvis does not ship as /v1/documents/*.

Hub: Make.com + Cryvis. Product: Custom extraction API. Schema reference: Custom extractor schemas.

When custom beats built-ins

Use a custom extractor when:

  • The PDF is not an invoice, receipt, passport, PAN, Aadhaar, driver’s license, or Indian RC.
  • You only need five fields from a dense form and want a closed schema (additionalProperties: false).
  • Multiple vendors share an internal template your finance team already named.

Stay on built-ins when the document is that type—invoice HTTP is faster to map and already models sellers, line items, and totals. Decision tree: Extract PDF data in Make.com.

End-to-end flow

Console: create extractor + schema
              |
              v
        slug assigned
              |
              v
Make: Watch Drive / Gmail attachment
              |
              v
HTTP POST /v1/custom-extractors/<slug>
      multipart field: file
              |
              v
Parse JSON → data.<your keys>
              |
              v
Google Sheets / Airtable / webhook

Credits: 1 per PDF page or 1 per image. MIME: PDF, JPEG, PNG, WebP. Auth: Bearer API key.

Step 1 — Schema in Console

In Console → Extractors:

  1. Name the extractor (e.g. Utility bill).
  2. Document description: short phrase injected into the model prompt (residential utility bill).
  3. Root schema: type: object, properties, prefer nullable unions ["string", "null"] / ["number", "null"].
  4. Mark critical IDs x-cryvis-validation: hard; noisy OCR fields soft.
  5. Save and copy the slug from the extractor detail page (path id used in the URL).

Minimal example for a utility bill:

{
  "type": "object",
  "properties": {
    "account_number": {
      "type": ["string", "null"],
      "description": "Utility account or customer number",
      "x-cryvis-validation": "hard"
    },
    "service_address": {
      "type": ["string", "null"],
      "description": "Service location as printed",
      "x-cryvis-validation": "soft"
    },
    "billing_period_start": {
      "type": ["string", "null"],
      "format": "date",
      "description": "Period start YYYY-MM-DD",
      "x-cryvis-validation": "soft"
    },
    "billing_period_end": {
      "type": ["string", "null"],
      "format": "date",
      "description": "Period end YYYY-MM-DD",
      "x-cryvis-validation": "soft"
    },
    "amount_due": {
      "type": ["number", "null"],
      "description": "Total amount due",
      "x-cryvis-validation": "soft"
    },
    "due_date": {
      "type": ["string", "null"],
      "format": "date",
      "description": "Payment due date",
      "x-cryvis-validation": "soft"
    }
  },
  "required": ["account_number"],
  "additionalProperties": false
}

Upload a real sample in Console and inspect meta.validation.warnings before you trust Make mappings. Field-design tips: Extract specific fields from PDFs. Full build walkthrough: Build a custom document extractor.

Step 2 — Make scenario: PDF → JSON → Sheets

Modules

  1. Google Drive — Watch Files in a Folder (PDF filter)
  2. Google Drive — Download a File
  3. HTTP — Make a Request
  4. Google Sheets — Add a Row (or Update a Row if you upsert by account number)

HTTP module

SettingValue
URLhttps://api.cryvis.com/v1/custom-extractors/YOUR_SLUG
MethodPOST
Body typeMultipart/form-data
HeaderAuthorization: Bearer sk_live_...
Field fileFile → map Drive binary; filename from Drive

Enable Parse response so Make exposes success, data, meta as mappable collections.

Successful response shape

{
  "success": true,
  "data": {
    "account_number": "48291033",
    "service_address": "12 Oak St",
    "billing_period_start": "2026-02-01",
    "billing_period_end": "2026-02-28",
    "amount_due": 94.2,
    "due_date": "2026-03-15"
  },
  "meta": {
    "document_type": "custom:YOUR_SLUG",
    "request_id": "...",
    "validation": {
      "is_valid": true,
      "warnings": [],
      "confidence": 1
    }
  }
}

Hard validation failures return 422 with error.code VALIDATION_ERROR—not a partial data object. Soft failures stay 200 with warnings in meta.validation.

Step 3 — Map into Sheets

ColumnMapping
Accountdata.account_number
Addressdata.service_address
Period startdata.billing_period_start
Amount duedata.amount_due
Due datedata.due_date
Valid?meta.validation.is_valid
Request IDmeta.request_id

Use ifempty() for nullable fields so empty cells stay empty instead of the literal string null. Nested objects and arrays: Map API JSON fields in Make.com.

Gmail variant

Replace Drive with Gmail — Watch EmailsIterate attachments → filter application/pdf → HTTP custom extractor → Sheets. Same multipart file mapping; binary comes from the attachment bundle (Upload a file to Cryvis).

Soft vs hard in production Make flows

ValidationHTTP statusMake behavior tip
Soft warning200Route on meta.validation.warnings length → Slack review queue
Hard fail422Error Handler → Break; fix schema or document
Bad key401Rotate Bearer token (auth guide)
No credits402Pause scenario; top up Console billing

Do not confuse with invoice JSON

POST /v1/documents/invoice returns seller, line_items, total_amount, etc. Your custom data only contains keys you declared. Mapping invoice paths onto a custom response will produce empty Sheets columns—not a Cryvis bug.

Checklist

  • Extractor created; slug copied into the HTTP URL
  • Schema tested in Console with a real PDF
  • Make multipart field name is exactly file
  • Sheets columns mirror schema keys (not invoice field names)
  • Error handler + optional Router for validation warnings

Next: wire multiple sources and destinations with the structured data pattern guide, or tighten field lists in extract specific fields.