Open a wallet or account in one WebView
The flagship pattern: open a session, upload NID + selfie, get a verified envelope. Most users clear in <8 seconds.
// 1. Open a verification session
Explore the request patterns below. Contact Adept Sense for API credentials, SDK packages, and the current integration specification for your account.
The SenseAI API provides identity verification services including ID card OCR, face match, liveness verification, transliteration, and gender estimation. Requests use JSON or multipart form data, depending on the endpoint. Responses use JSON.
https://api.adeptsense.tech/api/v1
https://api-sandbox.adeptsense.tech/api/v1
application/json
JPEG · PNG · WebP
All protected API requests require your custom API key passed in the x-api-key HTTP header:
x-api-key: YOUR_API_KEY
Contact Adept Sense for API access. Keep your keys secure — do not commit them to version control or expose them client-side.
Get from zero to your first successful API call in under 5 minutes.
Request API credentials from Adept Sense.
Use Node, Python, or standard cURL client to upload images to the API endpoint.
import fs from 'node:fs/promises'
import FormData from 'form-data'
const form = new FormData()
form.append('front', await fs.readFile('./front.jpg'), 'front.jpg')
form.append('back', await fs.readFile('./back.jpg'), 'back.jpg')
const res = await fetch('https://api.adeptsense.tech/api/v1/ocr/nid', {
method: 'POST',
headers: {
'x-api-key': process.env.ADEPT_KEY
},
body: form
})
const result = await res.json()
console.log(result.ok) // true
Use the sandbox base URL for all testing and development:
https://api-sandbox.adeptsense.tech/v1
Sandbox responses return realistic mock data with the same schema as production. Switch to the live URL when you're ready to go live.
Pick the vertical you're building for — the right endpoints, sample payloads, and order of operations for each integration pattern.
The flagship pattern: open a session, upload NID + selfie, get a verified envelope. Most users clear in <8 seconds.
// 1. Open a verification session
Bulk-friendly: invite candidates by email, collect NID + selfie, receive a per-row webhook with their verification status.
// 2. Upload candidate's NID
Send a pre-visit link via SMS or email. The patient verifies from their phone; you get a confirmed-identity flag in your EMR.
// 3. Confirm face matches the NID
Two-stage on the same WebView — buyers see an age-gate at checkout, sellers see a full KYC step that unlocks their first payout.
// Age-gate a buyer at checkout
Drivers verify once at signup, then re-verify on a rolling schedule. Passengers see a verified badge in the app.
// Re-verify a driver (12-month cadence)
Most users clear the signup age-gate in seconds. Full KYC kicks in only when they try to withdraw — same API, two stages.
// Stage 1 — age-gate at signup
SenseAI NID OCR supports Bangla and English cards, front/back extraction, PDF417 and TD1 MRZ reading, parent-name transliteration, father/spouse identification, configurable normalization, and cached results. Recognition can be trained for recurring errors in worn or photocopied cards. Explore the OCR workflow.
Extract structured identity fields from any government-issued ID card image — Bangladesh NID, passport, driver's license, voter ID, and more. The endpoint is named /ocr/nid for historical reasons but accepts any ID card format.
frontstring / fileYesFront of NID (binary file or base64 data URL)backstring / fileYesBack of NID (binary file or base64 data URL){
"ok": true,
"txId": "TX_1773843146096_646FF71CAA17",
"username": "alice",
"tokensRemaining": 99601,
"tokensUsed": 2,
"data": {
"fields": {
"name_bn": "রাজা আহমেদ",
"name_en": "RAZA AHMED",
"nid_number": "2025001221",
"dob_en": "01 Sep 1980",
"address_bn": "বাসা/হোল্ডিং: ১৩, গ্রাম/রাস্তা: আবাসিক কলোনী...",
"father_or_husband_bn": "মোহাম্মদ আলী",
"father_or_husband_en": "Mohammad Ali"
},
"normalized": {
"dob_iso": "1981-01-01"
}
}
}
Face Match evaluates facial structure and overall appearance. Reference-image recovery runs before comparison to address low-resolution, compressed government images. Appearance changes can still require review. Explore the matching workflow.
Submit a face matching task to compare reference and selfie images asynchronously.
referenceImagestring / fileYesReference or ID card portraitselfieImagestring / fileYesLive user selfie imagecallbackUrlstringNoPOST webhook URL for final results callback{
"ok": true,
"data": {
"taskId": "5190bb5e-0839-49ad-9027-c66d03e64d6f",
"status": "queued"
}
}
Poll this endpoint with taskId to fetch the async face comparison results.
The SDK performs configured tasks and on-device capture checks, then sends a five-second video and its findings for a server verdict. Tasks, workflow and decision policies are controlled from the backend; tagged review examples support training. Explore the two-part liveness workflow.
Create a one-time liveness session.
userIdstringYesUnique reference for the userplatformstringNoClient platform: "web", "mobile", etc.callbackUrlstringNoURL to post results once session completes{
"ok": true,
"data": {
"sessionId": "7995664a-b950-4aed-b4d1-76dc12c779c2",
"url": "https://api.adeptsense.tech/liveness?token=eyJzaWQiOiI3..."
}
}
Fetch the stored session results using sessionId query parameter.
Convert a Bangla name to its English transliteration or vice versa for cross-system database matching.
inputLangstringYesOriginal script: "en" or "bn"outputLangstringYesTarget script: "en" or "bn"namesarrayYesArray of string names to translatePredict gender and confidence levels from a given name in a specified language.
inputLangstringYesLanguage script: "bn" or "en"namesarrayYesArray of string names to analyzeFace matching and liveness are separate signals. Retrieve the completed result for each task and apply your configured review policy. A face match alone does not establish liveness.
Agree on thresholds and handling for uncertain or incomplete results with your team. Do not use a single example score as a universal acceptance rule.
error_code field in responses — if present, use it for granular error handling.
ERR_IMAGE_BLURRY422OCR couldn't read textAsk user to retake photoERR_LOW_LIGHT422Liveness failed — poor lightingImprove lighting guidanceERR_INVALID_DOCUMENT422Not a Bangladesh NIDValidate doc type client-sideERR_LOW_MATCH200Face match below thresholdPrompt better selfieERR_LIVENESS_FAIL200Liveness didn't passRe-attempt with anti-spoof guidanceERR_FILE_TOO_LARGE413Exceeds size limitCompress before uploadERR_UNAUTHORIZED403API key invalid/expiredRecheck API keyERR_QUOTA_EXCEEDED403Monthly limit reachedUpgrade planFor asynchronous liveness results, SenseAI can POST a callback to your server when the result is ready.
{
"event": "verification.completed",
"session_id": "ses_a1b2c3",
"result": {
"verified": true,
"liveness_score": 0.97
},
"timestamp": "2025-01-15T10:30:00Z",
"signature": "sha256=abc123..."
}
Verify the signature header using your webhook secret. Retries use exponential backoff (1s, 5s, 30s, 5m).
If you're using our hosted verification UI (/liveness?token=...) inside mobile or web applications, you can receive completion events natively via WebView and JavaScript bridges.
Listen for liveness completion event payload using standard browser message handler:
const livenessUrl = "https://api.adeptsense.tech/liveness?token=YOUR_TOKEN";
document.getElementById("lvFrame").src = livenessUrl;
window.addEventListener("message", async (event) => {
if (event.origin !== "https://api.adeptsense.tech") return;
const msg = event.data || {};
if (msg.type !== "liveness.result") return;
const sessionId = msg.sessionId;
// Fetch result securely from your backend -> /api/v1/liveness/result?sessionId=...
console.log("Session complete:", sessionId);
});
Register Javascript handler name livenessResult in the controller:
final String livenessUrl = "https://api.adeptsense.tech/liveness?token=YOUR_TOKEN";
InAppWebView(
initialUrlRequest: URLRequest(url: WebUri(livenessUrl)),
onWebViewCreated: (controller) {
controller.addJavaScriptHandler(
handlerName: "livenessResult",
callback: (args) async {
final payload = args.isNotEmpty ? args[0] : null;
final sessionId = payload?["sessionId"];
// Call your backend proxy -> /api/v1/liveness/result?sessionId=...
},
);
},
);
Observe the userContentController with script handler name livenessResult:
import WebKit
config.userContentController.add(self, name: "livenessResult")
webView.load(URLRequest(url: URL(string: "https://api.adeptsense.tech/liveness?token=YOUR_TOKEN")!))
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard message.name == "livenessResult" else { return }
if let payload = message.body as? [String: Any],
let sessionId = payload["sessionId"] as? String {
// Call your backend to verify -> /api/v1/liveness/result?sessionId=...
}
}
Create a JavaScript interface class bound as AndroidLiveness:
class LivenessBridge {
@android.webkit.JavascriptInterface
fun postMessage(payloadJson: String) {
// Parse JSON -> extract sessionId -> retrieve results via backend
}
}
webView.settings.javaScriptEnabled = true
webView.addJavascriptInterface(LivenessBridge(), "AndroidLiveness")
webView.loadUrl("https://api.adeptsense.tech/liveness?token=YOUR_TOKEN")
Bring guided liveness capture into your application. Contact Adept Sense for current packages, supported versions, and platform-specific setup instructions.
Request the current API specification and available Postman resources for your account.
Request integration resources →Confirm request limits, supported file formats, image dimensions, and timeouts for your account before going live. Use bounded retries for transient failures and handle unsuccessful responses in your integration.
Discuss your integration requirements →