Getting started with Name Verifcation

Lean Name Verification API illustration

Overview

This guide will help you to connect your customer's bank account in order to verify that the name your customer has provided to you matches the name from the bank account connected. This will help you ensure that the payments you receive comes directly from a bank account owned by the customer for which you have confirmed through your KYC process.

The Name Verification will compare a name you provide through the API call to the name the bank has on record for the account holder. The response will include both the raw name retrieved from the bank account and give a suggestion on the closeness of the match between both names.


Create a Customer

To start using the Name Verification API, you first need to create a Customer resource. This creates a relationship between your application, user and all the services they consume within Lean into a single object. If you are using Lean's Data or Payments API with the name verification feature you will likely already have Customer object.

To create a Customer, call the /customers/v1 endpoint with a reference to your app_user_id. You should save the returned customer_id against your user table for future reference.

Please note: app_user_id has a unique constraint, but does not need to map directly to the id of the user in your database, for example you could pass prod_usr_1246 as the app_user_id, so that you can identify that the Customer is a user of your production database. In this case, you should save both the customer_id and app_user_id against your user table for later retrieval and mapping.

Call

bash

curl -X POST 'https://sandbox.leantech.me/customers/v1/' \
--header 'Content-Type: application/json' \
--header 'lean-app-token: YOUR_APP_TOKEN' \
--data-raw '{
"app_user_id": "your_customer_identifier"
}'

Response

json

{
"app_user_id": "your_customer_identifier",
"customer_id": "f08fb010-878f-407a-9ac2-a7840fb56185"
}

Create an Entity

An Entity maps to a user's entire relationship with a specific bank. You will need to decide on the permissions you want to gain consent for from your customer during the linking process.

If you are already using Lean's Data API or are using the Payments API along with the Connect function of the Link SDK you should already have an entity created for your customer and can skip to the "Verify your customer's name" section. If not you can create an entity by following the instructions below.

An example Entity object will look like this:

json

{
"id": "f6dcc0ae-20c6-318c-bdba-49fb2ced41ce",
"customer_id": "6bc2336a-6d74-4e59-a492-65313423a8f8",
"bank_identifier": "ENBD_UAE",
"permissions": {
"identity": true,
"accounts": false,
"balance": false,
"transactions": false
}
}

Front-end

Entities are created by first calling the Lean.link() method in the LinkSDK in your front-end. In order to make a .link() call you need to provide the permissions for the endpoints you want to make calls for, your app_token and a customer_id. To use the Name Verification API you will need the identity permission.

Please see https://docs.leantech.me/link-sdk for more details on integrating the Link SDK into your application and additional functionality.

javascript

// page.html
<button onClick={linkAccount([customer_id])}>Link Account</button>
// script.js
function linkAccount = (customer_id) => {
Lean.link({
app_token: "YOUR_APP_TOKEN",
customer_id: "customer_id",
permissions: ["identity"],
sandbox: "false",
})
}

If you will be using the Payments API as well as the Name Verification API you should be using the Link SDK's Connect flow and specifying the permissions asked for as identity and payments. The call for the Connect function in this case would look like this:

javascript

// page.html
<button onClick={connectAccount([customer_id])}>Connect Account</button>
// script.js
function connectAccount = (customer_id) => {
Lean.connect({
app_token: "YOUR_APP_TOKEN",
customer_id: "customer_id",
permissions: ["identity", "payments"],
payment_destination_id: "9dd4fd55-8f45-44c9-9f73-08433badb2c1",
sandbox: "false",
})
}

When a customer completes the LinkSDK - please note, no details are shared directly from the SDK to your front-end. A Success, Error or Cancelled message can be returned from the SDK via a callback (depending on the platform you're integrating with, this is handled differently) in the following format:

json

{
status: "SUCCESS",
method: "LINK",
message: "Customer created entity successfully"
}

The details of your newly created entity will instead be sent via a webhook to your backend services. Your front-end should therefore handle the success by making a call to your backend to refresh the data. Webhooks are only sent upon successful entity creation, if the creating is unsuccessful the Link SDK will prompt the use to try again and advise the user on how to connect successfully the next time. A successful entity.created webhook looks like this:

json

{
"payload": {
"id": "f6dcc0ae-20c6-318c-bdba-49fb2ced41ce",
"customer_id": "6bc2336a-6d74-4e59-a492-65313423a8f8",
"app_user_id": "your_customer_identifier",
"permissions": ["identity"],
"bank_details": {
"name": "Emirates NBD",
"identifier": "ENBD_UAE",
"bank_type": "RETAIL",
"logo": "https://cdn.leantech.me/img/bank-assets/uae/glyphs/nbd/g-white-nbd_uae.png",
"main_color": "#06357A",
"background_color": "#ffffff"
}
},
"type": "entity.created",
"message": "An entity object has been created.",
"timestamp": "2021-06-22T09:15:40.1854Z",
"event_id": "f5ba996d-9a7b-479d-a244-e970334c7d99"
}

Backend

When a customer successfully links their bank with your application a webhook is sent back to your application:

json

{
"type": "entity.created",
"message": "An entity object has been created.",
"payload": {
"id": "f08fb010-878f-407a-9ac2-a7840fb56185",
"customer_id": "6bc2336a-6d74-4e59-a492-65313423a8f",
"permissions": ["transactions", "balance", "identity", "accounts"],
"bank_details": {
"name": "Emirates NBD",
"identifier": "ENBD_UAE",
"logo": "https://cdn.leantech.me/img/banks/white-lean.png",
"main_color": "#1beb75",
"background_color": "#001E26"
}
},
"timestamp": "2020-10-10T17:19:00.059933Z"
}

The new Entity details can be found under payload in the received webhook. It is up to you which details from this webhook you decide to save to your database, but at the minimum we suggest you save the entity_id for future use.

It's also worth noting that a user can have multiple connected Entities - one for each bank they have an account for.


Verify your customer's name

Once you have an entity_id you can now make calls to the insights/v1/name-verification endpoint.

Please note: backend calls in production are authenticated via certificates with mTLS.

json

// Identity Call - PERFECT_MATCH
curl -X POST 'https://sandbox.leantech.me/insights/v1/name-verification' \
--header 'Content-Type: application/json' \
--header 'lean-app-token: YOUR_APP_TOKEN' \
--data-raw '{
"entity_id": "f08fb010-878f-407a-9ac2-a7840fb56185",
"full_name": "Michael Garry Scott",
"async": "False"
}'
// Name Verification Response
{
"status": "OK",
"payload": {
"full_name_provided": "Michael Garry Scott",
"full_name_retrieved": "Michael Garry Scott",
"match_type": "PERFECT_MATCH",
"confidence": 1.0
}
}

