Available via API | Available via SDK | Needs configuration on Veriff’s side | Needs a separate integration | Needs a separate webhook |
|---|---|---|---|---|
✅ | ❌ | ✅ | ✅ | ❌ |
Unstructured Docs (also known as “uDocs”) is an intelligent document processing solution that allows the classification, data extraction, and validation of non-standardized documents such as bank statements, utility bills, and insurance policies. The system extracts structured data and performs advanced tampering checks to verify the end-user and detect fraud.
Unstructured Docs is currently available only via API. SDK integration is not possible.
You need a separate integration for this solution, meaning existing IDV or PoA or other integrations cannot be used.
Unstructured Docs can be:
used separately as a standalone check;
combined with Address Matching, Address Validation and document Tampering Check solutions.
All session-related info is returned via decision webhook and can be polled from different API endpoints. The results of the verification can also be viewed in the Veriff Customer Portal, in the All verifications > session > Webhooks tab.
If any data was extracted from the document, this data is provided in the decision webhook payload and GET /decision endpoint’s response payload.
Contact your solutions engineer for info and configuration.
Prerequisites
You have an integration set up with Veriff
The feature is configured for that integration by your Solutions Engineer
You have configured the decision webhook to get responses from Veriff
You are ready to collect and send Veriff your end-user’s data
Because the solution is available only via API:
Veriff strongly recommends you collect and send additional device/session data for improved fraud mitigation
Veriff strongly recommends that you create and send us the endUserId or vendorData
Key terminology
Term | Description |
|---|---|
Add-on | A solution/feature that can be enabled for the Unstructured Docs’ integration for additional data verification. |
Address Matching | A feature that compares addresses from two different sources (end-user’s documents and customer-provided initial data) to verify they belong to the same location. Outputs data in |
Address Validation | A feature that validates the address extracted from the end-user’s document. Outputs data in |
Classification | Process to identify document type (e.g., Outputs data in |
Core feature | A feature that is part of the Unstructured Document's solution, required to ensure the solutions’ functionality. |
Document Expiration | Data validation process that checks the validity of the document based on its expiration date or its issue date. Outputs data in |
Extraction | Process to extract specific data fields from the document (e.g., full name, address). Outputs data in |
Feature | In uDocs context, an umbrella term for “add-on”, “classification”, “extraction”, “core feature”, “validations” |
InitData Matching | Data validation process, where the extracted data fields will be matched against the data sent through as initial data on session creation. For name, bank account number and occupation title matching. Outputs data in |
Data fields to be extracted | Data field that can be extracted from end-user’s document. If set to be “mandatory”, the success or failure of this field’s extraction will impact your session result. You can chose which data fields are considered mandatory. |
Supported document type | Document type that can be used to perform a use case-specific verification. |
Tampering Check | Fraud detection feature that analyzes documents for signs of tampering. Outputs data in See below for more info. |
uDocs | Abbreviation of Unstructured Docs |
Use case | A specific real-life scenario where a unstructured document is used for end-user verification. |
Validations | Process where the input data (either extracted from end-user’s document or gathered from initData) is compared against some data point, e.g., against same data from another source, against a specific threshold or rule. |
End-user data sources
The “end-user data sources” refer to different origins from which the end-user’s information can be collected for database verification. There are two data sources: document data and initData.
InitData
This is data that you provide when creating a verification session, i.e. the parameters you specify in the POST /sessions request.
Parameters that can be sent via initData, all are optional:
Full name via
verification.person.fullName(e.g., for InitData Matching validation)Bank account number via
verification.document.number(e.g., for InitData Matching validation)Full address via
verification.address.fullAddress(for Address Matching and Address Validation add-ons)Occupation via
verification.person.occupation(e.g., for InitData Matching validation)
Document data
This is data that is extracted from the end-user’s document. Includes information like names, addresses, or account numbers extracted from bank statements, utility bills, vehicle registration forms etc.
uDocs use cases and flow setup rules
Veriff strongly suggest to have only one use case per integration.
Contact your solutions engineer for info and configuration.
Unstructured Docs can be used to flexibly solve document verification for different use cases. However, there are some rules when setting up the use case:
each use case supports only certain document types,
and allows the extraction of specific document data fields.
Supported document types and extractable data fields mapping is shown in the table below.
Also, each use case supports validation checks that can be configured to work with certain add-ons. Working combinations are shown in the table below.
Note about the data fields to be extracted
The table below shows the maximum list of data fields. You can enable only the ones needed.
None, some or all of them can be set to be mandatory, in which case the success or failure to extract that data will impact your session result.
Note that you need your Solution Engineer’s help to set up the document types, extractable data fields and validation check/add-on combinations. You cannot do this in Customer Portal or via initData.
Use case | Supported document types | Data fields to be extracted | Supported validations and optional supported add-ons |
|---|---|---|---|
Bank account ownership verification |
|
|
|
Source of income verification |
|
|
|
Vehicle ownership verification |
|
|
|
Vehicle insurance policy verification |
|
|
|
Tampering Check aka fraud validation
If the fraud validation has been enabled for your solution, then you will see the additionalVerifiedData.udocs.fraud object in the payload.
The fraud object shows the document's risk level and gives additional details about the factors that influenced this risk assessment. Veriff passes the data unaltered in webhooks and API payloads.
{
...
"additionalVerifiedData": {
"udocs": {
"fraud": {
"riskLevel": "HIGH_RISK",
"reason": "PDF_PROCESSED_BY_EDITOR",
"reasonDescription": "Document was processed using editing software",
"indicators": []
}
},
...
}
}
Note that:
The session will be
declinedif theriskLevel:HIGH_RISK.The decision webhook and API examples further below in this document contain limited info about the possible values of the keys in the
fraudobject.
Veriff recommends you do not build any logic on top of the
fraud.indicatorsarray, as possible values may be altered without prior notice to provide better insights. However, structure of entries will stay backwards compatible.
Flow overview
Unstructured Docs is currently available only via API.
You are responsible for the document capture interface and image quality.
Unstructured Docs verification (with initData validation)
Generate a verification session using the API keys and the
baseURLof your Unstructured Docs integration.Include the initData you want it to be matched against the data on the document.
Veriff strongly recommends you create and send the
endUserIdorvendorData.Veriff strongly recommends you collect and send additional session/device data via POST sessions/{sessionid}/collected-data[↗] for improved fraud detection.
Session creation bash example (with all possible initData fields)
curl --request POST \
--url https://exampleURL.com/v1/sessions/ \
--header 'content-type: application/json' \
--header 'x-auth-client: your-api-key' \
--data '{
"verification": {
"document": {
"number": "847293651024738569"
},
"person": {
"fullName": "JUAN MARTINEZ",
"occupation": "Driver"
},
"address": {
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100"
},
"endUserId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}'
Session creation json example (with all possible initData fields)
{
"verification": {
"document": {
"number": "847293651024738569"
},
"person": {
"fullName": "JUAN MARTINEZ",
"occupation": "Driver"
},
"address": {
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100"
},
"endUserId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}
Upload the end-user's media via POST /sessions/{sessionId}/media[↗] call.
Use your image-capturing method, or send previously collected document image(s).
Unstructured Docs supports JPEG, PNG, and multi-page PDFs (see the POST /sessions/{sessionId}/media[↗] documentation for more info about how to upload the image or PDF files).
Specify the
image.contextasgeneric-document-frontfor the document.This endpoint requires endpoint level authentication via
x-hmac-signatureheader. See HMAC Authentication and Endpoint Security article for general info about signature creation.
Media upload bash example
curl -X POST \
--url 'https://exampleURL.com/v1/sessions/{sessionId}/media' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: your-api-key' \
-H 'X-HMAC-SIGNATURE: your-hmac-signature' \
-d '{
"image": {
"data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAA...",
"context": "generic-document-front"
}
}'
Media upload json example
{
"image": {
"data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAA...",
"context": "generic-document-front"
}
}
Patch session status to
submittedstatus using PATCH /sessions/{sessionId}[↗] callThis endpoint requires endpoint level authentication via
x-hmac-signatureheader. See HMAC Authentication and Endpoint Security article for general info about signature creation.
Session update bash example
curl -X PATCH \
--url 'https://exampleURL.com/v1/sessions/{sessionId}' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: your-api-key' \
-H 'X-HMAC-SIGNATURE: your-hmac-signature' \
-d '{
"status": "submitted"
}'Session update json example
{
"status": "submitted"
}
Check the decision data and/or session related info from the decision webhook and/or query the data from the GET sessions/{sessionId}/decision[↗] endpoint. Solution-specific overview of what to expect is provided below in the Find decision and/or session related info > Solution-specific parameters section.
Unstructured Docs with document extraction (no initData validation)
Generate a verification session using the API keys and the
baseURLof your Unstructured Docs integration.If no initData is sent, the payload can be an empty
verificationobjectVeriff strongly recommends you create and send the
endUserIdorvendorDataVeriff strongly recommends you collect and send additional session/device data via POST sessions/{sessionid}/collected-data[↗] for improved fraud detection
Session creation bash example (empty verification object)
curl --request POST \
--url https://exampleURL.com/v1/sessions/ \
--header 'content-type: application/json' \
--header 'x-auth-client: your-api-key' \
--data '{
"verification": {}
}'Session creation json example (empty verification object)
{
"verification": {}
}
Upload the end-user's media via POST /sessions/{sessionId}/media[↗] call.
Use your image-capturing method, or send previously collected document image(s).
Unstructured Docs supports JPEG, PNG, and multi-page PDFs (see the POST /sessions/{sessionId}/media[↗] documentation for more info about how to upload the image or PDF files).
Specify the
image.contextasgeneric-document-frontfor the document.This endpoint requires endpoint level authentication via
x-hmac-signatureheader. See HMAC Authentication and Endpoint Security article for general info about signature creation.
Media upload bash example
curl -X POST \
--url 'https://exampleURL.com/v1/sessions/{sessionId}/media' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: your-api-key' \
-H 'X-HMAC-SIGNATURE: your-hmac-signature' \
-d '{
"image": {
"data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAA...",
"context": "generic-document-front"
}
}'
Media upload json example
{
"image": {
"data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAA...",
"context": "generic-document-front"
}
}
Patch session status to
submittedstatus using PATCH /sessions/{sessionId}[↗] call.This endpoint requires endpoint level authentication via
x-hmac-signatureheader. See HMAC Authentication and Endpoint Security article for general info about signature creation.
Session update bash example
curl -X PATCH \
--url 'https://exampleURL.com/v1/sessions/{sessionId}' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: your-api-key' \
-H 'X-HMAC-SIGNATURE: your-hmac-signature' \
-d '{
"status": "submitted"
}'
Session update json example
{
"status": "submitted"
}
Check the decision data and/or session related info from the decision webhook and/or query the data from the GET sessions/{sessionId}/decision[↗] endpoint. Solution-specific overview of what to expect is provided below in the Find decision and/or session related info > Solution-specific parameters section.
Find decision and/or session related info
You can get the data from three sources:
Receive the decision webhook (full example with placeholder values below)
Poll the results via GET /decision API endpoint (full example with placeholder values below)
View the session in Veriff Customer Portal > All Verifications > session > Webhooks tab
Solution-specific parameters
The info related to Unstructured Docs is returned in additionalVerifiedData.udocs array. This array contains data objects with info about different aspects (e.g., document classification, data extraction, data matching, document tampering) performed during the session.
Object | Description | Needs enablement by the SE? | Used in |
|---|---|---|---|
| Identifies document type, country, and issuer. Core feature; always present, though nested fields are omitted if confidence is low. | No | Core feature, classification |
| Checks the validity of the document based on either:
| Yes | Document validity period check, validation |
| Extracted data fields (e.g., name, address). Keys appearing here depend on the use case and document type used. Keys are optional and can have an empty value or be completely omitted, depending on the use case configuration and data availability on document. | No | Core feature, extraction |
| Tampering and risk analysis. Omitted if feature is disabled. Returns
| Yes | Tampering Check, add-on |
| Compares initData to extracted data. Omitted if feature is disabled or initData was not provided. Invalid data results in | Yes | Name matching Bank account number matching Occupation info matching |
| A generic object, containing meta info about the document and verification process. Always present. | No | N/A |
Note about object and field visibility
All objects and fields within the additionalVerifiedData.udocs array are optional. You should expect that any key may be omitted from the payload or return an empty or null value.
A field is included in the response only when:
The specific feature or add-on (e.g., Tampering Check or InitData Matching) has been configured for your integration by a solutions engineer
The use case setup defines which data fields need to be extracted
The system successfully extracts that specific data point from the end-user's document
Because the response schema is dynamic and based on both your specific configuration and the quality of the document provided, your application logic must account for omitted keys and null values as a standard part of the verification workflow.
Note on session outcomes
An approved session is identified by a verification.status of approved. The indicators of a “clean” session are found within the specific features’ and/or add-on’s objects.
Depending on your configuration, a session is approved when, for example:
fraud.riskLevelisLOW_RISK(if Tampering Check is enabled),matchinResults.matchistrue(if InitData Matching validation is enabled andinitDatawas provided),documentExpiration.isWithinValidityPeriodistrue(if Document Expiration validation is enabled and the document has an expiry date that cleared the range threshold).
If these features/add-ons are not enabled, their respective objects/keys are omitted from the payload and do not impact the approved status.
Sample payload of udocs object
The following is a sample response for a declined session with all possible additionalVerifiedData.udocs object parameters.
All strings and IDs (e.g., fullName, documentType) are placeholder values used for illustrative purposes only. Your production payload will contain real-time data extracted from the end-user's document.
See the Request properties explained section below for info about the properties.
{
"additionalVerifiedData": [
{
"udocs": {
"metadata": {
"pageCount": 2
},
"extraction": {
"fullName": "JUAN MARTINEZ",
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100",
"bankAccountNumber": "84532345",
"issueDate": "2024-05-28",
"expiryDate": "2025-05-28",
"documentNumber": "847293651024738569",
"vehicleIdentificationNumber": "1HGBH41JXMN109186",
"vehicleRegistrationNumber": "ABC-1234",
"occupation": "Driver",
"income": "45000",
"issuer": "Skrill Limited",
"currency": "USD"
},
"classification": {
"documentType": "financial",
"documentSubType": "bank_statement",
"countryCode": "mx",
"language": "es",
"issuer": "skrill_limited"
},
"matchingResults": [
{
"type": "full_name",
"match": true,
"originalValue": "JUAN MARTINEZ",
"extractedValue": "JUAN MARTINEZ",
"matchThreshold": 80,
"matchPercentage": 100
},
{
"type": "occupation",
"match": true,
"originalValue": "Driver",
"extractedValue": "Driver",
"matchThreshold": 80,
"matchPercentage": 100
}
],
"fraud": {
"riskLevel": "HIGH_RISK",
"reason": "DIGITAL_MODIFICATION_HIGH_CONFIDENCE",
"reasonDescription": "Document contains traces of digital modification, likely with fraudulent intent",
"indicators": [
"This document's metadata shows a creation time: 2023-03-31T12:04:01+00:00 and a modification time: 2024-05-29T11:30:26+00:00, suggesting the file was updated after it was first created. The time gap between creation and modification is 424 days, 23:26:25."
]
},
"documentExpiration": {
"isIssueDateInRange": false,
"isWithinValidityPeriod": false
}
}
}
]
}
Sample payload with Address Matching and Address Validation info
The following is a sample response for a declined session showing objects that are sent when Address Matching and Address Validation add-ons have been enabled for the use case.
All strings and IDs (e.g., fullName, documentType) are placeholder values used for illustrative purposes only. Your production payload will contain real-time data extracted from the end-user's document.
See the Address Matching and Address Validation documentation for more info about the properties.
{
"status": "success",
"verification": {
"acceptanceTime": "2026-02-18T13:39:54.401658Z",
"submissionTime": "2026-02-18T13:40:22.784253Z",
"decisionTime": "2026-02-18T13:41:47.173826Z",
"code": 9102,
"id": "f3a8b7c2-d4e1-4f92-a8b3-c5d6e7f8a9b0",
"vendorData": null,
"endUserId": null,
"status": "declined",
"reason": "Addresses do not match",
"reasonCode": 573,
"person": {
"firstName": "JUAN MARTINEZ",
"lastName": null,
"fullName": "JUAN MARTINEZ",
"citizenship": null,
"idNumber": null,
"gender": null,
"dateOfBirth": null,
"yearOfBirth": null,
"placeOfBirth": null,
"nationality": null,
"addresses": [
{
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100"
}
],
"pepSanctionMatch": null
},
"document": {
"number": null,
"type": "BANK_STATEMENT",
"country": "MX",
"validFrom": "2025-12-09",
"validUntil": null,
"state": null
},
"comments": [],
"additionalVerifiedData": {
"proofOfAddress": {
"addressValidationResult": {
"components": {
"plausibleFullAddress": "CALLE MADERO 415 INT 5 COL CENTRO CUAUHTÉMOC CIUDAD DE MÉXICO MÉXICO CP 06000",
"street": "CALLE MADERO",
"city": "CUAUHTÉMOC",
"state": "CIUDAD DE MÉXICO",
"postcode": "06000",
"country": "MÉXICO",
"houseNumber": "415",
"unit": "INT 5"
},
"addressType": "residential",
"validations": {
"countryExists": {
"result": "skipped"
}
}
}
},
"addressMatching": {
"matchPercentage": 0,
"matchThreshold": 80,
"result": false,
"addresses": [
{
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100",
"parsedAddress": {
"street": "AV INSURGENTES SUR",
"city": "BENITO JUAREZ",
"state": "CIUDAD DE MEXICO",
"postcode": "03100",
"country": "MEXICO",
"houseNumber": "2847",
"unit": "PISO 3"
}
},
{
"fullAddress": "CALLE MADERO 415 INT 5 COL CENTRO CUAUHTÉMOC CIUDAD DE MÉXICO MÉXICO CP 06000",
"parsedAddress": {
"street": "CALLE MADERO",
"city": "CUAUHTÉMOC",
"state": "CIUDAD DE MÉXICO",
"postcode": "06000",
"country": "MÉXICO",
"houseNumber": "415",
"unit": "INT 5"
}
}
]
},
"udocs": {
"metadata": {
"pageCount": 1
},
"extraction": {
"fullName": "JUAN MARTINEZ",
"fullAddress": "CALLE MADERO 415 INT 5 COL CENTRO CUAUHTÉMOC CIUDAD DE MÉXICO MÉXICO CP 06000",
"bankAccountNumber": "014180012345678902",
"issueDate": "2025-12-09",
"occupation": "",
"income": "",
"issuer": "Santander",
"currency": "MXN"
},
"classification": {
"documentType": "financial",
"documentSubType": "bank_statement",
"countryCode": "MX",
"language": "ES",
"issuer": "Santander"
},
"matchingResults": [
{
"type": "full_name",
"match": true,
"originalValue": "JUAN MARTINEZ",
"extractedValue": "JUAN MARTINEZ",
"matchThreshold": 80,
"matchPercentage": 100
},
{
"type": "occupation",
"match": false,
"originalValue": "Engineer",
"extractedValue": "",
"matchThreshold": 80,
"matchPercentage": 0
}
],
"fraud": {
"riskLevel": "HIGH_RISK",
"reason": "ILLEGIBILITY",
"reasonDescription": "Unreadable document",
"indicators": [
"This image appears to have been generated directly from a digital PDF. This is unusual and may suggest an attempt to conceal edits. Some organizations have policies restricting the acceptance and use of digital prints."
]
},
"documentExpiration": {
"isIssueDateInRange": true
}
}
},
"attemptId": "b9c8d7e6-f5a4-4b32-9c8d-7e6f5a4b3c2d"
},
"technicalData": {
"ip": null
}
}Webhook payload
The example below uses placeholder data to show all mandatory parameters and possible uDocs fields. While mandatory fields are always present, solution-specific keys are omitted if a feature is disabled or data extraction fails. Depending on your integration’s configuration, your production payload may contain additional parameters; for info on fields from other solutions, see the decision webhook documentation.
Sample request
The following features have been enabled for the session: Classification, Extraction, InitData Matching, Tampering Check, Document Expiration.
{
"status": "success",
"verification": {
"acceptanceTime": "2026-02-04T11:57:36.495752Z",
"submissionTime": "2026-02-04T11:57:43.127728Z",
"decisionTime": "2026-02-04T11:58:15.073712Z",
"code": 9102,
"id": "f3a8b7c2-d4e1-4f92-a8b3-c5d6e7f8a9b0",
"vendorData": null,
"endUserId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "declined",
"reason": "Name in initData does not match the document name",
"reasonCode": 541,
"person": {
"firstName": null,
"lastName": null,
"fullName": "JUAN MARTINEZ",
"citizenship": null,
"idNumber": null,
"gender": null,
"dateOfBirth": null,
"yearOfBirth": null,
"placeOfBirth": null,
"nationality": null,
"addresses": [
{
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100"
}
],
"pepSanctionMatch": null
},
"document": {
"number": null,
"type": null,
"country": null,
"validFrom": null,
"validUntil": null,
"state": null
},
"comments": [],
"additionalVerifiedData": {
"udocs": {
"metadata": {
"pageCount": 2
},
"extraction": {
"fullName": "JUAN MARTINEZ",
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100",
"bankAccountNumber": "84532345",
"issueDate": "2024-05-28",
"expiryDate": "2025-05-28",
"documentNumber": "847293651024738569",
"vehicleIdentificationNumber": "1HGBH41JXMN109186",
"vehicleRegistrationNumber": "ABC-1234",
"occupation": "Driver",
"income": "45000",
"issuer": "Skrill Limited",
"currency": "USD"
},
"classification": {
"documentType": "financial",
"documentSubType": "bank_statement",
"countryCode": "mx",
"language": "es",
"issuer": "skrill_limited"
},
"matchingResults": [
{
"type": "full_name",
"match": true,
"originalValue": "JUAN MARTINEZ",
"extractedValue": "JUAN MARTINEZ",
"matchThreshold": 80,
"matchPercentage": 100
},
{
"type": "occupation",
"match": true,
"originalValue": "Driver",
"extractedValue": "Driver",
"matchThreshold": 80,
"matchPercentage": 100
},
{
"type": "bank_account_number",
"match": true,
"originalValue": "AB123456789012345",
"extractedValue": "AB123456789012345",
"matchThreshold": 100,
"matchPercentage": 100
}
],
"fraud": {
"riskLevel": "HIGH_RISK",
"reason": "DIGITAL_MODIFICATION_HIGH_CONFIDENCE",
"reasonDescription": "Document contains traces of digital modification, likely with fraudulent intent",
"indicators": [
"This document's metadata shows a creation time: 2023-03-31T12:04:01+00:00 and a modification time: 2024-05-29T11:30:26+00:00, suggesting the file was updated after it was first created. The time gap between creation and modification is 424 days, 23:26:25."
]
},
"documentExpiration": {
"isIssueDateInRange": false,
"isWithinValidityPeriod": false
}
}
},
"attemptId": "b9c8d7e6-f5a4-4b32-9c8d-7e6f5a4b3c2d"
},
"technicalData": {
"ip": null
}
}Request properties explained
status:stringStatus of the responseverification:object | nullVerification request decision object.nullif decision is not available yetid:stringUUID v4 which identifies the verification sessionattemptId:stringUUID v4 of the attempt which received a status (as shown inverification.statusfield)vendorData:string | nullThe unique identifier that you created for your end-user.nullif not specifiedendUserId:string | nullTheUUIDthat you created for your end-user.nullif not specifiedstatus:stringVerification status, one ofapproved,declined,expired,abandonedcode:integerVerification session decision code, one of9001,9102,9103,9104,9121. For more info, see the verification session decision codesreason:string | nullReason why the verification failedreasonCode:integer | nullReason code of the failed verification. For more info, see the possible codes for a failed verificationacceptanceTime:stringTimestamp of the session generation, represented asUTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset(ISO 8601)submissionTime:stringTimestamp of when the session was submitted, represented asUTC YYYY-MM-DDTHH:MM:SS.SSSSSS+Timezone Offset(ISO 8601)decisionTime:string | nullTimestamp of the decision, represented asUTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset(ISO 8601)person:objectData about the verified personfirstName:string | nullPerson's first name as written on the documentlastName:string | nullPerson's last name as written on the documentfullName:string | nullFull name of the personcitizenship:nullDeprecated, always returns nullidNumber:string | nullNational identification numbergender:string | nullPerson's gender, represented as M or F, ornullif not presentdateOfBirth:string | nullPerson's date of birth, represented asYYYY-MM-DDyearOfBirth:string | nullPerson's year of birth, represented asYYYYplaceOfBirth:string | nullPerson's place of birthnationality:string | nullPerson's nationality, represented as ISO 3166alpha-2oralpha-3numberaddresses:arrayA map with keys forfullAddressfullAddress:string | nullAddress as single string
document:objectVerified documentnumber:string | nullDocument number,[a-zA-Z0-9]characters onlytype:string | nullDocument typecountry:string | nullDocument issuing country, represented as ISO 3166alpha-2codevalidFrom:string | nullDocument is valid from date, represented asYYYY-MM-DD. Optional, must be configured for your integration by the Solutions EngineervalidUntil:string | nullDocument is valid until date, represented asYYYY-MM-DD. Optional, must be configured for your integration by the Solutions Engineerstate:string | nullDocument issuing state, represented as ISO 3166alpha-2oralpha-3code
additionalVerifiedData:objectData that has been optionally verified for the sessionudocs:objectContainer for the features’ and add-ons’ resultsmetadata:objectContains meta info about the document and verification processpageCount:integerIndicates how many pages were processed
extraction:objectReturning info about all the data that was extractedfullName:stringPerson’s full name data from documentfullAddress:stringPerson’s full address data from documentbankAccountNumber:stringPerson’s bank account number from documentissueDate:stringDocument issue date data from documentexpiryDate:stringDocument expiry date data from documentdocumentNumber:stringDocument number from document, e.g., policy number, certificate number, document reference numbervehicleIdentificationNumber:stringThe unique 17-character VIN of the vehicle, as present on documentvehicleRegistrationNumber:stringVehicles registration number data, as present on documentoccupation:stringPerson’s occupation data from documentincome:stringPerson’s income amount from documentissuer:stringDocument issuer name from documentcurrency:stringCurrency as shown on document
classification:objectContains data about document’s type, country code, language and issuerdocumentType:stringDocument types’ grouping, one offinancial,government,housing,insurance,legal,tax,utility,otherdocumentSubType:stringDocument’s type (see possible values in Supported document types section)countryCode:stringDocument’s country, represented as ISO 3166alpha-2language:stringDocument’s language, represented as ISO 3166alpha-2issuer:stringDocument issuing entity
matchingResults:arrayReturns info about how initData matched to document data. Available only when the initData matching validation was enabled for your uDocs integration.type:stringIndicates the initData field that was matched to extracted datamatch:booleanIndicates if match wastrueorfalseoriginalValue:stringEchoes the initData valueextractedValue:stringReturns the value extracted form documentmatchThreshold:integerShows the match threshold set for the specific fieldmatchPercentage:integerReturns the match percentage
fraud:objectReturns data about document integrity. Available only if Tampering check is enabled for your uDocs integration.riskLevel:stringIndicates the risk level of the document, possible valuesLOW_RISK,MEDIUM_RISK,HIGH_RISK.nullif the check was not executed or failed.reason:stringShort description indicating the reason behind the risk level.nullif the check was not executed or failed.reasonDescription:stringHuman readable explanation of the data in thereasonfield.nullif the check was not executed or failed.indicators:arrayArray strings listing the factors that influenced the risk assessment. Empty if the check was not executed or failed.
documentExpiration:objectReturns data about document expiration. Available only if Document Expiration check is enabled for your uDocs integration.isIssueDateInRange:booleanChecks if document’s issue date clears the allowed range threshold (days since issue date). Skipped if the document has an expiry date and and expiry date check has been enabled.isWithinValidityPeriod:booleanChecks if document’s expiration date clears the range threshold (days before expiration date)
pepSanctionMatch:string | nullLegacy field, may return incorrect result, should be ignoredcomments:array(Deprecated) Always returns empty []
technicalData:objectTechnical data objectip:string | nullIP of the device from which the verification was made
API call
The example below uses placeholder data to show all mandatory parameters and possible uDocs fields. While mandatory fields are always present, solution-specific keys are omitted if a feature is disabled or data extraction fails. Depending on your configuration, the payload may contain additional parameters; for info on fields from other solutions, see the GET sessions/{sessionId}/decision[↗] API documentation.
Sample response
The following features have been enabled for the session: Classification, Extraction, InitData Matching, Tampering Check, Document Expiration.
{
"status": "success",
"verification": {
"acceptanceTime": "2026-02-04T11:57:36.495752Z",
"submissionTime": "2026-02-04T11:57:43.127728Z",
"decisionTime": "2026-02-04T11:58:15.073712Z",
"code": 9102,
"id": "f3a8b7c2-d4e1-4f92-a8b3-c5d6e7f8a9b0",
"vendorData": null,
"endUserId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "declined",
"reason": "Name in initData does not match the document name",
"reasonCode": 541,
"person": {
"firstName": null,
"lastName": null,
"fullName": "JUAN MARTINEZ",
"citizenship": null,
"idNumber": null,
"gender": null,
"dateOfBirth": null,
"yearOfBirth": null,
"placeOfBirth": null,
"nationality": null,
"addresses": [
{
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100"
}
],
"pepSanctionMatch": null
},
"document": {
"number": null,
"type": null,
"country": null,
"validFrom": null,
"validUntil": null,
"state": null
},
"comments": [],
"additionalVerifiedData": {
"udocs": {
"metadata": {
"pageCount": 2
},
"extraction": {
"fullName": "JUAN MARTINEZ",
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100",
"bankAccountNumber": "84532345",
"issueDate": "2024-05-28",
"expiryDate": "2025-05-28",
"documentNumber": "847293651024738569",
"vehicleIdentificationNumber": "1HGBH41JXMN109186",
"vehicleRegistrationNumber": "ABC-1234",
"occupation": "Driver",
"income": "45000",
"issuer": "Skrill Limited",
"currency": "USD"
},
"classification": {
"documentType": "financial",
"documentSubType": "bank_statement",
"countryCode": "mx",
"language": "es",
"issuer": "skrill_limited"
},
"matchingResults": [
{
"type": "full_name",
"match": true,
"originalValue": "JUAN MARTINEZ",
"extractedValue": "JUAN MARTINEZ",
"matchThreshold": 80,
"matchPercentage": 100
},
{
"type": "occupation",
"match": true,
"originalValue": "Driver",
"extractedValue": "Driver",
"matchThreshold": 80,
"matchPercentage": 100
},
{
"type": "bank_account_number",
"match": true,
"originalValue": "AB123456789012345",
"extractedValue": "AB123456789012345",
"matchThreshold": 100,
"matchPercentage": 100
}
],
"fraud": {
"riskLevel": "HIGH_RISK",
"reason": "DIGITAL_MODIFICATION_HIGH_CONFIDENCE",
"reasonDescription": "Document contains traces of digital modification, likely with fraudulent intent",
"indicators": [
"This document's metadata shows a creation time: 2023-03-31T12:04:01+00:00 and a modification time: 2024-05-29T11:30:26+00:00, suggesting the file was updated after it was first created. The time gap between creation and modification is 424 days, 23:26:25."
]
},
"documentExpiration": {
"isIssueDateInRange": false,
"isWithinValidityPeriod": false
}
}
},
"attemptId": "b9c8d7e6-f5a4-4b32-9c8d-7e6f5a4b3c2d"
},
"technicalData": {
"ip": null
}
}Response properties explained
status:stringStatus of the responseverification:object | nullVerification request decision object.nullif decision is not available yetid:stringUUID v4 which identifies the verification sessionattemptId:stringUUID v4 of the attempt which received a status (as shown inverification.statusfield)vendorData:string | nullThe unique identifier that you created for your end-user.nullif not specifiedendUserId:string | nullTheUUIDthat you created for your end-user.nullif not specifiedstatus:stringVerification status, one ofapproved,declined,expired,abandonedcode:integerVerification session decision code, one of9001,9102,9103,9104,9121. For more info, see the verification session decision codesreason:string | nullReason why the verification failedreasonCode:integer | nullReason code of the failed verification. For more info, see the possible codes for a failed verificationacceptanceTime:stringTimestamp of the session generation, represented asUTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset(ISO 8601)submissionTime:stringTimestamp of when the session was submitted, represented asUTC YYYY-MM-DDTHH:MM:SS.SSSSSS+Timezone Offset(ISO 8601)decisionTime:string | nullTimestamp of the decision, represented asUTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset(ISO 8601)person:objectData about the verified personfirstName:string | nullPerson's first name as written on the documentlastName:string | nullPerson's last name as written on the documentfullName:string | nullFull name of the personcitizenship:nullDeprecated, always returns nullidNumber:string | nullNational identification numbergender:string | nullPerson's gender, represented as M or F, ornullif not presentdateOfBirth:string | nullPerson's date of birth, represented asYYYY-MM-DDyearOfBirth:string | nullPerson's year of birth, represented asYYYYplaceOfBirth:string | nullPerson's place of birthnationality:string | nullPerson's nationality, represented as ISO 3166alpha-2oralpha-3numberaddresses:arrayA map with keys forfullAddressfullAddress:string | nullAddress as single string
document:objectVerified documentnumber:string | nullDocument number,[a-zA-Z0-9]characters onlytype:string | nullDocument typecountry:string | nullDocument issuing country, represented as ISO 3166alpha-2codevalidFrom:string | nullDocument is valid from date, represented asYYYY-MM-DD. Optional, must be configured for your integration by the Solutions EngineervalidUntil:string | nullDocument is valid until date, represented asYYYY-MM-DD. Optional, must be configured for your integration by the Solutions Engineerstate:string | nullDocument issuing state, represented as ISO 3166alpha-2oralpha-3code
additionalVerifiedData:objectData that has been optionally verified for the sessionudocs:objectContainer for the features’ and add-ons’ resultsmetadata:objectContains meta info about the document and verification processpageCount:integerIndicates how many pages were processed
extraction:objectReturning info about all the data that was extractedfullName:stringPerson’s full name data from documentfullAddress:stringPerson’s full address data from documentbankAccountNumber:stringPerson’s bank account number from documentissueDate:stringDocument issue date data from documentexpiryDate:stringDocument expiry date data from documentdocumentNumber:stringDocument number from document, e.g., policy number, certificate number, document reference numbervehicleIdentificationNumber:stringThe unique 17-character VIN of the vehicle, as present on documentvehicleRegistrationNumber:stringVehicles registration number data, as present on documentoccupation:stringPerson’s occupation data from documentincome:stringPerson’s income amount from documentissuer:stringDocument issuer name from documentcurrency:stringCurrency as shown on document
classification:objectContains data about document’s type, country code, language and issuerdocumentType:stringDocument types’ grouping, one offinancial,government,housing,insurance,legal,tax,utility,otherdocumentSubType:stringDocument’s type (see possible values in Supported document types section)countryCode:stringDocument’s country, represented as ISO 3166alpha-2language:stringDocument’s language, represented as ISO 3166alpha-2issuer:stringDocument issuing entity
matchingResults:arrayReturns info about how initData matched to document data. Available only when the initData matching validation was enabled for your uDocs integration.type:stringIndicates the initData field that was matched to extracted datamatch:booleanIndicates if match wastrueorfalseoriginalValue:stringEchoes the initData valueextractedValue:stringReturns the value extracted form documentmatchThreshold:integerShows the match threshold set for the specific fieldmatchPercentage:integerReturns the match percentage
fraud:objectReturns data about document integrity. Available only if Tampering check is enabled for your uDocs integration.riskLevel:stringIndicates the risk level of the document, possible valuesLOW_RISK,MEDIUM_RISK,HIGH_RISK.nullif the check was not executed or failed.reason:stringShort description indicating the reason behind the risk level.nullif the check was not executed or failed.reasonDescription:stringHuman readable explanation of the data in thereasonfield.nullif the check was not executed or failed.indicators:arrayArray strings listing the factors that influenced the risk assessment. Empty if the check was not executed or failed.
documentExpiration:objectReturns data about document expiration. Available only if Document Expiration check is enabled for your uDocs integration.isIssueDateInRange:booleanChecks if document’s issue date clears the allowed range threshold (days since issue date). Skipped if the document has an expiry date and and expiry date check has been enabled.isWithinValidityPeriod:booleanChecks if document’s expiration date clears the range threshold (days before expiration date)
pepSanctionMatch:string | nullLegacy field, may return incorrect result, should be ignoredcomments:array(Deprecated) Always returns empty []
technicalData:objectTechnical data objectip:string | nullIP of the device from which the verification was made
Veriff Customer Portal
You can find the verification session related info, including the decision, in the Veriff Customer Portal, in the All Verifications > session > Webhooks tab.
→ See Review verification in Veriff Customer Portal about how to view the session info in the Veriff Customer portal
Status and reason codes
For an approved session, see:
verification.codeabout verification session decision code, one of9001verification.statusabout verification status, one ofapproved
If the Unstructured Docs session was declined, you can find additional information by checking:
verification.reasonfor the reason why the verification failedverification.reasonCodefor reason code of the failed verification and cross-reference it with Granular reason codes (table)
|
|
| What does it mean? |
|---|---|---|---|
| 510 | Document type not supported | Document type not in accepted list or classified as "OTHER" |
| 511 | Document expired / issued too long ago | Document is expired or beyond validity period |
| 541 | Name on document does not match session data | Extracted name match score is below required threshold |
| 566 | System processing error | Internal system error or processing timeout |
| 568 | Invalid Input / Mandatory fields failed | Mandatory fields could not be extracted or initData is missing |
| 572 | Document number mismatch | Extracted number (e.g. bank account) does not match initData |
| 628 | Unable to collect issue date | The issue date could not be extracted from the document |
| 629 | Unable to collect expiry date | The expiry date could not be extracted from the document |
The table above aims to list the most common reasons why you may see the decline reason for an Unstructured Docs session. However, the session may be declined due to a reason that is not inherently Unstructured Docs verification related (e.g. uploaded document’s quality is low). In that case, to find info about the codes you are seeing, refer to:
Additional information
Best Practices
Document image quality: ensure that end-user’s document image is of good quality. This will reduce the possibility of session being
declinedor extraction failures happening.Error handling: implement proper error handling for all possible validation results. For processing timeouts (566), implement retry logic with exponential backoff.
Session declined due to third-party provider issues: implement proper session handling flow when possibly legitimate end-user’s session is declined due to internal system errors, as indicated by session code 566.
Webhook security: secure your webhook endpoint and verify request signatures.
Ensure backwards-compatible-changes for webhooks and API connections
Changelog
Date | Description |
|---|---|
Feb 20, 2026 | Sample payload with Address Matching and Address Validation info added |
Feb 19, 2026 | Documentation published |