API
Checks
The ten check kinds, their statuses, warning codes and decision reasons.
A decision is built from checks. Each has { id, kind, status, score, data, warnings, created_at }. score is between 0 and 1 where one exists, otherwise null. Each warning is { code, message, severity } with severity info, warn or high.
| Kind | Runs | What it decides |
|---|---|---|
document | document step | MRZ check digits, expiry, type and country against the workflow, image quality, face on the document |
liveness | liveness step | Challenge order, movement, same face throughout, one face, timing |
aadhaar | Aadhaar step | UIDAI signature, XML age, email hash when known |
pan | PAN step | Format, holder type, name initial, card cross-check |
email | email step | One-time code verified |
face_match | submit | Selfie against the document portrait, else the Aadhaar photo |
aml | submit | OFAC SDN and UN consolidated screening of the extracted name |
age | submit | Minimum age from the date of birth |
duplicate | submit | Document fingerprint or face seen in another session of the app |
ip | submit | Records the client IP and user agent |
Statuses
passed, failed, review, skipped or error. A check that errors never blocks the pipeline: it becomes error, which sends the session to review with a reason like face_match_error.
The decision rule
1. Any enabled check failed?
in_review when decision.auto_decline is false
declined
2. Any check review or error?
a person decides in the review queue
in_review
3. Otherwise
every check passed or was skipped
approved
Scored checks
Face match
- Below 0.30: failed, warning face_mismatch
- 0.30 to 0.363: review, warning weak_face_match
- 0.363 and above: passed (SFace's published threshold)
AML
- Below 0.82: not reported
- 0.82 to 0.90: potential_match (warn), session to review
- 0.90 and above: potential_match (high), session to review
Name score
token-set Jaro-Winkler, order-insensitive, diacritics and honorifics removed
Date of birth
match +0.05, mismatch −0.10, unknown leaves the score as is
Review, not decline
a hit sends the AML check to review; a session still declines if another check fails with auto_decline on
Decision reasons
| decision_reason | Typical cause |
|---|---|
document_expired | Expiry date in the past with reject_expired on |
document_type_mismatch · document_country_mismatch | The document does not match what the workflow allows or what was declared |
document_mrz_invalid | MRZ check digits do not verify |
liveness_failed | Challenges not met within the attempts allowed |
face_match_failed · face_match_weak | Similarity below the review threshold · between the thresholds |
aadhaar_signature_invalid | The UIDAI signature did not verify |
aml_potential_match · aml_lists_not_loaded | A sanctions entry scored above the review threshold · nothing was screened |
age_below_minimum · age_uncertain · age_unknown | Under min_age · only a birth year · no date of birth |
duplicate_found | The same document or face in another approved, in-review, processing or declined session of the app |
{step}_not_completed | A required step was not completed before submit |
manual_review_declined | Declined by a person or with PATCH /status |
Warning codes
| Code | Check | Meaning |
|---|---|---|
mrz_check_digits_failed | document | One or more MRZ check digits do not verify |
mrz_unreadable | document | No MRZ could be read from the image |
document_expired | document | The expiry date is in the past |
ocr_corrections | document | Characters were corrected in typed MRZ positions |
country_not_allowed | document | The issuing country is not in allowed_countries |
document_specimen | document | An ICAO specimen document: review on live apps, info only in sandbox |
portrait_not_found | document | No face found on the document (reason document_portrait_not_found) |
no_selfie_face · no_reference_face | face_match | No face in the selfie · no portrait or Aadhaar photo to compare against |
weak_face_match · face_mismatch | face_match | Between the thresholds · below the review threshold |
signature_invalid | aadhaar | The UIDAI signature did not verify |
xml_too_old | aadhaar | Offline XML older than max_xml_age_days |
pan_invalid_format · pan_name_initial_mismatch | pan | Structure wrong · fifth character does not match the name |
pan_card_number_mismatch | pan | The PAN read from the card differs from the one entered |
potential_match · lists_not_loaded | aml | A sanctions entry scored above the review threshold · a list is not loaded |
underage · age_uncertain · dob_missing | age | Below min_age · only a year known · no date of birth |
duplicate_found | duplicate | The document or face matches other sessions |
email_not_verified | The code was never confirmed |
Standalone check endpoints
AML, PAN, MRZ, face match and Aadhaar Secure QR are also available without a session. See the API reference.