In the above example, the name provided was a PERFECT_MATCH with the name of the account holder we retrieved from the bank. A PERFECT_MATCH is returned when the name provided identically matches the spelling and order of the name retrieved from the bank. Any salutation (eg. Mr., Mrs., Dr., etc.) will be ignored in the comparison.

In the scenario where the name retrieved is similar but not identical, we will return a match level of PARTIAL_MATCH. This will happen in cases where the names compared is deemed to be a variable spelling of each other, such as "Mohammed" and "Muhammad" or if either the name provided by you in the API request contains an initial whereas the name retrieved by the bank has the full name e.g. "Michael G Scott" compared to "Michael Garry Scott". This is shown below.

json

// Identity Call - PERFECT_MATCH
curl -X POST 'https://sandbox.leantech.me/insights/v1/name-verification' \
--header 'Content-Type: application/json' \
--header 'lean-app-token: YOUR_APP_TOKEN' \
--data-raw '{
"entity_id": "f08fb010-878f-407a-9ac2-a7840fb56185",
"full_name": "Michael G Scott",
"async": "False"
}'
// Name Verification Response
{
"status": "OK",
"payload": {
"full_name_provided": "Michael G Scott",
"full_name_retrieved": "Michael Garry Scott",
"match_type": "PARTIAL_MATCH",
"confidence": 0.75
}
}

If no match is found between the name provided and the name retreived from the bank, the match_type will be returned as NO_MATCH. This will happen when only one or none of the tokens within the provided and retreived names match in spelling.


Handle reconnection OTPs

When making a call to the name-verification endpoint, user verification may be required before the request can be completed (for example, an OTP or updated user credentials may be required).

When this happens, a RECONNECT_REQUIRED response will be returned:

json

{
"status": "RECONNECT_REQUIRED",
"payload": {
"reconnect_id": "20afcfd3-7ee3-44b8-9d6e-bf74b259fb90",
"type": "reconnect"
},
"results_id": "fae0ff1b-b0b7-481d-9c0a-533e0abfc798",
"message": "User input is required to reconnect with the bank",
"timestamp": "2020-12-30T16:40:49.779695Z"
}

When this happens the reconnect_id should be passed to your front-end and initialised through the LinkSDK like so:

javascript

Lean.reconnect({
app_token: "2c9a80897169b1dd01716a0339e30003",
reconnect_id: "20afcfd3-7ee3-44b8-9d6e-bf74b259fb90",
sandbox: "false"
});

Once the user has successfully reconnected their account, a webhook notifying you of successful reconnection will be sent, as well as a results.ready webhook allowing you to pick up the originally requested data.

json

// Entity Reconnected webhook.
{
"type": "entity.reconnected",
"payload": {
"id": "a2533394-6fcb-4407-989d-c35e96f34aa3" // the entity_id
"reconnect_id": "6222a07e-3aa8-42ba-87df-0ef989f36d19"
}
"message": "The entity was successfully reconnected.",
"timestamp": "2021-01-08T18:05:19.244672Z"
}
// Results webhook to fetch your originally requested data.
{
"type": "results.ready",
"payload": {
"id": "9b8ab652-cc95-4fb2-9340-59b0164c8fb2", // results_id
}
"message": "Your results are ready.",
"timestamp": "2021-01-08T18:05:19.244672Z"
}

Handle Asynchronous requests

When dealing with large amounts of data resulting in a timeout, or when a request is specified to be asynchronous ("async": "True") - Lean will fallback to an asynchronous workflow. You will notice in the example above, the request was specified to be synchronous. This was done to make this guide easier to follow but by default, if the async variable is undefined, the request will be treated asynchronously, it is highly recommended that you handle these requests asynchronously since banks will sometimes take a long time to process the request for the name.

When a request is specified to be asynchronous, our response to your request will have a status of PENDING and a results_id.

json

{
"status": "PENDING",
"results_id": "6dd9c7d2-1c8c-4862-bb1f-fcf52f5033d4",
"message": "Results not yet returned. Please try again later",
"timestamp": "2020-07-31T07:11:39.862804Z"
}

When the request has been fully processed in our system, a webhook will be sent to your system with a type of results.ready

json

{
"type": "results.ready",
"payload": {
"id": "6dd9c7d2-1c8c-4862-bb1f-fcf52f5033d4", // results_id
}
"message": "Your results are ready.",
"timestamp": "2021-01-08T18:05:19.244672Z"
}

You can now fetch your results with a GET request with the results_id provided as a query parameter:

bash

curl -X GET 'https://sandbox.leantech.me/v1/results/6dd9c7d2-1c8c-4862-bb1f-fcf52f5033d4' \
--header 'Content-Type: application/json' \
--header 'lean-app-token: YOUR_APP_TOKEN' \