Getting started with Data

Lean Data API illustration

Overview

This guide will help you to start connecting your customer's bank accounts to your application, so that you can query data from their financial institutions. With Lean's Data API you can retrieve Account and Identity details, Balances and up to 3 years of Transaction history.


Create a Customer

In order to start fetching data, 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.

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": "IDENTIFIER_FOR_CUSTOMER"
}'

Response

json

{
"app_user_id": "IDENTIFIER_FOR_CUSTOMER",
"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.

An example Entity object will look something like the following:

json

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

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.

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])}>Connect Account</button>
// script.js
function linkAccount = (customer_id) => {
Lean.link({
app_token: "YOUR_APP_TOKEN",
customer_id: customer_id,
permissions: ["identity","accounts","balance","transactions"]
})
}

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.

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.


Fetch Identity & Account data

Once you have an entity_id you can now make calls to the data/v1/identity and data/v1/accounts endpoints.

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

json

// Identity Call
curl -X POST 'https://sandbox.leantech.me/data/v1/identity' \
--header 'Content-Type: application/json' \
--header 'lean-app-token: YOUR_APP_TOKEN' \
--data-raw '{
"entity_id": "f08fb010-878f-407a-9ac2-a7840fb56185"
}'
// Identity Response
{
"full_name": "John Doe",
"mobile_number": "07849720842",
"gender": "male",
"national_identity_number": "123456789",
"birth_date": "1990-09-15",
"email_address": "sandboxuser1@leantech.me",
"address": "140 Tabernacle Street, Shoreditch EC2A 4SD"
}

bash

// Accounts Call
curl -X POST 'https://sandbox.leantech.me/data/v1/accounts' \
--header 'Content-Type: application/json' \
--header 'lean-app-token: YOUR_APP_TOKEN' \
--data-raw '{
"entity_id": "f08fb010-878f-407a-9ac2-a7840fb56185"
}'
// Accounts Response
[
{
"account_id": "3d586d40-04d9-4657-80b7-65bb8cce1e9a",
"name": "Mockbank1 Checkings Account",
"currency_code": "SAR",
"type": "Checkings",
"iban": "SA03 8000 0000 6080 1016 7519",
"bank_identifier": "LEANMB1"
}, {
"account_id": "3e9e4289-9e4f-480f-af68-3181cb35218e",
"name": "Mockbank1 Savings Account",
"currency_code": "SAR",
"type": "Savings",
"iban": "SA03 8000 0000 6080 1635 2788",
"bank_identifier": "LEANMB1"
}
]

After making an accounts call you should save the id field from the response, as this will be used to make Balance and Transaction calls on the associated accounts.


Fetch Balance and Transaction data

Once you have an account_id for a specific account, you can now make calls for balance and transaction data.

Balance returns an overview of the cash position and type of the account.

Transactions returns an array of transaction objects, you can also request for this to be returned with categorization with the insights: true flag.

Balance Call & Response

bash

// Call
curl -X POST 'https://sandbox.leantech.me/v1/balance' \
--header 'Content-Type: application/json' \
--header 'lean-app-token: YOUR_APP_TOKEN' \
--data-raw '{
"entity_id": "f08fb010-878f-407a-9ac2-a7840fb56185",
"account_id": "01bb8b3f-8462-470b-b2ed-14eb15b95fa2"
}'
// Response
{
"balance": 15035.85,
"currency_code": "SAR",
"account_id": "01bb8b3f-8462-470b-b2ed-14eb15b95fa2",
"account_name": "Mockbank1 Checkings Account",
"account_type": "Checkings"
}

Transactions Call & Response

bash

// Call
curl -X POST 'https://sandbox.leantech.me/v1/transactions' \
--header 'Content-Type: application/json' \
--header 'lean-app-token: YOUR_APP_TOKEN' \
--data-raw '{
"entity_id": "f08fb010-878f-407a-9ac2-a7840fb56185",
"account_id": "01bb8b3f-8462-470b-b2ed-14eb15b95fa2",
"start_date": "2020-03-01",
"end_date": "2020-03-15",
"insights": true
}'
// Response
{
"status": "OK",
"payload": {
"transactions": [
{
"id": "01e39a9c-a4ff-3429-a079-968ad1bbb0a3",
"description": "ALETIHAD CREDIT BUREAU ABU DHABI AE",
"amount": 84685.18,
"currency_code": "AED",
"pending": false,
"timestamp": "2021-01-31T00:00:00Z",
"insights": {
"description_cleansed": "ALETIHAD CREDIT BUREAU ABU DHABI AE",
"category": "LOANS_AND_INVESTMENTS",
"category_confidence": 0.99,
"type": "TRANSFER",
"type_confidence": 1
}
}
]
}
}

Handle reconnection OTPs

When making a call to accounts, balance, identity and transactions endpoints, 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 like so:

javascript

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

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 asked for specifically to be asynchronous - Lean will fallback to an asynchronous workflow.

When this happens instead of returning a payload, 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 requirements of this request have been satisfied, 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:

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' \