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.

  
Authentication
To use PSD2, you need a client ID and a secret. Bisnode uses OAuth2 for authentication. More information here.
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)
For easy access we have provided you with a postman collection here.
Technical documentation
Please check our technical documentation for our API here.
 
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

 

Provided data in API

In our API we provide data of end-user transactions. Transactions can be queried for some category/categories in the specified date range. The response contains a list of all end-user transactions which belong to given categories. If you request parent or root category, the response would include also all subcategories.

Our API provides information on both income and expenses. More detailed information is described here

 

PSD2 data process flow

Step 1

As the first step, the 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 an iframe, a web link, or redirection to the provider.

The aim of this step is to retrieve the short-lived authentication code which must be exchanged for an 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-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&mode=iframe">

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 messages via postMessage.

When no CALLBACK_URL is used or CALLBACK_URL is localhost, then is user redirected to the default landing page after successful login, and postMessage is sent there.

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

The APPLICATION_ID is used for verification of redirect_uri and it is mandatory. For getting APPLICATION_ID, contact our team and provide us your redirect CALBACK_URL (it also can be more than one). We will generate a unique APPLICATION_ID for you.

When the user is successfully logged in postMessage contains success: true and in the payload is code:

{"success":true,"payload":{"code":"1234567890asdfghjkl"}}

 

If there occurs an error, then in postMessage is "success": false, and in the payload is error and message:

{"success":false,"payload":{"error":{"status":"USER_CANCELLED","message":"The user cancelled the authentication"}}}


A list of all error statuses can be found here.

 

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);
} else {
const { payload: { error }} = data;

console.error(
`Error occurred: ${error.status} with message: ${error.message}.`
);
}

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-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID">

The difference is that we are omitting the mode=iframeparameter 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 the CALLBACK_URL GET parameter (CALLBACK_URL?code=<your code will be here>).

For testing purposes we can set the CALLBACK_URL to http://localhost:3000/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.

 

When an error occurred during login, the CALLBACK_URL will contain the error parameter for the error code and the message parameter for the error message.

For example:

http://localhost:3000/callback?error=USER_CANCELLED&message=The%20user%20cancelled%20the%20authentication

 

A list of all error statuses can be found here.

 

The APPLICATION_IDis used for verification of redirect_uri and it is mandatory. For getting APPLICATION_ID, contact our team and provide us your redirect CALBACK_URI (it also can be more than one). We will generate a unique APPLICATION_ID for you.

When no CALLBACK_URL is used or CALLBACK_URL is localhost, then is user redirected to the default landing page after successful login.

Step 1.c. - redirection to provider

 

The link can be used as a simple HREF link which provides redirection to the provider as well:

 

<a href="https://ais.bisnode.com/psd2-auth-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&mode=redirect_to_provider">

 

Implementation is similar to the HREF link (see 1.b) with the difference that mode is set to redirect_to_provider, which indicates that ais.bisnode.com will provide redirection to provider and back to CALLBACK_URL.

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

When no CALLBACK_URL is used or CALLBACK_URL is localhost, then is user redirected to the default landing page after successful login.

The disadvantage of using this approach is that there are two redirects and the end-user lands directly on the account information provider web page.

For testing purposes we can set the CALLBACK_URL to http://localhost:3000/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.

 

When an error occurred during login, the CALLBACK_URL will contain the error parameter for the error code and the message parameter for the error message.

For example:

http://localhost:3000/callback?error=USER_CANCELLED&message=The%20user%20cancelled%20the%20authentication

 

A list of all error statuses can be found here.

The APPLICATION_IDis used for verification of redirect_uri and it is mandatory. For getting APPLICATION_ID, contact our team and provide us your redirect CALBACK_URI (it also can be more than one). We will generate a unique APPLICATION_ID for you.

 

Error statuses:

Error status Description
INTERNAL_ERROR

An internal error. Please contact support for help.

PROVIDER_ERROR

A provider error. Please try again later.

USER_CANCELLED

The end-user canceled the flow.

BAD_REQUEST

The URL was incorrectly configured.

 

Optional parameters:

These parameters can be used for the customization of the authentication views. If the parameter is not filled or has the wrong value, the default value is used. 

Scope 

Grant access to different provider API endpoints which controls the permitted data access.

It is possible to use multiple values separated by a comma. Or by multiple scope parameters.

It is highly recommended to use the default value to get all information needed. 

Possible values Description  Default value
accounts Access to all the user's account information, including balances.

accounts,
investments,
transactions,
identity,
credentials

investments Access to the user's portfolios and underlying financial instruments.
transactions Access to all the user's transactional data.
identity Access to the user's personal information that can be used for identification purposes.
credentials Access to the information describing the user's different bank credentials

 

Sample usage:

<a href="https://ais.bisnode.com/psd2-auth-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&scope=accounts,transaction,identity">


<a href="https://ais.bisnode.com/psd2-auth-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&scope=accounts&scope=transaction&scope=identity">

 

Market

Lists all providers on a specified market.

Only one value can be specified in the parameter.

Possible values Description Default value
ATAUBEBGBRCACYCZ,... The ISO 3166-1 alpha-2 market code. SE

 

Sample usage:

<a href="https://ais.bisnode.com/psd2-auth-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&market=AT">

 

Locale

Specify the language of the login form.

Possible values Description Default value
da_DK Danish en_US
de_DE German
en_US English (United States)
es_ES Spanish
fi_FI Finnish
fr_FR French
it_IT Italian
nl_NL Dutch
no_NO Norwegian Nynorsk 
pt_PT Portuguese 
sv_SE Swedish

 

