Proof of Address Extraction

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

  1. Generate a verification session using the authentication integration tokens (check the POST /sessions[↗] endpoint in the API reference)

  2. Capture end-user’s PoA document images with Veriff’s SDKs

    1. Send the end-user through the verification flow to capture the image (using the preferred Veriff SDK)

    2. You need the session URL generated in step 1 to use the SDKs (found in response payload as verification.url)

  3. Session will be submitted automatically once the end-user takes and submits necessary images of their face

  4. 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 be document-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

3.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, always submitted

*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.

  1. Wait for the session to be approved and decision webhook to send response (see the webhook payload subsection below)

  2. Now you can use the following API calls to query the document info:


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 response

  • verification: object* Verification request decision object. null if decision is not available yet

    • id: string* UUID v4 which identifies the verification session

    • attemptId: string* UUID v4 of the attempt which received a status (as shown in verification.status field)

    • vendorData: string | null* The unique identifier that you created for your end-user. null if not specified

    • endUserId: string | null* The UUID that you created for your end-user. null if not specified

    • status: string* Verification status, one of approved, declined, resubmission_requested, review, expired, abandoned

    • code: integer* Verification session decision code, one of 9001, 9102, 9103, 9104, 9121. For more info, see the verification session decision codes

    • reason: string | null* Reason why the verification failed

    • reasonCode: integer | null* Reason code of the failed verification. For more info, see the possible codes for a failed verification

    • decisionTime: string* Timestamp of the decision, represented as UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset (ISO 8601)

    • acceptanceTime: string* Timestamp of the session generation, represented as UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset (ISO 8601)

    • person: object* Data about the verified person

      • gender: string | null* Person’s gender, represented as M or F, or null if not present

      • idNumber: string | null* National identification number

      • lastName: string | null* null, unless prefilled by the customer

      • addresses: array* Array of person's addresses

        • fullAddress: string Address as a single string

      • firstName: string | null* Person's first name as written on the document, if available

      • dateOfBirth: string* Person’s date of birth, represented as YYYY-MM-DD

      • nationality: string | null* Person's nationality

      • yearOfBirth: string | null* Person’s year of birth, represented as YYYY

      • placeOfBirth: string | null* Person's place of birth

      • pepSanctionMatch: string | null* Legacy field, may return incorrect result, should be ignored

      • citizenship: string | null* Deprecated, always returns null

    • document: object* Verified document

      • type: string | null Document type

      • number: string | null Document number, [a-zA-Z0-9] characters only

      • country: string | null* Document issuing country, represented as ISO 3166 alpha-2 code

      • validUntil: string | null Document is valid until date, represented as YYYY-MM-DD. Optional, must be configured for your integration by the Solutions Engineer

      • validFrom: string | null Document is valid from date, represented as YYYY-MM-DD. Optional, must be configured for your integration by the Solutions Engineer

    • additionalVerifiedData: object* Data which has been optionally verified for session

      • proofOfAddress: object Proof of address data. Optional, available only if the name match check has been enabled for the integration

        • nameMatch: 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 data

    • ip: 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 response

  • verification: object Verification request decision object. null if decision is not available yet

    • id: string UUID v4 which identifies the verification session

    • attemptId: string UUID v4 of the attempt which received a status (as shown in verification.status field)

    • vendorData: string | null The unique identifier that you created for your end-user. null if not specified

    • endUserId: string | null The UUID that you created for your end-user. null if not specified

    • status: string Verification status, one of approved, declined, resubmission_requested, review, expired, abandoned

    • code: integer Verification session decision code, one of 9001, 9102, 9103, 9104, 9121. For more info, see the verification session decision codes

    • reason: string | null Reason why the verification failed

    • reasonCode: integer | null Reason code of the failed verification. For more info, see the possible codes for a failed verification

    • decisionTime: string Timestamp of the decision, represented as UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset (ISO 8601)

    • acceptanceTime: string Timestamp of the session generation, represented as UTC YYYY-MM-DDTHH:MM:SS.SSS+Timezone Offset (ISO 8601)

    • person: object Data about the verified person

      • gender: string | null Person’s gender, represented as M or F, or null if not present

      • idNumber: string | null National identification number

      • lastName: string | null null, unless prefilled by the customer

      • addresses: array Array of person's addresses

        • fullAddress: string Address as a single string

      • firstName: string | null Person's first name as written on the document, if available

      • dateOfBirth: string Person’s date of birth, represented as YYYY-MM-DD

      • nationality: string | null Person's nationality

      • yearOfBirth: string | null Person’s year of birth, represented as YYYY

      • placeOfBirth: string | null Person's place of birth

      • pepSanctionMatch: string | null*Legacy field, may return incorrect result, should be ignored

      • citizenship: string | null Deprecated, always returns null

    • document: object Verified document

      • type: string | null Document type

      • number: string | null Document number, [a-zA-Z0-9] characters only

      • country: string | null Document issuing country, represented as ISO 3166 alpha-2 code

      • validUntil: string | null Document is valid until date, represented as YYYY-MM-DD. Optional, must be configured for your integration by the Solutions Engineer

      • validFrom: string | null Document is valid from date, represented as YYYY-MM-DD. Optional, must be configured for your integration by the Solutions Engineer

    • additionalVerifiedData: object Data which has been optionally verified for session

      • proofOfAddress: object Proof of address data. Optional, available only if the name match check has been enabled for the integration

        • nameMatch: 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 data

    • ip: 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 in

    • proofOfAddress.nameMatch and

    • proofOfAddress.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 response

  • verification: object* Verification request decision object

    • ...

    • additionalVerifiedData: object* Data which has been optionally verified for session

      • proofOfAddress: object* Proof of address data

        • nameMatch: 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