Skip to content

KYCVerify: Identity verification API

Verify identities with evidence you can read.

Documents, selfie liveness, face match, Aadhaar, PAN and sanctions screening behind one API. People verify in a hosted flow; you get a decision with every check and its evidence, signed and delivered to your backend. Uploads are encrypted at rest and purged on your retention schedule.

  1. POST /v1/sessions
  2. /verify/{token}
  3. session.status_updated

Sandbox app, test keys and a default workflow on sign-up.

ICAO 9303MRZ, every check digit recomputed
UIDAIsignatures verified on Aadhaar QR and XML
AES-256-GCMuploads encrypted at rest
HMAC-SHA256signed webhooks, 8 attempts
OFAC · UNsanctions lists, fuzzy matched
10check kinds a decision can carry
90 daysdefault retention, then purged

A session, start to finish

What the person sees. What your team sees.

The hosted flow on the left is the page your users open. The console on the right fills in as each step finishes, and the decision reaches your backend as a signed event. The screens, strings and statuses below are the product's own.

Hosted flow/verify/q3Xf…

Your appStep 1 of 4

Before you start

Your app uses KYCVerify to confirm your identity. Here is what happens with your information.

What we collect

  • Photos of your identity document and the details printed on it
  • A short sequence of selfie photos to confirm you are present
  • Technical details of this device and connection (IP address, browser) to help prevent fraud
I agree that Your app may process my information as described above to verify my identity.Agree and continue

Secured by KYCVerify

Console · Sessions

ses_01JD7Q8YB6N2Z3K4M5P6R7S8T9

In progress

full_name

—

date_of_birth

—

document_type

—

document_number_masked

—

nationality

—

expiry_date

—

Checks0 of 6

  • documentwaiting for the step
  • livenesswaiting for the step
  • face_matchruns on submit
  • amlruns on submit
  • duplicateruns on submit
  • ipruns on submit

Timeline

  1. session createdPOST /v1/sessions
  2. consent recordedtime, ip, user agent
  3. document check writtenpassed · 0.97
  4. liveness check writtenpassed · 3 challenges
  5. submittedbackground checks run
  6. webhook delivered200 · attempt 1

Webhook session.status_updated is sent on every status change.

A mock of one verification session. The person consents, photographs a passport, completes three selfie challenges and submits; the console records each check, the session is approved and a signed session.status_updated webhook is delivered.

How it works

One call to start. One signed event to finish.

There is no SDK to embed and no verification UI to build. Your backend creates a session, the person follows a link, and the decision comes back to you.

  1. 01POST /v1/sessions

    Create a session

    Your backend asks for a verification with your own reference and an optional workflow. KYCVerify returns a one-time link and a session id. Test and live keys are separate, so the sandbox never touches production data.

    • x-api-key header, test or live
    • vendor_data ties it to your user
    • Link expires after 7 days by default
  2. 02/verify/{token}

    The person verifies

    Consent, an optional email code, the document or Aadhaar, PAN, then the selfie challenges, on any phone or laptop browser. A desktop visitor can hand off to their phone with a QR code. Nothing to install.

    • Steps chosen by the workflow
    • Quality gate before every read
    • 3 attempts per step by default
  3. 03session.status_updated

    You get a signed decision

    Background checks run on submit: face match, sanctions, age, duplicates, IP. The decision rule is applied and the result is posted to your webhook, signed with HMAC-SHA256 and retried until your server says 2xx.

    • Approved, declined or in review
    • Every check with its evidence
    • 8 attempts with backoff

What it verifies

Ten check kinds. One decision with its evidence.

Each check returns a status, a score where one exists, and the warnings behind it, so anyone reviewing a decision can see exactly why it was reached.

Built for India

Aadhaar and PAN, verified the way they were designed to be.

UIDAI signs Aadhaar's offline formats. KYCVerify checks that signature with UIDAI's own public certificate instead of trusting a photo of a card, validates PAN's structure, and from the signed formats keeps only the last four Aadhaar digits.

KYCVerify verifies UIDAI-signed offline artefacts; it is not Aadhaar authentication. Offline verification requires OVSE registration with UIDAI, which software cannot confer. Regulatory notes

For developers

Three calls. One signature to check.

Plain HTTPS and JSON, a documented error envelope, and webhooks you can verify in ten lines. Nothing to install on the client.

Signature scheme

v1=hex(HMAC-SHA256(secret, "{timestamp}.{raw_body}"))

x-kyc-event
session.status_updated
x-kyc-delivery
whd_0k3v9z7c2b…
x-kyc-timestamp
1767225600
x-kyc-signature
v1=5f2c…

Retries until 2xx

8 attempts

  1. now
  2. +30 s
  3. +2 min
  4. +10 min
  5. +30 min
  6. +1 h
  7. +3 h
  8. +6 h

The queue lives in the database, so a restart never loses a delivery. Any delivery can be resent from the console.

POST /v1/sessions

curl -X POST https://kycverify.me/api/v1/sessions \
  -H "x-api-key: $KYC_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "vendor_data": "user-42",
    "contact": { "email": "anna@example.com" }
  }'

Response

201 Created
{
  "session_id": "ses_0k3v9x2m4a7qhd8f1rtb",
  "status": "not_started",
  "url": "https://kycverify.me/verify/q3Xf…",
  "session_token": "q3Xf…",
  "workflow_id": "wf_0k3t1c8n5e2wpzr6g4ya",
  "vendor_data": "user-42",
  "expires_at": "2026-10-10T09:12:44Z"
}

