← Back to blog

Automate KYC in Zapier: Forms to Passport, PAN, Aadhaar, and HubSpot

Build a Zap that routes form or Drive KYC uploads by document type to Cryvis Passport, PAN, and Aadhaar APIs via Paths, then writes contact fields and KYC status to HubSpot.

Manual KYC review does not scale. Applicants upload mixed ID packs, ops teams rename files, and CRM fields stay empty until someone types them in. This tutorial builds a Zap that takes a Google Forms / Typeform-style multi-file submission (or a Drive drop with a doc-type field), branches with Paths by Zapier, calls the matching Cryvis extraction endpoint, and updates a HubSpot contact with structured identity data plus a KYC status.

You will wire:

  • Form or Drive as intake
  • Paths that branch on document type
  • Cryvis POST /v1/documents/passport, /pan, and /aadhaar
  • HubSpot contact create/update with KYC status

Focused singles: PAN, driver's license. Hub: /blog/zapier.

Architecture

Form / Typeform / Drive (doc type + files)
        |
        v
   Zapier
        |
   Paths by Zapier
   +----+----+----+
   |         |    |
   v         v    v
Passport   PAN  Aadhaar
 (Cryvis) (Cryvis) (Cryvis)
   |         |    |
   +----+----+----+
        |
        v
  HubSpot Contact
  + KYC status

Every Cryvis call uses:

POST https://api.cryvis.com/v1/documents/<type>
Authorization: Bearer YOUR_API_KEY
Content-Type: multipart/form-data

Create an API key in the Cryvis console. Store it in a Zapier secret or private field — not in shared Zap templates.

Step 1: Intake — form or Drive

Option A: Google Forms / Typeform

FieldTypePurpose
EmailEmailHubSpot contact key
Full nameShort textFallback display name
Document typeMultiple choicepassport / pan / aadhaar
ID uploadFile upload (multiple)Document images

Trigger: Google Forms → New Response or Typeform → New Entry. Download uploads to binary before Custom Request (URL alone is not a multipart file).

Option B: Google Drive with doc-type field

Trigger: Google Drive → New File in Folder. Resolve document_type from a companion Sheet row keyed by folder name, or a filename prefix (passport_, pan_, aadhaar_). Passport needs biodata + final page (first_page + last_page). Aadhaar accepts 1–2 parts named file.

Step 2: Normalize before Paths

Use Formatter / Storage / Code by Zapier:

doc_type          = lowercase document_type   # passport | pan | aadhaar
email             = email
applicant_name    = full_name
file_1            = first uploaded binary
file_2            = second uploaded binary (optional)

Filter: if doc_type is passport and file_2 is empty → stop and Slack ops. Passport will reject a single-page call.

Step 3: Paths by document type

Paths by Zapier — three paths (plus optional fallback):

PathRule
Passportdoc_type (Text) Exactly matches passport
PANdoc_type Exactly matches pan
Aadhaardoc_type Exactly matches aadhaar
FallbackAlways (last)

Step 4: Cryvis Passport path

Webhooks by Zapier → Custom Request

SettingValue
URLhttps://api.cryvis.com/v1/documents/passport
MethodPOST
Payload TypeForm / multipart
HeaderAuthorization: Bearer YOUR_API_KEY
FieldValue
first_pagefile_1 (biodata) — required
last_pagefile_2 (final page) — required

Map from data: passport_number, full_name, date_of_birth, nationality, expiry_date, and mrz.check_digits_valid. Set kyc_status to extracted_ok when MRZ check digits pass, else review_mrz — never silent-pass a failed MRZ.

Docs: /docs/api/extractPassport · /apis/passport.

Step 5: Cryvis PAN path

SettingValue
URLhttps://api.cryvis.com/v1/documents/pan
Multipartfile = file_1 (required)

Map:

kyc_doc_type    = pan
kyc_id_number   = data.pan_number
kyc_full_name   = data.full_name
kyc_dob         = data.date_of_birth
kyc_father      = data.father_name
holder_type     = data.holder_type
kyc_status      = empty(pan_number) ? review_missing_pan : extracted_ok

Docs: /docs/api/extractPan · /apis/pan. Tutorial: Extract PAN card data.

Step 6: Cryvis Aadhaar path (PII-aware)

SettingValue
URLhttps://api.cryvis.com/v1/documents/aadhaar
Multipartone or two parts both named file

Omit the second file part when only one image was uploaded.

Response data includes aadhaar_number, full_name, date_of_birth / year_of_birth, gender, care_of, address, pincode, is_masked.

PII: Prefer storing a masked display when is_masked is true. Restrict HubSpot property visibility. Avoid logging full UID in Zap history beyond what compliance allows.

kyc_doc_type     = aadhaar
kyc_id_number    = data.aadhaar_number
kyc_full_name    = data.full_name
kyc_dob          = date_of_birth or year_of_birth
kyc_address      = data.address
kyc_pincode      = data.pincode
is_masked        = data.is_masked
kyc_status       = is_masked ? extracted_masked : extracted_ok

Docs: /docs/api/extractAadhaar · /apis/aadhaar.

Step 7: Converge into HubSpot

Each path ends with the same HubSpot shape.

HubSpot → Create or Update Contact (match on email):

HubSpot propertySource
Emailemail
First / Last namesplit kyc_full_name or form name
Custom: kyc_document_typekyc_doc_type
Custom: kyc_id_numberkyc_id_number
Custom: kyc_date_of_birthkyc_dob
Custom: kyc_statuskyc_status
Custom: kyc_extracted_atnow

Create those custom properties before go-live. Passport: also kyc_nationality, kyc_expiry. PAN: holder_type. Aadhaar: kyc_pincode, aadhaar_is_masked. Status vocabulary: extracted_ok, extracted_masked, review_mrz, review_missing_pan, needs_unmasked_resubmit, error.

Step 8: Errors and checklist

After each Custom Request, Filter on success = true. On failure: set kyc_status=error, HubSpot update (status only), Slack with status code + email (not the file).

StatusCause
400Wrong multipart names (passport must be first_page/last_page)
401Bad Bearer token
415Bad MIME — PDF, JPEG, PNG, WebP only

Credits: 1 per PDF page or image (Credits). Confirm: passport always two pages; PAN one file; Aadhaar 1–2× file with HubSpot respecting is_masked; every path upserts by email; failures never silent-drop.

CTA

Ship the multi-doc KYC Paths with Cryvis: Passport, PAN, and Aadhaar. Paste a Bearer token into Custom Request, branch on doc type, and map data.* into HubSpot.