Aadhaar OVSE (Offline Verification)
7 operations.
What is it?
Aadhaar OVSE (Offline Verification Seeking Entity) enables privacy-first identity verification using UIDAI's official Aadhaar App. Your end-users authenticate via face scan in the Aadhaar App and consent to share verified identity details. No Aadhaar number is ever collected or stored. SignCare holds the UIDAI OVSE license, so you don't need your own registration.
Quick Start (3 Steps)
Step 1: Create verification request
POST /api/v1/aadhaar-ovse/init
Pass the claims you need as a simple array of names and the channel:
{
"claims": ["name", "dob", "gender", "photo", "address", "pincode", "masked_mobile"],
"channel": "web",
"language": "english",
"face_auth": true,
"webhook_url": "https://yourapp.com/webhook"
}
Response: txnId, intentJwt, requestUrl (for web channel), expiresAt
Step 2: Redirect your user
- Web-to-App (
channel: "web"): Redirect user's browser to the returnedrequestUrl. Aadhaar App opens on their phone. - Cross-Device QR (
channel: "qr"): CallPOST /qr-intentwith thetxnId, then render the returnedqrPayloadas a QR code. - App-to-App (
channel: "app"): Use theintentJwtto launch Aadhaar App via Android Intent or iOS URL scheme.
User authenticates via face scan and consents to share their details.
Step 3: Receive verified claims
- Webhook (recommended): We POST verified claims to your
webhookUrlautomatically. - Polling (fallback):
GET /api/v1/aadhaar-ovse/result/{txnId}— returnspending: trueuntil done.
Available Claims
Pass any of these values in the claims array:
Identity: name, local_name, photo, dob, gender, age_above_18, age_above_50, age_above_60, age_above_75, nri_status, care_of, enrolment_number, enrolment_date, credential_date
Address: address, regional_address, building, locality, street, landmark, vtc, sub_district, district, state, pincode, po_name
Contact: mobile, masked_mobile, email, masked_email
Common combinations:
- Basic KYC:
["name", "dob", "photo", "address", "pincode"] - Full KYC:
["name", "dob", "gender", "photo", "address", "pincode", "masked_mobile"] - Age verification only:
["age_above_18"] - Address verification:
["name", "address", "state", "district", "pincode"]
Languages
Pass language name or code: english (default), hindi, marathi, gujarati, tamil, telugu, bengali, kannada, malayalam, punjabi, urdu, assamese, oriya, nepali, or code 1-23
Webhook Payload
POSTed to your webhookUrl as JSON:
{
"success": true,
"data": {
"txnId": "94f63917-...",
"verificationPassed": true,
"verifiedClaims": {
"residentName": "RAM KUMAR",
"dob": "1990-01-15",
"gender": "M",
"address": "123, MG Road, Pune",
"pincode": "411001"
},
"verifiedAt": "2026-04-13T10:18:30Z"
}
}
Choosing the Right Channel
The channel you pass to /init should match how your end-users encounter your product, not how your backend works.
web — your user is on a mobile browser
Best when your product is a mobile web app (fintech KYC form, loan application, signup flow, embedded iframe).
- You call
/initwithchannel: "web". - We return
requestUrl— open it in the user's mobile browser (redirect, popup, or new tab). - Our verify page detects the platform and fires the right deep link:
intent://...on Android,pehchaan://...on iOS. - Aadhaar Pehchaan opens, user does face auth, you get a webhook.
Don't use this for desktop browsers — desktop users have no Pehchaan app to launch. Use qr instead.
qr — your user is at a counter, kiosk, or desktop
Best for physical venues, branches, hotel reception, retail counter, conference desks, or any desktop-screen flow.
- You call
/initwithchannel: "qr". - We return
requestUrl— render it as a QR code on your screen using any QR library. - The QR follows UIDAI's spec format (
https://maadhaar.com/getIntent?value=...) so it works two ways:- End-user opens their phone camera → scans → Pehchaan opens automatically.
- End-user opens Aadhaar Pehchaan → taps "Scan QR" inside the app → reads the same QR.
- Either path lands on the same
txnIdand you get a webhook.
Multi-guest variant: if you need one persistent QR for many guests (hotel weekend sign, conference welcome banner), use Event QR Mode — /events instead of /init. One QR, unlimited fresh transactions.
app — your user is inside your native mobile app
Best when you have your own Android or iOS app that needs to verify the user mid-flow (banking onboarding, wallet KYC, driver verification).
- You call
/initwithchannel: "app", plus yourapp_id(Android package id) andapp_signature(Base64 SHA-256 of your signing cert). - Android: we return
aadhaarAppUri— anintent:URI your Android code fires viastartActivity(). - iOS: use the
intentJwtfrom the response and open the URL scheme yourself:UIApplication.shared.open(URL(string: "pehchaan://in.gov.uidai.pehchaan?req=\(intentJwt)")!) - Pehchaan opens directly inside your app, returns the user when verification finishes.
Channel cheat sheet
| Your product | Channel | What you render | End user does |
|---|---|---|---|
| Mobile web app | web | nothing — just redirect | Phone browser → Pehchaan opens automatically |
| Branch / kiosk / desktop site | qr | a QR image | Phone camera or Pehchaan in-app scan |
| Hotel / event with many guests | Event QR | one persistent QR | Each guest scans the same QR |
| Native Android app | app | nothing — fire intent | Pehchaan opens inside your app |
| Native iOS app | app | nothing — open URL scheme | Pehchaan opens inside your app |
Trial Center vs Production
The "Running Trial on Aadhaar OVSE" screen inside the SignCare portal is a developer sandbox. It exists to help you:
- Pick claims and a channel, then see exactly what
/initreturns. - Test your webhook URL end-to-end with a real verification.
- Inspect the
verifiedClaimsJSON shape so you know what fields to map. - Try Event QR mode with a live registrations dashboard before printing anything.
The trial center is not for your end users. Your real users never see the SignCare portal. In production, your own backend calls this External API directly with your X-API-KEY and X-API-APP-ID headers, and you render the verify URL or QR inside your product. The trial center just lets you verify the wiring before writing integration code.
Trial center transactions debit credits exactly like production — keep that in mind while testing.
Event QR Mode — One QR for Many Guests
Use Event QR when you need to verify many people at a venue without knowing who's coming. You print one QR code — each guest scans it and gets their own fresh Aadhaar verification.
Best for: hotel check-in, conference registration, branch walk-in, exhibitions, field operations.
Event QR Quick Start (3 steps)
Step 1: Create an event
POST /api/v1/aadhaar-ovse/events
{
"name": "Hotel ABC Conference — March 5",
"claims": ["name", "dob", "photo", "masked_mobile"],
"language": "english",
"max_guests": 200,
"expires_at": "2026-03-06T23:59:59Z",
"webhook_url": "https://yourapp.com/webhooks/event-guests"
}
Response: event_id, qr_url (print this as a QR code)
Step 2: Print the QR and display at venue. Guests scan with phone camera → Aadhaar App opens automatically → face auth → consent.
Step 3: Receive a webhook per verified guest. Same payload shape as single verification.
Optionally poll GET /events/{eventId}/registrations for a live guest list.
Event management endpoints
GET /events/{eventId}— check status, registration count, capacityGET /events/{eventId}/registrations?page=1&page_size=50— live guest list with verified claimsPATCH /events/{eventId}— disable, raise cap, or extend expiry mid-event
Event QR — Key points
- 1 credit per verified guest — same rate as single
/init - Abandoned scans (guest walks away before face auth) consume 1 credit but don't count toward
max_guests max_guestscaps successful verifications only, not total scans- When credits run out, the QR gracefully shows "event unavailable" — no hard failure
- Disable an event instantly:
PATCH /events/{id}with{ "is_active": false }
Error Codes
- 400 — Unknown claims / invalid channel: check the claims list above
- 401 — Unauthorized: check X-API-KEY and X-API-APP-ID headers
- 402 — Insufficient credits: purchase more via SignCare portal
- 404 — Transaction or event not found
- 409 — Event at capacity (max_guests reached)
- 410 — Transaction expired (15 min window) or event expired
Benefits
- No OVSE license needed — use SignCare's
- No Aadhaar number collected — privacy by design
- UIDAI digitally signed data (SD-JWT) — tamper-proof
- Face biometric authentication — prevents impersonation
- 3 API calls to verify an identity — simple integration
- Event QR mode — one QR for unlimited guests — hospitality, conference, branch walk-in