Security

Identity data, encrypted and kept only as long as you say.

Every check runs on KYCVerify's own engine: no third-party verification API and no external model API sees your users' documents or faces. Uploads are encrypted at rest, each organisation's data is isolated, and a retention worker purges evidence on schedule.

The personany phone or laptop browser
hosted flow

KYCVerify

kycverify.me

  • Rust APIaxum · SQLite
  • Vision modelson CPU, in-process
  • Sanctions indexOFAC SDN · UN
  • Encrypted storageAES-256-GCM

No third-party verification or model API.

signed webhook
Your backendverifies, then trusts
The person opens the hosted flow in a browser. The KYCVerify API, vision models, sanctions index and encrypted storage all run inside the KYCVerify service, which then sends a signed webhook to your backend. Nothing is sent to a third-party verification or model API.
every upload, encrypted at rest
AES-256-GCM
console passwords
Argon2id
API keys and tokens stored hashed
SHA-256
owner, admin, reviewer, viewer
4 roles

Compared honestly

Other vendors do more. Here is what we can show.

Mature KYC products have features KYCVerify does not. We compare only what is published and checkable: webhook signing, check types, Aadhaar offline verification and the decision data you get back.

What other vendors offer that KYCVerify does not

  • NFC chip reading of e-passports and eIDs
  • Passive liveness, and PAD certification from an accredited lab
  • PEP lists, adverse media and ongoing AML monitoring
  • Government and bureau database lookups in many countries
  • Business verification (KYB)
  • KYCVerify

    Webhook signing
    HMAC-SHA256 over the timestamp and the raw body (x-kyc-signature), 5-minute replay window
    Webhook retries
    8 attempts with backoff from 30 s to 6 h, persisted; redeliver from the console
    Aadhaar offline signature verification
    Yes: Secure QR and Offline e-KYC XML, UIDAI signatures verified
    Default retention
    90 days per app (1 to 3,650), then purged
  • Didit

    Webhook signing
    HMAC-SHA256: X-Signature-V2 over canonical JSON, or X-Signature over the raw body; 300 s window
    Webhook retries
    Retried twice (about 1 min, then 4 min later) on 5xx, 404 or timeout, then dropped; replay from the console
    Aadhaar offline signature verification
    Not live (per its docs)
    Default retention
    Indefinite unless configured (30 days to 10 years)

Public sources as of 3 October 2026, linked on the comparison page.

Public sources as of 3 October 2026, linked on the comparison page.
TopicKYCVerifyDidit
Webhook signingHMAC-SHA256 over the timestamp and the raw body (x-kyc-signature), 5-minute replay windowHMAC-SHA256: X-Signature-V2 over canonical JSON, or X-Signature over the raw body; 300 s window
Webhook retries8 attempts with backoff from 30 s to 6 h, persisted; redeliver from the consoleRetried twice (about 1 min, then 4 min later) on 5xx, 404 or timeout, then dropped; replay from the console
Aadhaar offline signature verificationYes: Secure QR and Offline e-KYC XML, UIDAI signatures verifiedNot live (per its docs)
Default retention90 days per app (1 to 3,650), then purgedIndefinite unless configured (30 days to 10 years)

FAQ

Questions, answered plainly.

Something else? Ask us.

Is KYCVerify a hosted service?

Yes. KYCVerify runs at kycverify.me: your backend calls https://kycverify.me/api, people verify at kycverify.me/verify/{token}, and your team uses the console there. Every check runs on KYCVerify's own engine, uploads are encrypted at rest with AES-256-GCM, and each app's evidence is purged after its retention period.

What can it verify?

Passports, ID cards and residence permits through the ICAO 9303 MRZ; Aadhaar, PAN, voter ID and Indian driving licences by OCR; Aadhaar Secure QR and Offline e-KYC against UIDAI signatures; active liveness; face match; sanctions screening against OFAC SDN and UN lists; minimum age; duplicates; email ownership.

What does it not do?

No NFC chip reading, no certified passive liveness, no PEP or adverse-media screening, no KYB, no phone OTP, no government database lookups and no native SDKs. We would rather you know now. The comparison lists it all.

Is the liveness check certified?

No. It is active challenge-response (turn left, turn right, smile, move closer) analysed frame by frame on KYCVerify's engine, and it is labelled as such. It has not been tested by a presentation-attack-detection lab.

How does my backend get the result?

A session.status_updated webhook signed with HMAC-SHA256 for every status change, carrying the full decision when the session is final. You can also call GET /v1/sessions/{id}/decision at any time.

Do people need to install an app?

No. The hosted flow runs in the browser on any modern phone or laptop and uses the device camera.

How long is data kept?

Each app has a retention period, 90 days by default. A worker purges the files, face embeddings and identity data of older sessions automatically, and you can purge any session on demand with DELETE /v1/sessions/{id}.

Does it handle Aadhaar numbers?

The offline formats (Secure QR and Offline e-KYC XML) contain only the last four digits, so that is all they give you. If a workflow also accepts a photographed Aadhaar card, the number is read to validate it and kept only masked and as a keyed fingerprint; the card image, which shows the full number, stays encrypted until the retention purge.

Start in the sandbox today.

An organisation, a sandbox app, test keys and a default workflow are created when you sign up.

curl -X POST …/v1/sessions -H "x-api-key: …"

201 Created · status not_started

url → /verify/q3Xf…