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
| Setting | Value |
|---|---|
| Method | POST |
| URL | https://api.cryvis.com/v1/documents/<type> (full path) |
| Authentication | Header Auth, or Header Authorization = Bearer <API_KEY> |
| Body Content Type | Form-Data / multipart-form-data |
| Body parameter | Name = endpoint field (file, first_page, …), Type = File, Input Data Field Name = binary property (usually data) |
| Response | JSON (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 onlyIn 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
| API | URL | Form-Data |
|---|---|---|
| Invoice | /v1/documents/invoice | file ← $binary.data |
| Receipt | /v1/documents/receipt | file ← $binary.data |
| PAN | /v1/documents/pan | file ← $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.
Passport — first_page + last_page
URL: /v1/documents/passport
| Name | Type | Binary property |
|---|---|---|
first_page | File | biodata binary (required) |
last_page | File | final page binary (required) |
There is no file field on passport. Mapping a single PDF into file fails the contract.
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
| Symptom | Cause | Fix |
|---|---|---|
| 401 | Missing/wrong Bearer | Header Authorization: Bearer … with one space |
| 400 missing file | Wrong Form-Data name | Use file or passport first_page/last_page as documented |
| Empty fields mapped | Read top-level | Use {{ $json.data.* }} |
| Garbled upload | Sent URL / base64 in JSON body | Body Content Type = Form-Data, Type = File |
| Binary missing | Previous node renamed property | Match 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.