Sample usage:

<a href="https://ais.bisnode.com/psd2-auth-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&locale=de_DE">

 

Username

If this parameter is provided, the username field will be pre-filled in the login form. If not, the end-user can type it in. 

Possible values Description Default value
Username, Personal Identification Number for a specific country, or a Social Security Number.    

 

Sample usage:

<a href="https://ais.bisnode.com/psd2-auth-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&username=tink">

 

Test

Specify if the test environment is used.

Possible values Description Default value
true The test login form is displayed. With this value, you can try the login described here false
false Real banks are displayed 

 

Sample usage:

<a href="https://ais.bisnode.com/psd2-auth-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&test=true">

 

 It is possible to use all optional parameters together.

Optional parameters can be used in an iframe like this:

<iframe src="https://ais.bisnode.com/psd2-auth-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&mode=iframe&scope=SCOPE&market=MARKET&locale=LOCALE&test=TEST&username=tink">

 

The same usage is for simple HREF:

<a href="https://ais.bisnode.com/psd2-auth-link-web/v1/auth?redirect_uri=CALLBACK_URL&app_id=APPLICATION_ID&scope=SCOPE&market=MARKET&locale=LOCALE&test=TEST&username=tink">
Demo page
We are providing a demo page to try it all out. The demo page can be found at https://ais.bisnode.com/psd2-auth-link-web/v1/demo.
There is also the possibility to try optional parameters.
Default landing page
A default landing page is created for visualization of postMessage response in a user-friendly way. It should be used only for testing purposes.
Example of success postMessage on the default landing page:
imagezd0l.png
Example of error postMessage on the default landing page:
imagekfnwf.png
Step 2

After 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 call also must have an Authorization: Bearer eyJhb...seAtPCCQ header. See the Authentication section above.

GET /token
Token query parameters:

Key Value Description
code 4gdfg654edr89tg7e4gh654sdf654 The code from the 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 access token, we can fetch data from "Provider" APIs. For income verification flow, we can use /account/transactions. 

 

A 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"
}
},
...
]
}

 

These categories can be queried in our API:

  income
  root category
  income-salary
  income subcategory
  income-financial
  income subcategory
  income-pension
  income subcategory
  income-refund
  income subcategory
  income-other
  income subcategory
  income-benefits
  income subcategory
  income-uncategorized
  uncategorized income
  expenses
  root category
  expenses-house
  expenses subcategory
  expenses-house-fitment
  expenses-house subcategory
  expenses-house-garden
  expenses-house subcategory
  expenses-house-repairs
  expenses-house subcategory
  expenses-house-uncategorized
  uncategorized expenses-house subcategory
  expenses-misc
  expenses subcategory
  expenses-misc-education
  expenses-misc subcategory
  expenses-misc-charity
  expenses-house subcategory
  expenses-misc-outlays
  expenses-misc subcategory
  expenses-misc-others
  expenses-misc subcategory
  expenses-misc-kids
  expenses-misc subcategory
  expenses-misc-pets
  expenses-misc subcategory
  expenses-misc-withdrawals
  expenses-misc subcategory
  expenses-misc-uncategorized
  uncategorized expenses-misc subcategory
  expenses-food
  expenses subcategory
  expenses-food-alcoholtobacco
  expenses-food subcategory
  expenses-food-bars
  expenses-food subcategory
  expenses-food-coffee
  expenses-food subcategory
  expenses-food-groceries
  expenses-food subcategory
  expenses-food-restaurants
  expenses-food subcategory
  expenses-food-uncategorized
  uncategorized expenses-food subcategory
  expenses-home
  expenses subcategory
  expenses-home-services
  expenses-home subcategory
  expenses-home-communications
  expenses-home subcategory
  expenses-home-incurencesfees
  expenses-home subcategory
  expenses-home-mortgage
  expenses-home subcategory
  expenses-home-rent
  expenses-home subcategory
  expenses-home-utilities
  expenses-home subcategory
  expenses-home-uncategorized
  uncategorized expenses-home subcategory
  expenses-shopping
  expenses subcategory
  expenses-shopping-books
  expenses-shopping subcategory
  expenses-shopping-clothes
  expenses-shopping subcategory
  expenses-shopping-electronics
  expenses-shopping subcategory
  expenses-shopping-gifts
  expenses-shopping subcategory
  expenses-shopping-hobby
  expenses-shopping subcategory
  expenses-shopping-uncategorized
  uncategorized expenses-shopping subcategory
  expenses-wellness
  expenses subcategory
  expenses-wellness-beauty
  expenses-wellness subcategory
  expenses-wellness-eyecare
  expenses-wellness subcategory
  expenses-wellness-healthcare
  expenses-wellness subcategory
  expenses-wellness-pharmacy
  expenses-wellness subcategory
  expenses-wellness-uncategorized
  uncategorized expenses-wellness subcategory
  expenses-transport
  expenses subcategory
  expenses-transport-car
  expenses-transport subcategory
  expenses-transport-flights
  expenses-transport subcategory
  expenses-transport-publictransport
  expenses-transport subcategory
  expenses-transport-taxi
  expenses-transport subcategory
  expenses-transport-uncategorized
  uncategorized expenses-transport subcategory
  expenses-entertainment
  expenses subcategory
  expenses-entertainment-culture
  expenses-entertainment subcategory
  expenses-entertainment-hobby
  expenses-entertainment subcategory
  expenses-entertainment-sport
  expenses-entertainment subcategory
  expenses-entertainment-vacation
  expenses-entertainment subcategory
  expenses-entertainment-uncategorized
  expenses-entertainment subcategory

 

 

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.