This is a legacy solution. If you are interested in Veriff’s Proof of Address solution, please refer to Proof of Address Verification documentation
Veriff’s Proof of Address Extraction (PoA Extraction) feature captures the submitted document and extracts the firstName
, fullAddress
, documentType
and document.validFrom
data from it.
It is available via API, web flow, and native SDKs.
Contact your solutions engineer for info and configuration.
It is possible to get the additional name match check enabled for your integration. See the Optional Proof of Address name match check section below for more info.
Prerequisites
You have an integration set up with Veriff
Your Solutions Engineer has enabled the PoA Extraction for the integration
You have set up the decision webhook
If using the API, you are ready to send Veriff images of the end-user’s proof of address document
Flow overview
The flow is a bit different, depending on the method you are using to verify your end-users with Veriff.
Use via SDKs
Generate a verification session using the authentication integration tokens (check the POST /sessions[↗] endpoint in the API reference)
Capture end-user’s PoA document images with Veriff’s SDKs
Send the end-user through the verification flow to capture the image (using the preferred Veriff SDK)
You need the session URL generated in step 1 to use the SDKs (found in response payload as
verification.url
)
Session will be submitted automatically once the end-user takes and submits necessary images of their face
Receive the results from Veriff via decision webhook
Use via API
1. Create a session using the POST /sessions call
1.1 Include the API URL and mandatory headers
POST {baseURL}/v1/sessions
Type: object
Headers:
X-AUTH-CLIENT: string (required) = API key
Content-Type: application/json
1.2 Add the following data (minimum payload)
verification
:object
Verification object*. You can send an empty object, or include the following to improve the results:vendorData:
string
endUserId:
string
*Mandatory parameter
Request payload sample
curl -X POST \
--url '/v1/sessions/' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-d '{
"verification": {
"vendorData": "11111111"
}
}'
→ See the POST /sessions[↗] endpoint documentation for further details about how to start a session
2. Make a POST /sessions/{sessionId}/media request
You can use this endpoint to send several images, but you need to upload them one at a time.
Also, if you post several image files, make sure that the value of image.context
parameter of the image relevant to the PoA Extraction flow is document-front
, otherwise the PoA Extraction flow will not work.
2.1 Include the API URL and mandatory headers
POST {baseURL}/v1/sessions/{sessionId}/media
Type: object
Headers:
X-AUTH-CLIENT: string (required) = API key
X-HMAC-SIGNATURE: string (required) = sessionId signed with the shared secret key
Content-Type: application/json
2.2 Add the following data into the minimum payload
image
:object
*context
:string
* In this case, it must bedocument-front
content
:string
* Base64 encoded image (.jpg, .jpeg, .png, .heif, .heic, .webp and .pdf formats are supported)
*Required parameter
Request payload sample
curl -X POST \
--url '/v1/sessions/aea9ba6d-1b47-47fc-a4fc-f72b6d3584a7/media' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: 034c6da2bb31fd9e6892516c6d7b90ebe10f79b47cfb3d155d77b4d9b66e1d53' \
-d '{
"image": {
"context": "document-front",
"content": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+.../9fgAEAKcxisFjVfn0AAAAASUVORK5CYII="
}
}'
→ See the POST /sessions/{sessionId}/media[↗] endpoint documentation for further details about how to send media files
3. Update the session status to submitted
using the PATCH /sessions/{sessionId} call
submitted
using the PATCH /sessions/{sessionId} call3.1 Include the API URL and mandatory headers
PATCH {baseURL}/v1/sessions/{sessionId}
Type: object
Headers:
X-AUTH-CLIENT: string (required) = API key
X-HMAC-SIGNATURE: string (required) = sessionId signed with the shared secret key
Content-Type: application/json
3.2 Add the following data (minimum payload)
verification
:object
*status
:string
* Status of the verification session you are patching the session into, alwayssubmitted
*Required parameter
Request payload sample
curl -X PATCH \
--url '/v1/sessions/fd5c1563-1d23-4b1a-ae46-7ba429927ed8' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-H 'X-HMAC-SIGNATURE: dd994f70b1150ae012f9c1d6d20adf7ed69780044835d39de20b00ffae0660a0' \
-d '{
"verification": {
"status": "submitted"
}
}'
Once done, an event webhook with submitted
status will be sent.
Wait for the session to be approved and decision webhook to send response (see the webhook payload subsection below)
Now you can use the following API calls to query the document info:
GET /sessions/{sessionId}/media[↗] to get a list of media objects and address media with the
sessionId
GET /attempts/{attemptId}/media[↗] to get a list of media objects and address media with the attempt ID
GET /media/{mediaId}[↗] to get a media file with the
mediaId
Find the decision and see verified data
You can get the data from three sources:
Receive the decision webhook
Query the results via GET sessions/{sessionId}/decision
View the session in Veriff Customer Portal
Webhook payload
As soon as the session is approved, the decision webhook will send an approved
response. This response will include the session status, as well as all the data that was extracted from the PoA document.
Below is an explanation and a sample of a decision webhook payload for a PoA Extraction session. The decision webhook is used for many purposes, to find more info about it, see the decision webhook documentation.
Sample request
{
"status": "success",
"verification": {
"id": "ab1c2345-678d-4e3b-98a3-a75b00b715kj",
"attemptId": "c6cab5b0-c506-47a6-922d-6ae3b72ca172",
"code": 9001,
"person": {
"gender": null,
"idNumber": null,
"lastName": "null",
"addresses": [
{
"fullAddress": "Jaan Koorti 777,
99999 Tallinn, Estonia"
}
],
"firstName": "Jane Doe",
"citizenship": null,
"dateOfBirth": null,
"nationality": null,
"yearOfBirth": null,
"placeOfBirth": null,
"pepSanctionMatch": null
},
"reason": null,
"status": "approved",
"comments": [],
"document": {
"type": null,
"number": null,
"country": null,
"validFrom": "2022-11-25",
"validUntil": null
},
"reasonCode": null,
"vendorData": "11111111",
"endUserId": null,
"decisionTime": "2023-01-23T10:31:05.293000Z",
"acceptanceTime": "2023-01-23T10:25:40.026Z",
"additionalVerifiedData": {
"proofOfAddress": {
"nameMatch": true,
"nameMatcPercentage": 100.00,
"documentType": "UTILITY_BILL"
},
},
}
"technicalData": {
"ip": null
}
Request properties explained
*Required field
status
:string
* Status of the responseverification
:object
* Verification request decision object.null
if decision is not available yetid
:string
* UUID v4 which identifies the verification sessionattemptId
:string
* UUID v4 of the attempt which received a status (as shown inverification.status
field)vendorData
:string | null
* The unique identifier that you created for your end-user.null
if not specifiedendUserId
:string | null
* TheUUID
that you created for your end-user.null
if not specifiedstatus
:string
* Verification status, one ofapproved
,declined
,resubmission_requested
,review
,expired
,abandoned
code
:integer
* Verification session decision code, one of9001
,9102
,9103
,9104
,9121
. For more info, see the verification session decision codesreason
:string | null
* Reason why the verification failedreasonCode
:integer | null
* Reason code of the failed verification. For more info, see the possible codes for a failed verificationdecisionTime
:string
* Timestamp of the decision, represented asUTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset
(ISO 8601)acceptanceTime
:string
* Timestamp of the session generation, represented asUTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset
(ISO 8601)person
:object
* Data about the verified persongender
:string | null
* Person’s gender, represented as M or F, ornull
if not presentidNumber
:string | null
* National identification numberlastName
:string | null
*null
, unless prefilled by the customeraddresses
:array
* Array of person's addressesfullAddress
:string
Address as a single string
firstName
:string | null
* Person's first name as written on the document, if availabledateOfBirth
:string
* Person’s date of birth, represented asYYYY-MM-DD
nationality
:string | null
* Person's nationalityyearOfBirth
:string | null
* Person’s year of birth, represented asYYYY
placeOfBirth
:string | null
* Person's place of birthpepSanctionMatch
:string | null
* Legacy field, may return incorrect result, should be ignoredcitizenship
:string | null
* Deprecated, always returns null
document
:object
* Verified documenttype
:string | null
Document typenumber
:string | null
Document number,[a-zA-Z0-9]
characters onlycountry
:string | null
* Document issuing country, represented as ISO 3166alpha-2
codevalidUntil
:string | null
Document is valid until date, represented asYYYY-MM-DD
. Optional, must be configured for your integration by the Solutions EngineervalidFrom
:string | null
Document is valid from date, represented asYYYY-MM-DD
. Optional, must be configured for your integration by the Solutions Engineer
additionalVerifiedData
:object
* Data which has been optionally verified for sessionproofOfAddress
:object
Proof of address data. Optional, available only if the name match check has been enabled for the integrationnameMatch
:boolean
Indicates if the name on the proof of address document matches the name from the initial request data.null
if the check could not be completed.nameMatchPercentage
:float
Indicates the level of similarity the matched names have, in the range of 0.00-100.00.null
if the check could not be completed.documentType
:string
Indicates the type of the proof of address document.null
if the check could not be completed.
comments
:array
* (Deprecated)
technicalData
:object
* Technical dataip
:string | null
IP of the device from which the verification was made
API call
You can use the GET sessions/{sessionId}/decision[↗] endpoint to get the decision data.
Below is an explanation and a sample of the API call payload for a PoA Extraction session. The endpoint is used for many purposes, to find more info about it, see the GET sessions/{sessionId}/decision[↗] documentation.
Sample response
{
"status": "success",
"verification": {
"id": "ab1c2345-678d-4e3b-98a3-a75b00b715kj",
"attemptId": "c6cab5b0-c506-47a6-922d-6ae3b72ca172",
"code": 9001,
"person": {
"gender": null,
"idNumber": null,
"lastName": "null",
"addresses": [
{
"fullAddress": "Jaan Koorti 777,
99999 Tallinn, Estonia"
}
],
"firstName": "Jane Doe",
"citizenship": null,
"dateOfBirth": null,
"nationality": null,
"yearOfBirth": null,
"placeOfBirth": null,
"pepSanctionMatch": null
},
"reason": null,
"status": "approved",
"comments": [],
"document": {
"type": null,
"number": null,
"country": null,
"validFrom": "2022-11-25",
"validUntil": null
},
"reasonCode": null,
"vendorData": "11111111",
"endUserId": null,
"decisionTime": "2023-01-23T10:31:05.293000Z",
"acceptanceTime": "2023-01-23T10:25:40.026Z",
"additionalVerifiedData": {
"proofOfAddress": {
"nameMatch": true,
"nameMatcPercentage": 100.00,
"documentType": "UTILITY_BILL"
},
},
}
"technicalData": {
"ip": null
}
Response properties explained
status
:string
Status of the responseverification
:object
Verification request decision object.null
if decision is not available yetid
:string
UUID v4 which identifies the verification sessionattemptId
:string
UUID v4 of the attempt which received a status (as shown inverification.status
field)vendorData
:string | null
The unique identifier that you created for your end-user.null
if not specifiedendUserId
:string | null
TheUUID
that you created for your end-user.null
if not specifiedstatus
:string
Verification status, one ofapproved
,declined
,resubmission_requested
,review
,expired
,abandoned
code
:integer
Verification session decision code, one of9001
,9102
,9103
,9104
,9121
. For more info, see the verification session decision codesreason
:string | null
Reason why the verification failedreasonCode
:integer | null
Reason code of the failed verification. For more info, see the possible codes for a failed verificationdecisionTime
:string
Timestamp of the decision, represented asUTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset
(ISO 8601)acceptanceTime
:string
Timestamp of the session generation, represented asUTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset
(ISO 8601)person
:object
Data about the verified persongender
:string | null
Person’s gender, represented as M or F, ornull
if not presentidNumber
:string | null
National identification numberlastName
:string | null
null
, unless prefilled by the customeraddresses
:array
Array of person's addressesfullAddress
:string
Address as a single string
firstName
:string | null
Person's first name as written on the document, if availabledateOfBirth
:string
Person’s date of birth, represented asYYYY-MM-DD
nationality
:string | null
Person's nationalityyearOfBirth
:string | null
Person’s year of birth, represented asYYYY
placeOfBirth
:string | null
Person's place of birthpepSanctionMatch
:string | null
*Legacy field, may return incorrect result, should be ignoredcitizenship
:string | null
Deprecated, always returns null
document
:object
Verified documenttype
:string | null
Document typenumber
:string | null
Document number,[a-zA-Z0-9]
characters onlycountry
:string | null
Document issuing country, represented as ISO 3166alpha-2
codevalidUntil
:string | null
Document is valid until date, represented asYYYY-MM-DD
. Optional, must be configured for your integration by the Solutions EngineervalidFrom
:string | null
Document is valid from date, represented asYYYY-MM-DD
. Optional, must be configured for your integration by the Solutions Engineer
additionalVerifiedData
:object
Data which has been optionally verified for sessionproofOfAddress
:object
Proof of address data. Optional, available only if the name match check has been enabled for the integrationnameMatch
:boolean
Indicates if the name on the proof of address document matches the name from the initial request data.null
if the check could not be completed.nameMatchPercentage
:float
Indicates the level of similarity the matched names have, in the range of 0.00-100.00.null
if the check could not be completed.documentType
:string
Indicates the type of the proof of address document.null
if the check could not be completed.
comments
:array
(Deprecated)
technicalData
:object
Technical dataip
:string | null
IP of the device from which the verification was made
Veriff Customer Portal
You can find the verification session related info, including uploaded images, in the Veriff Customer Portal, by opening the session on the All Verifications page.
→ See Review verification in Veriff Customer Portal about how to view the session info in the Veriff Customer portal
Optional Proof of Address name match check
Note that the name match check is not performed by default, it needs to be configured for your integration.
Please ask your Solutions Engineer to configure the feature for your integration.
In order to do the Proof of Address name match check, you can add the optional parameters person.firstName
and person.lastName
to the POST /sessions request payload.
If the check has been enabled, and you have sent us the first name and last name data, the check will be performed. The results are displayed in decision webhook response, in:
additionalVerifiedData.proofOfAddress
object, more specifically inproofOfAddress.nameMatch
andproofOfAddress.nameMatchpercentage
fields
If the check has been enabled, but you do not send us the name data, the strings will be null
.
Sample POST /sessions request payload
GET {baseURL}/v1/sessions/
Type: object
Headers:
X-AUTH-CLIENT: string (required) = API key
Content-Type: application/json
curl -X POST \
--url '/v1/sessions/' \
-H 'Content-Type: application/json' \
-H 'X-AUTH-CLIENT: API-PUBLIC-KEY' \
-d '{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith",
},
}
}'
Webhook payload
Below is an explanation and a sample of the part of a decision webhook payload relevant to the name match check. To see the full decision webhook response related to Proof of Address check, see the Webhook payload section above.
Sample request
{
"status": "success",
"verification": {
...
"additionalVerifiedData": {
"proofOfAddress": {
"nameMatch": true
"nameMatcPercentage": 100.00
},
},
},
...
}
Request properties explained
status
:string
* Status of the responseverification
:object
* Verification request decision object...
additionalVerifiedData
:object
* Data which has been optionally verified for sessionproofOfAddress
:object
* Proof of address datanameMatch
:boolean | null
* Indicates if the name on the proof of address document matches the name from the initial request data.null
if the check could not be completed.nameMatchPercentage
:float| null
* Indicates the level of similarity the matched names have, in the range of 0.00-100.00.null
if the check could not be completed.
...
*Required field
Note about PDF support
Legacy PoA Extraction solution supports PDF file uploads.
Contact your solutions engineer for info and configuration.
The file that is uploaded for Proof of Address flow must contain only one PoA document. If you need to send several PoA documents, upload them one-by-one in separate PDF files.
For PoA, documents can be uploaded in following configurations:
Single PDF file, where the document data is on one page
Single PDF file, where the document data spans over several pages
Veriff processes first 5 pages of uploaded PDF file. System removes empty pages from the PDF.
Article versioning
Date | Description |
---|---|
May 2, 2025 | Documentation marked as legacy solution as new Proof of Address Verification solution is now available. Note bout PDF support added, as the multi-page PDF upload is supported only by the legacy Proof of Address Extraction |
Mar 12, 2025 | Documentation published |