Extract PAN Card Data with n8n: Google Drive to Google Sheets
Watch an India-KYC Drive folder, call Cryvis POST /v1/documents/pan with multipart $binary file, and append PAN number, name, and holder type to Google Sheets.
Indian KYC packs often land as PAN card scans in a shared Drive folder before anyone opens a CRM. This n8n workflow watches an India-KYC folder, sends each new file to Cryvis POST /v1/documents/pan, and appends structured rows to Google Sheets — including holder_type and pan_structure fields you can use for Individual vs Company routing.
Multi-document HubSpot flow: Automate KYC. Driver license companion: Extract driver's license data. Hub: /blog/n8n.
Architecture
Google Drive
/India-KYC/pan-inbox/
|
v (Trigger)
n8n workflow
|
v
POST https://api.cryvis.com/v1/documents/pan
multipart: file = $binary.data
Authorization: Bearer ...
|
v
Google Sheets
pan_number | full_name | father_name | dob | holder_type | ...Prerequisites
- Cryvis API key (Header Auth credential in n8n)
- Google Drive folder dedicated to PAN uploads (isolate from Aadhaar/passport)
- Google Sheet with a header row
- n8n Google Drive + Sheets + HTTP Request nodes
Step 1: Folder and Sheet schema
Drive path example: India-KYC / pan-inbox. Optionally move processed files to pan-done to avoid re-processing.
Sheet columns:
| Column | Cryvis data field |
|---|---|
| A processed_at | {{ $now.toISO() }} |
| B drive_file_id | Drive trigger |
| C file_name | Drive trigger |
| D pan_number | {{ $json.data.pan_number }} |
| E full_name | {{ $json.data.full_name }} |
| F father_name | {{ $json.data.father_name }} |
| G date_of_birth | {{ $json.data.date_of_birth }} |
| H holder_type_code | {{ $json.data.holder_type_code }} |
| I holder_type | {{ $json.data.holder_type }} |
| J series | {{ $json.data.pan_structure.series }} |
| K name_initial | {{ $json.data.pan_structure.name_initial }} |
| L sequence | {{ $json.data.pan_structure.sequence }} |
| M check_digit | {{ $json.data.pan_structure.check_digit }} |
| N status | ok / error |
Step 2: Watch Drive and download binary
Google Drive Trigger → File Created in Folder
- Folder:
pan-inbox - Restrict to images/PDF if the trigger allows MIME filters
Downstream: Google Drive → Download File so the item has $binary.data. Watching metadata alone is not enough for multipart upload.
Confirm binary is present before HTTP:
{{ $binary.data }} // must exist
{{ $binary.data.mimeType }} // image/jpeg, application/pdf, ...Step 3: Call Cryvis PAN
HTTP Request
| Setting | Value |
|---|---|
| Method | POST |
| URL | https://api.cryvis.com/v1/documents/pan |
| Authentication | Header Auth → Authorization: Bearer <API_KEY> |
| Body Content Type | Form-Data / Multipart |
| Response Format | JSON |
| Body Parameter | Type | Value |
|---|---|---|
file | n8n Binary File | Input Binary Field = data |
Supported types: PDF, JPEG, PNG, WebP. Field name must be exactly file (lowercase).
cURL equivalent:
curl -X POST https://api.cryvis.com/v1/documents/pan \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@pan-card.jpg"Step 4: Response fields
{
"success": true,
"data": {
"pan_number": "ABCPS1234F",
"full_name": "RAHUL SHARMA",
"father_name": "SURESH SHARMA",
"date_of_birth": "1992-08-14",
"holder_type_code": "P",
"holder_type": "Individual",
"pan_structure": {
"series": "ABC",
"holder_type_code": "P",
"holder_type": "Individual",
"name_initial": "S",
"sequence": "1234",
"check_digit": "F"
}
}
}After HTTP Request, expressions read under $json.data.*:
{{ $json.data.pan_number }}
{{ $json.data.full_name }}
{{ $json.data.holder_type_code }}
{{ $json.data.pan_structure.series }}holder_type_code is the 4th character semantics (e.g. P = Individual, C = Company). Use holder_type for human-readable Sheets filters.
Docs: /docs/api/extractPan · Product: /apis/pan.
Step 5: Append to Sheets
Google Sheets → Append Row
Map each column from Step 1. Nested structure:
series = {{ $json.data.pan_structure.series }}
name_initial = {{ $json.data.pan_structure.name_initial }}
sequence = {{ $json.data.pan_structure.sequence }}
check_digit = {{ $json.data.pan_structure.check_digit }}Set status = ok on the success path. Gate with IF:
{{ $json.success }} equals trueStep 6: Route by holder type
Add a Switch (or IF) after a successful extract:
| Output | Condition | Action |
|---|---|---|
| Individual | {{ $json.data.holder_type_code }} = P | Optional Slack “retail KYC” |
| Company | {{ $json.data.holder_type_code }} = C | Flag for entity KYC pack |
| Other | fallback | Ops review |
You are not calling another Cryvis endpoint here — only branching on returned enums.
Step 7: Move processed files
Google Drive → Move File from pan-inbox → pan-done. Prevents the trigger from re-ingesting the same scan.
Keep Drive file id from the trigger item. If a Set/Code node stripped binary but you still need the id, use a Merge (Combine by position) of the Drive metadata item with the HTTP response, or store drive_file_id in a Set node before HTTP.
Step 8: Errors
Attach an Error Trigger workflow (or Error Workflow on the HTTP node):
- Write a Sheets row with
status=error,pan_numberblank,file_nameset. - Move the file to
pan-failedinstead ofpan-done. - Alert Slack with Drive link only — not the image bytes.
Common issues:
- Wrong field name (
documentinstead offile) - Sending a URL string instead of
$binary.data - HEIC uploads (convert before Cryvis, or reject with IF on mimeType)
- Multi-page PDF of an entire KYC pack — prefer a cropped PAN-only file
Deduping and credits
Optional Sheets lookup on {{ $json.data.pan_number }}: Update if found, Append if not. Guard with IF {{ $json.data.pan_number.length }} Equal to 10. This workflow is extraction, not NSDL verification.
PAN is 1 credit per PDF page or image (Credits). Crop multi-page KYC packs to the PAN page. Move to pan-done so the trigger does not re-queue.
Related reading
- Automate KYC in n8n
- Extract driver's license data
- Extract Indian vehicle RC
- Convert PDFs to JSON
- /blog/n8n
CTA
Extract Indian PAN cards to JSON with Cryvis: /apis/pan. Docs: /docs/api/extractPan. From n8n, POST $binary.data as multipart file to https://api.cryvis.com/v1/documents/pan with Bearer auth and append {{ $json.data.pan_number }}, {{ $json.data.full_name }}, and {{ $json.data.holder_type }} to Sheets.