Overview

To use the services, end users have to authenticate themselves and grant access to information from a "Provider" (i.e. a financial institution). First, we need to create an auth url and redirect the user to that url. Then a code from callback should be exchanged for a long-live access token. Bisnode will collect data of the user and apply analytics. The type of returned data depends on the requested scope during authentication. Scopes can be changed in a re-authentication process later if needed.

Bisnode PSD2 Authentication Flow

When a user wants to share their bank account information through the service, the Bisnode PSD2 Authentication Flow interface must be used. We construct a URL containing integration parameters. There are additional optional parameters that can be used for customisation. One is iframe support. The user selects provider and performs the authentication and grants access. Bisnode starts to download the data from the provider, and the user is shown a waiting page during this time. When the download is complete and the data is available for use from Bisnode, the user is redirected back (or we get a postMessage in case of iframe) with a short lived authorization code. The code can then be exchanged for an access token using an API endpoint with Bisnodes confidential credentials. The access token can then be used to query the various Bisnode endpoints.

 

 Get started

You'll need 3 things to get started.

  • Bisnode ID (contact api-support@bisnode.com for one if you don't have it yet)
  • Sandbox API Key (you need to be logged in with your Bisnode ID to get it)
  • Subscribe to the API (you need to be logged in with your Bisnode ID to subscribe)
Refer to Docs for more details

Ready to start?

Get API Key

Documentation

How to use the API

This guide is intended to help you get going with your integration against the Bisnode PSD2 API. It serves as a complement to the  Endpoint Reference  and aims to bring a high level understanding of the key concepts of the platform. 

For questions and support, please contact Bisnode at api-support@bisnode.com

 

Changes and versioning

API version is provided in the base of the requested URL in the form of "v1", "v2" etc. Only major version numbers are used.

API versions are raised only on breaking (i.e. backwards incompatible) changes in the API. Fields may be added but will never be removed during an API version lifecycle. When developing your application, take care to ensure that your application is able to handle additional fields.

 

Authentication 

 

Authentication using OAuth2

Bisnode's newest APIs use OAuth2 for authentication. For all API requests, you need to supply an access token in order to authenticate yourself. To obtain such an access token you need to submit your CLIENT_ID and CLIENT_SECRET to Bisnode's authentication endpoint at https://login.bisnode.com/as/token.oauth2. The access token is then passed along in the Authorization header to all API requests. Follow the instructions below to learn how to do this.

 

Get and Use the Bisnode Access Token

Step 1. Get the Access Token

To get an access token you need to make a POST request to https://login.bisnode.com/as/token.oauth2 using the following HTTP header: Content-Type: application/x-www-form-urlencoded and the following request body: grant_type=client_credentials&scope=psd2. The request must be authenticated using HTTP Basic authentication and your CLIENT_ID and CLIENT_SECRET.

Example in cURL
curl -X POST \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d 'grant_type=client_credentials&scope=psd2' \
     -u "$CLIENT_ID:$CLIENT_SECRET" \
     https://login.bisnode.com/as/token.oauth2
 
Example response
{
  "access_token": "eyJhb....seAtPCCQ",
  "token_type": "Bearer",
  "expires_in": 7199
}
 
Step 2. Use the Access Token

Supply your access token with all requests to the API using the HTTP Authorization header: Authorization: Bearer <your access token here> You should reuse the access token for multiple calls to the API. See the next section on recommended usage.

 
Example in cURL 
curl -X POST \
     -H "Authorization: Bearer eyJhb...seAtPCCQ" \
-H 'Content-Type: application/json' \ https://api.bisnode.com/psd2/v1/account/statistics


Reusing the Access Token

After you have fetched an access token you should save it and use it for subsequent calls to the API. There is no limit on the number of calls it can be used for, but it will expire after a certain time.

We recommend that you use the expires_in field to determine when to request a new access token. It specifies the number of seconds the token will be valid for. Because of possible delays in network communication as well as delays between checking the timestamp and transmitting the actual API request, it is a good idea to request a new token a few seconds before it is about to expire. This minimizes the risk of accidentally using an expired token.

The following pseudo code illustrates how to use the authentication endpoint together with the API.

function make_authorized_api_request():
    token = get_cached_access_token()
    if token == null or is_soon_to_be_expired(token):
        token = get_new_access_token()
        save_to_cache(token)
    make_api_call(token)


function get_new_access_token():
    token = get_token_from_auth_endpoint()
    token.expiration_timestamp = now().add_seconds(token.expires_in)
    return token


function is_soon_to_be_expired(token):
    # Add time margin to avoid token expiring during call
    if now().add_seconds(60) >= token.expiration_timestamp:
        return true
    return false

 

Provided data in API

In our API we provide data of end-user transactions and statistics. Transactions can be queried for some category/categories in specified date range. Response contains list of all end-user transactions which belongs to given categories. Statistics can be also queried for some category, but instead of date range, it requires list of periods. Response contains in these periods summary of all transactions that belongs to one specific category. It might be better to use statistics data for income verification.

These categories can be queried in our API:

  income
  parent category
  income-salary
  leaf category
  income-financial
  leaf category
  income-pension
  leaf category
  income-refund
  leaf category
  income-other
  leaf category
  income-benefits
  leaf category
  expenses
  parent category


Note:
Only leaf category can be used for statistics. 

 

Income verification flow

Step 1

As the first step, user has to give us his consent and authenticate himself / herself against a financial institution. This can be achieved by embedding Bisnode's authentication flow as a web link or iframe.

The aim of this step is to retrieve the short lived authentication code which must be exchanged for authorization token.

 

For the testing purposes, select "Test Password" and use "tink" as the user authorized by "tink-1234" password.

 

Step 1.a. - iframe

 

<iframe src="https://ais.bisnode.com/psd2-auth-web/v1/auth?redirect_uri=CALLBACK_URL&iframe=true">

When using the iframe solution, the code is sent via the postMessage method to the parent window.

The CALLBACK_URL is used as the target origin when sending message via postMessage.

The code can be retrieved by adding event listener to your site, the page which is embeding the iframe.

 

window.addEventListener('message', (event) => {
if (event.origin !== 'https://ais.bisnode.com') {
return;
}

const data = JSON.parse(event.data);

const { success } = data;

if (success) {
const { payload: { code }} = data;

// Use the code to exchange for authentication
console.log('Auth code is', code);
}

console.log(event);
}, false);

 

Step 1.b. - web link

 

The link can be used as a simple href link as well:

 

<a href="https://ais.bisnode.com/psd2-auth-web/v1/auth?redirect_uri=CALLBACK_URL">

 

The difference is that we are ommiting the iframe=true parameter and that the end user will be redirected back to your CALLBACK_URL instead of sending window.postMessage.

Once the user is authenticated against the bank account, he/she is brought back to your site with the code as part of CALLBACK_URL GET parameter (CALLBACK_URL?code=<your code will be here>).

For testing purposes we can set the CALLBACK_URL to http://localhost/callback, the callback will result in the "Page was not found" error if there is no web server running on the localhost, but everything you need is the code from the url. Try it out!

 

The resulting code is used for exchanging an access token in the next step.

 

Step 2

After a successful user authentication, your application will have a code available (from the previous step). This code needs to be exchanged at /token endpoint.

Note:
Every subsequent calls also must have a  Authorization: Bearer eyJhb...seAtPCCQ header. See Authentication section above.

GET /token
Token query parameters:

Key Value Description
code 4gdfg654edr89tg7e4gh654sdf654 The code from callback

response:

{
    "token": {
        "accessToken": "eyJhbGciOiJFUzI1NiIsImtpZCI6IjMxOWRjYTQx79MwMGItNDBmZi1hYzY4LTFiNzFjYmEwZjZkMCIsInR5cCI6IkpXVCJ9.e4pleHAiOjE1ODc2MzQzOTEsImlhdCI6MTU4NzYyNzE5MSwiaXNzIjoidGluazovL2F1dGgiLCJqdGkiOiJlNWY2MzdmYy0yZTMxLTQwNTktYWYyZi1jNzk4MDk5OTVhMDUiLCJvcmlnaW4iOiJtYWluIiwic2NvcGVzIjpbImNhdGVnb3JpZXM6cmVhZCIsInN0YXRpc3RpY3M6cmVhZCIsImFjY291bnRzOnJlYWQiLCJ0cmFuc2FjdGlvbnM6cmVhZCJdLCJzdWIiOiJ0aW5rOi8vYXV0aC91c2VyLzZjNGY1YTE2NjBjZDRhMGFhMmMxZWFkY2E1NmQxYzM0IiwidGluazovL2FwcC9pZCI6ImUxMTJiYjQ3YzI3YzRmN2FiMGZjMDg3ZGRlNzM5ZjY5In0.fKhJtCK8cAciV2ajmVbTTzMRJy0snpmsOviJ023MHreFwOagbhpX3ItSuwzGjg7ecaNfK-h5METJrFTG-odg4A",
        "tokenType": "bearer",
        "expiresIn": 7200,
        "refreshToken": "4cf6c2ec3f6641ad855095fda6dbded8",
        "scope": "categories:read,statistics:read,accounts:read,transactions:read"
    }
}
 
Step 3

With this JWT access token we can fetch data from "Provider" APIs. For income verification flow, we can use /account/statistics?category=income-salary. This Endpoint needs to specify period, which is multi-value query parameter. Each value represents one period. Period can be year or month. The response contains summary of all transactions in each period that belongs to specific category.

 

GET /account/statistics
Headers:

Key Value Description
psd2-token eyJhbGciOiJFUzI1NiIsImtpZ... The JWT token from /token endpoint

Query parameters:

Key Value Description
periods 2020-03  
periods 2020-02  
periods 2020-01  
periods 2019  
category income-salary  Salary for income verification
category income-pension  Just example of another category (not needed for income verification)

 

 Response:

{
"income-salary": {
"periods": [
{
"period": "2019-05",
"type": "income-by-category",
"value": 10500.0
},
{
"period": "2019-09",
"type": "income-by-category",
"value": 10500.0
},
{
"period": "2019-12",
"type": "income-by-category",
"value": 10500.0
},
{
"period": "2019-08",
"type": "income-by-category",
"value": 10500.0
}
]
},
"income-pension": {...}
}
 

 

 

List of transactions can be found in /account/transactions.

Example query

GET /account/transactions
Headers:

Key Value Description
psd2-token eyJhbGciOiJFUzI1NiIsImtpZ... The JWT token from /token endpoint

Query parameters:

Key Value Description
category income  List of all categories
startDate 2020-07-24  Start of range in yyyy-MM-dd format
endDate 2020-01-24  End of range in yyyy-MM-dd format
limit 5 Pagination parameter
offset 0 Pagination parameter
sort DATE:DESC Available: DATE, DESCRIPTION, AMOUNT, CATEGORY

 Example response:

{
"metrics": {
"COUNT": "1106",
"NET": "-5046376.59",
"SUM": "5172376.59",
"AVG": "4676.651528028933"
},
"transactions": [
{
"amount": -41256.0,
"date":"2019-07-27T10:00:00",
"inserted": "2019-07-27T10:00:00",
"lastModified": "2019-07-27T10:00:00",
"description": {
"info": "Apple Retail",
"type": "EXPENSES",
"primaryName": "Shopping",
"secondaryName": "Electronics"
},
"currencyDenominatedAmount": {
"unscaledValue": -412560,
"scale": 1,
"currencyCode": "SEK"
},
"currencyDenominatedOriginalAmount": {
"unscaledValue": -412560,
"scale": 1,
"currencyCode": "SEK"
}
},
...
]
}

 

 

Below you can find all endpoints. Each endpoint is documented and has example in curl. 

 

API Console

Production Endpoints

Production URLs:
https://api.bisnode.com/psd2/v1

Sandbox Endpoints

Sandbox URLs:
https://sandbox-api.bisnode.com/psd2/v1

Get Access

Please find the complete reference of the API below. In future releases it will also be possible to try the API out directly from your browser.