← Back to blog

HTTP Request OCR Setup for Cryvis in n8n

Configure n8n HTTP Request for Cryvis multipart OCR: Bearer auth, Form-Data file fields, $binary.data, and endpoint field variants.

Every Cryvis extraction call is multipart/form-data with Bearer auth. n8n has no Cryvis node — you use HTTP Request and map a binary property from the previous node into a Form-Data field. Get the field name wrong and the API returns a client error even when $binary.data is present.

This post is the building block for invoice, receipt, passport, Aadhaar, and the rest. Hub: n8n + Cryvis. Credits: 1 per page/image.

Baseline HTTP Request settings

SettingValue
MethodPOST
URLhttps://api.cryvis.com/v1/documents/<type> (full path)
AuthenticationHeader Auth, or Header Authorization = Bearer <API_KEY>
Body Content TypeForm-Data / multipart-form-data
Body parameterName = endpoint field (file, first_page, …), Type = File, Input Data Field Name = binary property (usually data)
ResponseJSON (default)

Do not set Content-Type yourself — n8n adds the multipart boundary. Forcing application/json breaks the upload.

Store the key in an n8n credential. On self-hosted instances, prefer env-backed credentials your ops team rotates.

Binary rule

File bytes live in $binary, not $json. After Google Drive download, Gmail attachment, or Read Binary File, the default property is usually data:

$binary.data          → bytes + mimeType + fileName
$binary.data.fileName → metadata only

In HTTP Request Form-Data, set the File parameter’s input field name to data (or whatever binaryPropertyName the previous node used). Sending a Drive URL string as the file body will fail.

Endpoint field variants

Single file — invoice, receipt, PAN, custom

APIURLForm-Data
Invoice/v1/documents/invoicefile$binary.data
Receipt/v1/documents/receiptfile$binary.data
PAN/v1/documents/panfile$binary.data
Custom/v1/custom-extractors/<slug>file$binary.data

Products: Invoice, Receipt, PAN, Custom.

Aadhaar — one or two parts named file

URL: /v1/documents/aadhaar

Add one or two Form-Data rows both named file, each pointing at a different binary property (e.g. data and data_back). Not front/back — those names are for vehicle RC.

Aadhaar · extractAadhaar.

Passport — first_page + last_page

URL: /v1/documents/passport

NameTypeBinary property
first_pageFilebiodata binary (required)
last_pageFilefinal page binary (required)

There is no file field on passport. Mapping a single PDF into file fails the contract.

Passport · extractPassport.

Indian vehicle RC — front / back

URL: /v1/documents/indian-vehicle-rc — Form-Data front and/or back as File. Indian vehicle RC.

Driver license — file + country

URL: /v1/documents/driver-license — File file plus Text country (ISO 3166-1 alpha-3, e.g. IND, USA). Missing country → MISSING_COUNTRY. Driver license.

ASCII cheat sheet

invoice / receipt / pan / custom  →  file
aadhaar                           →  file [, file]
passport                          →  first_page + last_page
indian-vehicle-rc                 →  front + back
driver-license                    →  file + country (text)

Response envelope and expressions

Cryvis returns:

{
  "success": true,
  "data": { "...": "fields depend on endpoint" },
  "meta": {}
}

After HTTP Request, expressions read the parsed body:

{{ $json.success }}
{{ $json.data.invoice_number }}
{{ $json.data.seller.name }}

Not {{ $json.invoice_number }} — fields live under data.

IF after HTTP Request

IF {{ $json.success }} equals true
  → Sheets / Postgres / Slack
ELSE
  → Error path (Set node with status + body snippet)

Optional: enable Retry on Fail on the HTTP Request node for transient 5xx. Do not retry endlessly on 400 (bad multipart / MIME).

Error Trigger pattern

For production workflows, add an Error Trigger workflow that receives failed executions and posts to Slack: workflow name, node name, HTTP status, message. Keep PII out of Slack — log file name and status, not full document JSON for KYC docs.

Self-hosted note: Error Trigger + execution pruning settings matter when binaries sit in execution history. Shorten retention for KYC-heavy workflows.

MIME and credits

Accepted (typical): application/pdf, image/jpeg, image/png, image/webp.

Credits: 1 per PDF page or image. Two passport images = two credits. See Credits and Pricing.

Minimal test flow

Manual Trigger
  → Read Binary File (or Drive Download → $binary.data)
  → HTTP Request (Form-Data file = data)
  → IF {{ $json.success }}
  → Set: invoice_number = {{ $json.data.invoice_number }}

Run once, inspect HTTP Request output JSON before wiring destinations. That separates auth/multipart bugs from mapping bugs.

Common failures

SymptomCauseFix
401Missing/wrong BearerHeader Authorization: Bearer … with one space
400 missing fileWrong Form-Data nameUse file or passport first_page/last_page as documented
Empty fields mappedRead top-levelUse {{ $json.data.* }}
Garbled uploadSent URL / base64 in JSON bodyBody Content Type = Form-Data, Type = File
Binary missingPrevious node renamed propertyMatch Input Data Field Name to actual binaryPropertyName

Next tutorials

Sign up, create a key, and wire HTTP Request against extractInvoice or any endpoint above. Full index: /blog/n8n.