KYC · API reference
Document
Document Read
/v1/idv/readdocuments.readThe full read of an ID document. Returns every container the reader produced, type, printed and MRZ fields, portrait, security and image-quality checks, under data.ContainerList. An optional hint says whether the document matches what you expected.
**Returns**
- data.ContainerList.List[]: the containers; read each by its own result_type, order is not fixed
- doc_hint: the match against your expected country and type (when you set a hint)
**Limits**
- Front required; back optional. ~1,400 document types. - Personal values are not masked here; gate who may call it. Use Document Fields for a masked view.
Price: 0.35 credits per successful call.
Body parameters
image_frontstringrequiredDocument front. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.
image_backstringDocument back. The reverse side, when it carries data. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.
scenariostringScenario.
FullProcessFullAuthBarcodeMrzdoc_hintobjectShow 2 fieldsHide fields
countrystringExpected country. ISO code, for example RW or RWA.
typestringExpected type.
passportnational_iddriving_licenceresidence_permit
Returns
The check ran.
Show the DocumentReadResponse fieldsHide fields
okbooleanrequiredtrue: the result is in
data.request_idstringlatency_msnumberHow long the check took, in milliseconds.
dataobjectrequiredThe full result of Document Read: everything the check found. See the fields listed in the operation.
warningsarray of stringserroranyEmpty on success.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v1/idv/read \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image_front": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==",
"scenario": "FullProcess"
}'{
"ok": true,
"request_id": "req_ab957d053778450995a3",
"latency_ms": 1215,
"data": {
"ok": true,
"data": {
"ContainerList": {
"Count": 14,
"List": [
{
"OneCandidate": {
"AuthenticityNecessaryLights": 3224,
"CheckAuthenticity": 6817327,
"DocumentName": "Czech Republic - ePassport (2006)",
"FDSIDList": {
"Count": 3,
"ICAOCode": "CZE",
"List": [
3244,
11569,
18726
],
"dCountryName": "Czech Republic",
"dDescription": "Passport",
"dFormat": 2,
"dMRZ": true,
"dType": 11,
"dYear": "2006",
"isDeprecated": false
},
"ID": 824952191,
"NecessaryLights": 25165824,
"OVIExp": 5,
"P": 0.723872721195221,
"RFID_Presence": 1,
"Rotated180": 0,
"RotationAngle": 0,
"UVExp": 6
},
"buf_length": 8,
"light": 0,
"list_idx": 0,
"page_idx": 0,
"result_type": 9
},
{
"ImageQualityCheckList": {
"Count": 6,
"List": [
{
"featureType": 0,
"mean": -4.747840881347656,
"probability": 99,
"result": 1,
"std_dev": 4.747161865234375,
"type": 1
},
{
"featureType": 0,
"mean": 0,
"probability": 0,
"result": 1,
"std_dev": 0,
"type": 0
},
{
"featureType": 0,
"mean": 0,
"probability": 0,
"result": 1,
"std_dev": 0,
"type": 7
},
{
"featureType": 0,
"mean": 0,
"probability": 0,
"result": 1,
"std_dev": 0,
"type": 5
},
{
"featureType": 0,
"mean": 0,
"probability": 0,
"result": 1,
"std_dev": 0,
"type": 4
},
{
"featureType": 0,
"mean": 0,
"probability": 0,
"result": 1,
"std_dev": 0,
"type": 2
}
],
"result": 1
},
"buf_length": 8,
"light": 0,
"list_idx": 0,
"page_idx": 0,
"result_type": 30
},
{
"Status": {
"detailsOptical": {
"docType": 1,
"expiry": 0,
"imageQA": 1,
"mrz": 0,
"overallStatus": 0,
"pagesCount": 1,
"security": 2,
"text": 0,
"vds": 2
},
"detailsRFID": {
"AA": 2,
"BAC": 2,
"CA": 2,
"PA": 2,
"PACE": 2,
"TA": 2,
"overallStatus": 2
},
"optical": 0,
"overallStatus": 0,
"portrait": 2,
"rfid": 2,
"stopList": 2
},
"buf_length": 84,
"light": 0,
"list_idx": 0,
"page_idx": 0,
"result_type": 33
}
]
},
"TransactionInfo": {
"DateTime": "2026-10-05T05:36:22.939Z",
"Tag": "37e5e108-691a-445e-a03d-9a32e49a52d5",
"TransactionID": "436d80f4-38de-42bd-86f3-056b84a1ad89"
},
"ProcessingFinished": 1
},
"doc_hint": {
"country": "CZ",
"type": "passport",
"detected": {
"country": "CZE",
"category": "Passport"
},
"country_matches": true,
"type_matches": true
}
},
"warnings": [],
"error": null
}Document Classify
/v1/idv/classifydocuments.classifyJust the identity of the document: its name, category, issuing country, year and a confidence.
**Returns**
- document_name: the full type name
- category: Passport, National ID, Driving Licence or Residence Permit
- country / country_name: the issuer, ISO alpha-3 and name
- state: the state or province that issued it (licences and IDs), or null
- size: ID-1 card, ID-2, ID-3 passport page or A4
- has_mrz / has_chip: whether this type carries an MRZ, and a chip
- deprecated: true when the issuer no longer issues this type
- confidence: 0 to 1
Price: 0.02 credits per successful call.
Body parameters
imagestringrequiredDocument. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.
Returns
The check ran.
Show the DocumentClassifyResponse fieldsHide fields
okbooleanrequiredtrue: the result is in
data.request_idstringlatency_msnumberHow long the check took, in milliseconds.
dataobjectrequiredThe answer of Document Classify.
Show 12 fieldsHide fields
document_namestringdoc_typestringcategorystringcountrystringcountry_namestringstateanyyearstringsizestringhas_mrzbooleanhas_chipbooleandeprecatedbooleanconfidencenumber
warningsarray of stringserroranyEmpty on success.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v1/idv/classify \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
}'{
"ok": true,
"request_id": "req_62b56d3e2b9b454e9724",
"latency_ms": 1506,
"data": {
"document_name": "Czech Republic - ePassport (2006)",
"doc_type": "PASSPORT",
"category": "Passport",
"country": "CZE",
"country_name": "Czech Republic",
"state": null,
"year": "2006",
"size": "ID-3",
"has_mrz": true,
"has_chip": true,
"deprecated": false,
"confidence": 0.723872721195221
},
"warnings": [],
"error": null
}Document MRZ
/v1/idv/mrzdocuments.mrzThe MRZ read from the document: the raw lines, the parsed fields, and every check digit recomputed under ICAO 9303 (the same rule for every country).
**Returns**
- lines[]: the raw MRZ lines
- format: TD1, TD2, TD3 or a visa
- valid: true when every check digit holds and dates are real
- expired: true when the expiry date has passed
- check_digits: each check digit with its recomputed digit and ok/fail
- print_quality: the MRZ print checks: check sums, contrast, format, position, stains, symbols
- parsed: the named fields
**Limits**
- Returns an empty result with a warning when the document has no MRZ.
Price: 0.06 credits per successful call.
Body parameters
imagestringrequiredDocument page with the MRZ. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.
Returns
The check ran.
Show the DocumentMrzResponse fieldsHide fields
okbooleanrequiredtrue: the result is in
data.request_idstringlatency_msnumberHow long the check took, in milliseconds.
dataobjectrequiredThe answer of Document MRZ.
Show 8 fieldsHide fields
linesarray of stringsformatstringvalidbooleanexpiredbooleanproblemsarray of objectsShow 2 fieldsHide fields
fieldstringissuestring
check_digitsobjectShow 5 fieldsHide fields
doc_numberobjectShow 2 fieldsHide fields
digitstringokboolean
birth_dateobjectShow 2 fieldsHide fields
digitstringokboolean
expiryobjectShow 2 fieldsHide fields
digitstringokboolean
personal_numberobjectShow 2 fieldsHide fields
digitstringokboolean
compositeobjectShow 2 fieldsHide fields
digitstringokboolean
print_qualityobjectShow 7 fieldsHide fields
check_sumsstringcontraststringdoc_formatstringmrz_formatstringprint_positionstringstainsstringsymbolsstring
parsedobjectShow 20 fieldsHide fields
Surname And Given NamesstringRemainderTermstringDate of BirthstringGiven NamesstringSurnamestringDate of ExpirystringDocument Class CodestringIssuing State NamestringFinal CheckdigitstringOptional Data CheckDigitstringOptional DatastringIssuing State CodestringDocument NumberstringDocument Number CheckdigitstringNationality CodestringDate of Birth CheckdigitstringSexstringDate of Expiry CheckdigitstringPersonal NumberstringMRZ Typestring
warningsarray of stringserroranyEmpty on success.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v1/idv/mrz \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
}'{
"ok": true,
"request_id": "req_594cea1a392d46ac8725",
"latency_ms": 1164,
"data": {
"lines": [
"P<CZESPECIMEN<<VZOR<<<<<<<<<<<<<<<<<<<<<<<<<",
"99006000<8CZE1102299F16090641152291111<<<<24"
],
"format": "TD3",
"valid": false,
"expired": true,
"problems": [
{
"field": "birth_date",
"issue": "not a real date"
}
],
"check_digits": {
"doc_number": {
"digit": "8",
"ok": true
},
"birth_date": {
"digit": "9",
"ok": true
},
"expiry": {
"digit": "4",
"ok": true
},
"personal_number": {
"digit": "2",
"ok": true
},
"composite": {
"digit": "4",
"ok": true
}
},
"print_quality": {
"check_sums": "pass",
"contrast": "not_checked",
"doc_format": "not_checked",
"mrz_format": "not_checked",
"print_position": "not_checked",
"stains": "not_checked",
"symbols": "not_checked"
},
"parsed": {
"Surname And Given Names": "SPECIMEN VZOR",
"RemainderTerm": "0",
"Date of Birth": "110229",
"Given Names": "VZOR",
"Surname": "SPECIMEN",
"Date of Expiry": "2016-09-06",
"Document Class Code": "P",
"Issuing State Name": "Czech Republic",
"Final Checkdigit": "4",
"Optional Data CheckDigit": "2",
"Optional Data": "1152291111",
"Issuing State Code": "CZE",
"Document Number": "99006000",
"Document Number Checkdigit": "8",
"Nationality Code": "CZE",
"Date of Birth Checkdigit": "9",
"Sex": "F",
"Date of Expiry Checkdigit": "4",
"Personal Number": "1152291111",
"MRZ Type": "ID-3"
}
},
"warnings": [],
"error": null
}Document Portrait
/v1/idv/portraitdocuments.portraitThe portrait cut from the document, and a one-time reference you can pass straight to Face Verify or Face Match as image1.
**Returns**
- portrait_ref: a doc_ token for the portrait, reusable in a Face call
- face_detected: whether a face was found on the document
- faces_on_document: how many faces the page carries (a second is often the ghost image)
- face_confidence: 0 to 1, how sure the face detection is
- portrait: the portrait image, base64
**Limits**
- The reference token lasts about an hour.
Price: 0.02 credits per successful call.
Body parameters
imagestringrequiredDocument. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.
Returns
The check ran.
Show the DocumentPortraitResponse fieldsHide fields
okbooleanrequiredtrue: the result is in
data.request_idstringlatency_msnumberHow long the check took, in milliseconds.
dataobjectrequiredThe answer of Document Portrait.
Show 5 fieldsHide fields
portrait_refstringface_detectedbooleanfaces_on_documentnumberface_confidencenumberportraitstring
warningsarray of stringserroranyEmpty on success.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v1/idv/portrait \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
}'{
"ok": true,
"request_id": "req_f6d88e9d8641426bad23",
"latency_ms": 1165,
"data": {
"portrait_ref": "doc_Vb3Xq9LmT2rKw8Zp4nYc1sHd",
"face_detected": true,
"faces_on_document": 1,
"face_confidence": 0.96,
"portrait": "<base64 image>"
},
"warnings": [],
"error": null
}Document Authenticity
/v1/idv/authenticitydocuments.authenticityThe document's checks and the capture's image quality. Each item is pass, fail or not_checked, with one overall verdict.
**Returns**
- overall: the top-line verdict: pass, fail or not_checked
- failed[]: every check that failed, expiry included
- summary: how many checks passed, failed or were not checked
- checks[]: each document check with its status
- image_quality: glare, focus, resolution, screen capture, bounds, portrait
**Limits**
- Status values: pass, fail, not_checked. A specimen document can read as fail by design.
Price: 0.25 credits per successful call.
Body parameters
image_frontstringrequiredDocument front. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.
image_backstringDocument back. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.
Returns
The check ran.
Show the DocumentAuthenticityResponse fieldsHide fields
okbooleanrequiredtrue: the result is in
data.request_idstringlatency_msnumberHow long the check took, in milliseconds.
dataobjectrequiredThe answer of Document Authenticity.
Show 5 fieldsHide fields
overallstringfailedarray of stringssummaryobjectShow 3 fieldsHide fields
passnumberfailnumbernot_checkednumber
checksarray of objectsShow 2 fieldsHide fields
namestringstatusstring
image_qualityobjectShow 6 fieldsHide fields
focusstringglarestringportraitstringboundsstringperspectivestringresolutionstring
warningsarray of stringserroranyEmpty on success.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v1/idv/authenticity \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image_front": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
}'{
"ok": true,
"request_id": "req_188d8bca755843808f92",
"latency_ms": 1181,
"data": {
"overall": "fail",
"failed": [
"expiry",
"mrz",
"text"
],
"summary": {
"pass": 2,
"fail": 3,
"not_checked": 2
},
"checks": [
{
"name": "docType",
"status": "pass"
},
{
"name": "expiry",
"status": "fail"
},
{
"name": "imageQA",
"status": "pass"
},
{
"name": "mrz",
"status": "fail"
},
{
"name": "security",
"status": "not_checked"
},
{
"name": "text",
"status": "fail"
},
{
"name": "vds",
"status": "not_checked"
}
],
"image_quality": {
"focus": "pass",
"glare": "pass",
"portrait": "pass",
"bounds": "pass",
"perspective": "pass",
"resolution": "pass"
}
},
"warnings": [],
"error": null
}Document Fields
/v1/idv/fieldsdocuments.fieldsWhich fields were read, from which sources, whether each is valid, and whether the sources agree. Values are masked, so it is safe to log.
**Returns**
- summary: how many fields are valid, failed or not checked, and how many disagree between sources
- fields[].label: the field name
- fields[].sources: where it was read: MRZ, VISUAL, BARCODE
- fields[].status: valid, fail or not_checked
- fields[].sources_agree: whether the sources match
- fields[].value_masked: the value, masked
**Limits**
- Raw values are never returned here; use Document Read for full values, behind access control.
Price: 0.02 credits per successful call.
Body parameters
imagestringrequiredDocument. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.
Returns
The check ran.
Show the DocumentFieldsResponse fieldsHide fields
okbooleanrequiredtrue: the result is in
data.request_idstringlatency_msnumberHow long the check took, in milliseconds.
dataobjectrequiredThe answer of Document Fields.
Show 4 fieldsHide fields
date_formatstringcountnumbersummaryobjectShow 4 fieldsHide fields
passnumberfailnumbernot_checkednumbersources_disagreenumber
fieldsarray of objectsShow 6 fieldsHide fields
typenumberlabelstringstatusstringsourcesarray of stringssources_agreestringvalue_maskedstring
warningsarray of stringserroranyEmpty on success.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v1/idv/fields \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
}'{
"ok": true,
"request_id": "req_0a12c067aef84eabb429",
"latency_ms": 1229,
"data": {
"date_format": "yyyy-MM-dd",
"count": 31,
"summary": {
"pass": 13,
"fail": 8,
"not_checked": 10,
"sources_disagree": 3
},
"fields": [
{
"type": 25,
"label": "Surname And Given Names",
"status": "fail",
"sources": [
"VISUAL"
],
"sources_agree": "not_checked",
"value_masked": "S••••••••••Ó"
},
{
"type": 25,
"label": "Surname And Given Names",
"status": "fail",
"sources": [
"MRZ",
"VISUAL"
],
"sources_agree": "fail",
"value_masked": "S••••••••••R"
},
{
"type": 364,
"label": "RemainderTerm",
"status": "fail",
"sources": [
"MRZ",
"VISUAL"
],
"sources_agree": "pass",
"value_masked": "•"
},
{
"type": 8,
"label": "Surname",
"status": "fail",
"sources": [
"VISUAL"
],
"sources_agree": "not_checked",
"value_masked": "S••••••N"
}
]
},
"warnings": [],
"error": null
}Proof of Address
/v1/poa/analyzeproofOfAddress.analyzeReads a proof-of-address document (utility bill, bank statement, letter) and checks it against the name, address and country you expect, with a recency and integrity check.
**Returns**
- document: what it is, type, issue date
- address: the extracted address, split into parts
- verification.comparisons: name, address and country against what you expected
- verification.recency: how old the document is vs the limit
- verification.decision: pass, refer or fail, with reasons
**Limits**
- PDF, JPG or PNG, up to 10 MB.
Price: 0.4 credits per successful call.
Body parameters
document_tokenstringrequiredAddress document. Encrypted in your browser; the API takes the token of the stored document. A document token from the vault.
filenamestringFile name.
expectedobjectShow 3 fieldsHide fields
namestringExpected name.
addressstringExpected address.
countrystringExpected country. ISO alpha-2, for example RW.
Returns
The check ran.
Show the ProofOfAddressAnalyzeResponse fieldsHide fields
okbooleanrequiredtrue: the result is in
data.request_idstringlatency_msnumberHow long the check took, in milliseconds.
dataobjectrequiredThe full result of Proof of Address: everything the check found. See the fields listed in the operation.
warningsarray of stringserroranyEmpty on success.
Errors
400A field is missing or not valid.401No API key, or the key is not valid, expired or revoked.402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.413The image or the request is too large.429Too many requests for this key: waitRetry-Afterseconds. Nothing was charged.5XXThe check could not run. Nothing was charged.
curl -X POST https://verisec.dev/v1/poa/analyze \
-H "Authorization: Bearer $VERISEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_token": "doc_example"
}'{
"ok": true,
"request_id": "req_7c1e2a9b40d35f6e8a12",
"latency_ms": 21400,
"data": {
"schema_version": "1.0",
"file": {
"kind": "image",
"pages": 1,
"pages_analyzed": 1,
"sha256": "9f2c0b7e41a3d58c"
},
"document": {
"is_proof_of_address": true,
"what_it_is": "A water utility bill",
"not_accepted_because": null,
"type": "utility_bill",
"title_as_printed": "Water bill",
"country": "RW",
"languages": [
"en"
],
"issue_date": "2026-09-02",
"period_end": "2026-08-31"
},
"issuer": {
"name": "Example Water Ltd",
"type": "utility",
"contact_as_printed": "+250 700 000 000"
},
"holder": {
"names": [
"Jane Example"
],
"role": "account_holder",
"national_id": {
"scheme": null,
"value_masked": null
}
},
"address": {
"role": "service_address",
"raw": "KG 000 St, Kacyiru, Gasabo, Kigali",
"street": "KG 000 St",
"sector": "Kacyiru",
"district": "Gasabo",
"city": "Kigali",
"country": "RW"
},
"account": {
"account_number": "000123456",
"references": [
{
"kind": "invoice",
"value": "INV-0001"
}
]
},
"amounts": {
"amount_due": 12500,
"currency": "RWF",
"line_items": [
{
"label": "Water",
"amount": 12500
}
]
},
"forensics": {
"integrity": {
"edited_text_suspected": false,
"totals_consistent": true,
"pixel_check": "clean"
},
"capture": {
"screen_photo": false,
"photocopy": false,
"page_complete": true
}
},
"verification": {
"comparisons": {
"name_vs_id": {
"status": "match",
"score": null
},
"address_vs_declared": {
"status": "match",
"score": null
},
"country_vs_expected": {
"status": "match",
"score": null
}
},
"recency": {
"status": "pass",
"days_old": 33,
"max_days": 90,
"date_used": "2026-09-02"
},
"document_type": {
"status": "pass",
"type": "utility_bill"
},
"integrity": {
"status": "pass"
},
"authenticity_score": 92,
"decision": "pass",
"reasons": [
{
"code": "recent",
"label": "Issued within 90 days",
"tone": "good"
}
]
}
},
"warnings": [],
"error": null
}