Skip to main content

The Accounts API

This page describes the Accounts API in a more technical way and explains specific advanced use cases with the authentication, the widget management, or with the full API use if you have a PSD2 agreement.

The resources involved in the use cases are very different depending on your choice to use the widget based integration or the full API integration.

Description

The Accounts API is used to link a third-party application to the banking application for Account Information Services (AIS).

Data acquisition is carried out in two ways:

  • Screen scraping of data (access to customer accounts via their identifiers)
  • Open banking based on open APIs (PSD2)

Linxo Connect covers the following use cases :

  • Signup a new user: Use Accounts API to create your users with the client credential flow.
  • Signin existing user: Authenticate your users with the resource owner password credentials flow and get access token in order to consume API resources. You may also directly manage your users' data with a client authentication.
  • Add bank connection and bank account: Secure your users' credentials
  • Synchronize and get transactions: Get fresh datas from their finantial institutes.
  • Delete user: Delete users and remove all their personal datas.

The API consists of 3 main parts:

  • The authentication. below more technical details on authentication mechanisms
  • The widget management mainly describes in the Quickstart and HowTo chapters
  • The full API integration with or without using the widget. It requires to have a PSD2 agreement.

Authentication

Glossary

OAuth2 is an open standard for access delegation, commonly used as a way for Internet users to grant websites or applications access to their information on other websites but without giving them the passwords.

OAuth 2.0 is the industry-standard protocol for authorization and focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices.

  • ROPC flow (Resource Owner Password Credentials) allows an application to sign in the user by directly handling their password.
  • Basic client credential flow: With machine-to-machine (M2M) applications, the system authenticates and authorizes the app rather than a user. M2M apps use the Client Credentials Flow (RFC 6749) in which they pass along their Client ID and Client Secret to authenticate themselves and get a token.

MFA: Multi-factor authentication is an authentication method in which a computer user is granted access only after successfully presenting two or more pieces of evidence to an authentication mechanism

The flows

  • You obtain an access token from the Linxo Connect Authorization Server

    A single access token can grant varying degrees of access to multiple resources. A variable parameter called scope controls the set of resources and operations that an access token permits. During the access-token request, your application sends one or more values in the scope parameter.

    There are several ways to make this request, and they vary based on the type of application you are building. For example, a JavaScript application might request an access token using a browser redirect to Linxo Connect, while an application installed on a device which doesn't have a browser could use web service requests.

  • You send the access token to the API

    After an application obtains an access token, it sends the token to the API in an HTTP authorization header.

    Access tokens are valid only for the set of operations and resources described in the scope of the token request. For example, if an access token is issued for the bank account resource only, it does not grant access to the transaction resource. You can, however, send that access token to the API multiple times for similar operations.

See below for a description of the scope values.

Linxo Connect Authorization Server:

Linxo Connect Signup Flow

Detail

All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.

Property 
Security scheme typeOAuth2
OAuth2 FlowClient credentials & ROPC
Token URL{anvilUrl}/token

### Client credentials

OAuth2 client credentials flow schema

This flow is meant to be used from a service on the server side (it needs the client secret) in order to access resources which do not belong to a specific user. This flow also allows the API to be used in admin mode. To use this flow, you will have to perform a POST request on the /token endpoint of Linxo Connect authentication server with a HTTP basic authentication and some parameters documented below.

HTTP basic authentication is made by setting a HTTP header Authorization with the value of: Basic clientid:clientsecret Note that this value must be base64-encoded in the request.

You can find the endpoint description /token in the reference documentation

Example:

# Get access_token
response=$(curl -s -u "${client_id}:${client_secret}"-X POST {anvilUrl}/token \
-d grant_type=client_credentials \
-d scope=users_create

# Print human readable response
echo $response | sed -r 's/.?"([^"]+)":"?([^",]+)"?.?/\1: \2\n\n/g'

This command outputs:

access_token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
token_type: Bearer
expires_in: 3600

### Resource owner password credentials

In the shared Linxo Connect environment, you own your users. You can therefore use the ROPC authentication flow allowing you to obtain an access token against your user credentials.

OAuth2 ropc flow schema

Widgets services are relying on Accounts API endpoints and therefore you need to ask for the accurate list of scopes when negociating a User Access Token and depending on the widget action you want to deal with for your Linxo Connect user, this list may vary. Refer to the dedicated chapter for the detailed list of scopes.

You can find the endpoint description /token in the reference documentation

ROPC example:

# Get access_token
response=$(curl -sk -X POST {anvilUrl}/token \
-d username=${username} \
-d password=${password} \
-d grant_type=password \
-d client_id=${client_id} \
-d client_secret=${client_secret} \
-d scope=openid%20profile%20accounts_read \
-d provider=connect)

# Print human readable response
echo $response | sed -r 's/.?"([^"]+)":"?([^",]+)"?.?/\1: \2\n\n/g'

# Get token
token=$(echo $response | sed -r 's/.?"([^"]+)":"?([^",]+)"?.?/\1: \2\n\n/g' | grep access_token | cut -d' ' -f2)

# Use token on a private resource
curl -sk ${api_baseurl}/accounts -H "authorization: Bearer $token" | jq .

Scopes list

The scopes list represents the list of permissions you can request from a user. Each scope is associated with endpoints in our API v2.

Scope 
accounts_readAllows you to retrieve the user's bank account information: bank name, account name, balance...
accounts_manageaccounts_read permissions + update, create and delete bank accounts
connections_manageupdate connections credentials, add connections, generate keys for encrypt datas, subscribe to synchronization events queue
connections_syncAllows you to trigger a synchronization.
transactions_readAllows you to retrieve the user's bank account information, connections information and transactions information.
profileAllows you to retrieve information of the user's profile.
profile_editprofile permissions + update and delete informations
users_createability to create users

Use the widget

The widget allows to delegate some tasks. After having requested a session, user is redirected to a browser to lead them in wanted fonction. A return URL transmits process result and necessary information. Events are tracked to follow user behavior.

Widget based integration

The widget entry points are the following:

  • Create a session: authentification to be able to use the widget (POST /widget_session)
  • Add a connection: add a connection to a provider by filling a credential form (GET /widget/add_connection)
  • Edit credentials: edit an existing connection and optionally update its credentials (GET /widget/edit_credentials)
  • User Input: build the form making it possible to enter challenges (GET /widget/user_input)
  • Accept terms and conditions: for a given end user, approve the service Terms and conditions' current version (GET /widget/terms)
  • Professional account: provide information regarding any professional account (GET /widget/professional-account)
  • Manage accounts (PSD2 mandatory): to modify the list of accounts in a connection (GET /widget/manage_accounts)

The widget is able to handle web redirects and multiple authentication management, using our API.

To select a bank or a test bank, you need to add a connection to a provider.

You can therefore redirect the user on the widget with the link provided by the response of the widget session (in the '_links' field), or by building it by concatenation of this endpoint with the session_id. The following actions are performed:

  • It will allow you to display a form to select the bank and will try to reach this provider after filling in a credential form.
  • The provider is connected
  • The account list retrieved
  • You accept PSD2 consent (all existing and future bank accounts for Linxo Connect consent)
  • The synchronisation is started.
  • If captive_mode parameter is enabled, The user will remain on the widgets until the last bank operation is retrieved.

The connection is used to manage the lifecycle of the channels. Using the PSD2 redirect channel, the connection is created as the user is redirected back to our services and we provide a ready to use connection when your user comes back on the URI you provided.

Depending on the widget options you choose, you may need to implement a waiting step before the data is collected in our systems.

The widget integration

Terms and conditions

When you create a user, he must validate the Linxo Connect terms and conditions. If he does not, all API calls will return 401 errors indicating that the user has an action to perform.

Linxo Connect is a payment establishment, approved by the ACPR for account information and payment initiation services.

Linxo Connect widgets detect when the user must accept the terms and conditions. When the user uses a widget, it is first redirected to the UI allowing to accept Linxo Connect terms and conditions and authorize your user to transfer their account data to you.

PSD2 channels

Banks' PSD2 APIs allow the user authentication by obtaining his credentials, in order to access data for checkings and credit card accounts only. When a connection is added, the widget allows the user to be redirected to the bank's access portal which is responsible of his authentication.

These credentials expires after 90 days. In this case, the widget

  • either manage the update of its credentials thanks to a user interface thanks to the edit_credentials endpoint.
  • or allows to retrieve the redirect URL that is produced by calling the endpoint POST /providers/<provider_id>/channel_definitions/<channel_definition_id>/authorize_url in the redirect channel definition. The URL will contain the information necessary to handle security tokens negotiation after the authentication. You can therefore redirect your user to the provider's authentication website.

According to the PSD2, the user will need to perform a multifactor authentication (MFA) with an SMS or a security device when he adds a new connection and when he renews its credentials.

Notice that to cover the entire functional scope of your application, you may still need to use the form based credentials (scraping mode) to collect the data not available via PSD2 API.

When you use the Linxo Connect PSD2 agreement, with the Linxo Connect consent, the user agrees to share all existing and future bank accounts related to their credentials.

When a new account is available on the connection, it is automatically added to the user's connection without the need for re-consent.

Internationalization

Widgets are, for now, translated into french and english languages. Widgets are able to rely on your browser default language to switch to it if available. The default supported language is french. It is possible to specify a language by setting a lng query parameter when requesting a widget. Example: https://embed.linxo-connect.com/widget/add_connection?lng=en will force the english version of the widget.

Available languages:

NameValue
Englishen
Frenchfr

Requirements to use Linxo Connect widgets

Widget session sequence diagramm

The Widget service provides an endpoint to create a session from the user credentials. It will create a session containing the credentials and return the session ID.

The quickstart and the HowTo gives you examples whereas the reference documentation details the endpoint.

### Connection flow with the widget

Widget flow

Actors :

  • Auth Server: The delegated authentication server.
  • Webview Service: The service that hosts the webviews and connects to the API.
  • User: the end user of the client
  • Client: the service company that uses our services as aggregation provider
  • API: The existing REST API v2

The main features:

  • You create a session (widget) (endpoint)

    The widgets need a valid user access token and optionally a refresh token. If you do not provide a refresh_token while creating a new session, widget service won't be able to refresh the access_token for you. As a consequence the lifetime of the session will be linked to the lifetime of the provided access_token.

  • You [add connection (widget): example & endpoint These widgets require an active session, the Webview service will immediately redirect to the redirect_uri with an "expired" result if the session has expired. The client can provide some parameters to customize the screen flow and he is notified of the results by a callback URL.

    • A credential form is displayed to your user
    • The provider is connected
    • The account list retrieved
    • You accept PSD2 consent (all existing and future bank accounts for Linxo Connect consent)
    • The synchronisation is started.
    • If captive_mode parameter is enabled, The user will remain on the widgets until the last bank operation is retrieved.

    When you create the session, you have the option to provide the parameters "provider_id", "channel_definition_id", "captive_mode", "select_accounts", "multiple_channels", "select_channel". When they are provided as query string parameters in add connection widget, they overwrite those recorded in the session.

And, if needed:

  • You may [edit credentials (widget)](/) (endpoint)

    • Modify a widget parameter
    • Update the user credentials
    • Add a new channel

    The client can provide some parameters to customize the screen flow and he is notified of the results by a callback URL.

    These screens require an active Webview service session, the Webview service will immediately redirect to the redirect_uri with a result of "expired" if the session is expired.

  • You may enter new challengeswith User input (widget)](/) (endpoint) This widget allows you to build the form making it possible to enter challenges. You need to use queue polling.

    The results are added as query string parameters to the redirection URL provided when creating a session or displaying the widget

  • Your end user can validate the processing of professional accounts with [Professional account (widget)](/) (endpoint)

  • Your end user can [Accept terms and conditions (widget)](/) (endpoint)

    Once "Terms and conditions" are validated, the webview service will automatically redirect to a provided redirect_uri with a "success" or "error" result.

  • You may modify the list of accounts in a connection if you have a PSD2 approval with [Manage accounts (widget)](/) (endpoint)

    This widget allows you to modify the list of accounts in a connection by consenting to the addition of new accounts or by stopping consent for certain accounts. A synchronization is triggered for consented accounts.

### The webviews

The Webviews provide a user interface allowing user to interact easily with the banking requests

  • Bank adding
  • Identifiers updating
  • Strong authentication
  • Linxo Connect terms and conditions validation
  • Professionnal accounts management

The flows are created from the combination of several parameters :

ParameterValueDefaultDescription
captive_modeBooleantrueWhen this parameter is set to false (default value), we try

to keep the user as short as possible on widgets. This implies that you are responsible for polling the event queue to retrieve the account list or transactions. We just validate that the user IDs are valid and functional. When this parameter is set to true, the screens are linked synchronously. The user will remain on the widgets until the last bank operation is retrieved. This greatly simplifies the integration work. | select_accounts | Boolean | false | When this parameter is set to false (default value), we get the list of all accounts available for the provider's channel definition. When this setting is set to true, we display a list of accounts, allowing your user to share only the data they want to aggregate via widgets. You must have a PSD agreement to use this parameter | multiple_channels | Boolean | false | When the provider has two different channels to retrieve payment account information and information from other types of accounts, we prioritize first the REDIRECT channel and then the EMBEDDED channel. When this parameter is false and the provider has several channels, we only realize the first one. When this parameter is true, we aggregate all channels through webviews. | select_channel | Boolean | false | When the provider has two different channels to retrieve payment account information and information from other types of accounts, we prioritize first the REDIRECT channel and then the EMBEDDED channel. When this parameter is false and the provider has several channels, we choose the REDIRECT channel definition. Most of the time this channel is dedicated to the recovery of payment accounts. When this paramater is set to true and the provider has several channels, a popup appears and asks the user if he wants to add payment accounts (REDIRECT channel definition) or savings accounts (EMBEDDED channel definition).

When an operation takes more than a few seconds, a loading screen may appear. Actions that take a little time are usually those related to the captive_mode parameter. When this parameter is set to true, we wait for all the necessary information from the current step to be gathered before proceeding to the next step.

Exemples:

  • When the REDIRECT channel is selected:

    • The user selects his provider from the list of available providers.
    • The REDIRECT channel is selected. The user is informed that by connecting to the website of his provider, he agrees to transfer the information to you through Linxo Connect
    • The user is redirected to the provider's site, authenticates himself following the provider's screens. The user consents, by connecting to the provider's website, he authorizes Linxo Connect to send you banking information.
    • The provider redirects to the widgets, we create the connections and we give you back your hand after a few seconds.
  • When the EMBEDDED channel is selected

    • The user selects his provider from the list of available providers.
    • The EMBEDDED channel is selected.
    • The user fills his credentials
    • We validate the credentials, create the connection and we give you back the hand after few seconds.
  • (Declination) Skip provider list

    • You force the provider with the parameter **provider_id**, so the providers list widget is not displayed
    • Linxo Connect prioritizes channel definitions (in this example, REDIRECT channel is available)
    • The user fills his credentials
    • We validate the credentials, create the connection and we give you back the hand after few seconds.

      If the value provided for provider_id property is not valid, the user will be redirected on your **redirect_uri** with an error message.

  • (Declination) Skip provider list & force the channel definition

    • You force the provider with the parameter **provider_id**, so the providers list widget is not displayed

    • You force the channel with the parameter **channel_definition_id** (EMBEDDED1)

    • The user fills his credentials

    • We validate the credentials, create the connection and we give you back the hand after few seconds.

      If the values provided for provider_id & channel_definition_id properties are not valid, the user will be redirected on your redirect_uri with an error message.

  • (Declination) Let the user choose the channel definition

    • The user selects his provider from the list of available providers.
    • The provider has several channel definition, we ask to the user which channel he wants to use: parameter **select_channel** set to true
    • Depending on the channel definition chosen, the user will continue on the screens dedicated to the REDIRECT or EMBEDDED path
  • (Declination) Use all channels during the aggregation

    • The user selects his provider from the list of available providers.
    • Linxo Connect prioritizes channel definitions: parameter **multiple_channels** set to true
    • The user fills his credentials
    • We validate the credentials, create the connection
    • Then we invite the user to edit his connection to add the second channel
  • (Declination) Use all channels and select accounts

    • The user selects his provider from the list of available providers.
    • Linxo Connect prioritizes channel definitions: parameter **multiple_channels** set to true
    • The user fills his credentials
    • We validate the credentials, create the connection
    • The list of available accounts is displayed and the user can choose which data he wants to aggregate: parameter **select_channel** set to true
    • Then we invite the user to edit his connection to add the second channel
    • The list of available accounts is displayed and the user can choose which data he wants to aggregate.

Request a refresh access token

A token and a refresh token are returned when you authenticate the client.

Access tokens have limited lifetimes. If your application needs access to the API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.

The widgets need a valid user access token and optionally a refresh token to manage the Connect Authentication of the user with the API. The access token and the refresh token are provided in the response of the user authentication

If you do not provide a refresh_token while creating a new widget session, widget service won't be able to refresh the access_token for you. As a consequence the lifetime of the session will be linked to the lifetime of the provided access_token.

You can have detailed information about authentication in a dedicated chapter of the Advanced API integration page. The reference documentation describes the token API endpoint parameters.

Request example:

curl -s -X POST {anvilUrl}/token -d refresh_token=${refresh_token_value} -d grant_type=refresh_token -d redirect_uri=${redirect_uri} -d client_id=${client_id} -d client_secret=${client_secret} -H 'Accept: application/json' -H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'

Response example:

{
"access_token": "eyJhbGciOiJSUzI1NiJ9 ... mBy308Znno7AWuaGNoyoRgwSuYwdo",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "3495142fgte56fb3f13b",
"id_token": "eyJhbGciOiJSUzI1NiJ9 ... 9d016f0e2.350a2157fa75b9bd4c166340"
}

Full API integration

Description

If you have a PSD2 agreement, you can choose to use the widget or not. Notice that this last process does not necessarily include any Linxo Connect UI and can be used to redirect the user seamlessly to your application if you have PSD2 agreement.

The API endpoints allow you to manage all the components needed to create connections and retrieve users' data. You will need to define the web interfaces to choose a bank, accept the PSD2 consent, perform the bank login, create and synchronize the connections and manage the events to be able to set up the necessary actions.

If you do not use the widget, some of the mechanics of the API are strongly linked. When dealing with synchronizations or adding a connection, several resources interacts. For optimal operation, it is essential to understand the interactions and to make calls to the API in the right order.

Using the widget

The widget is available for any customer and customizable at different levels depending on your legal licence.

If you don't have or don't plan to use your own PSD2 licence, making a widget based integration will be mandatory.

Regulatory reminders: Depending on whether you have PSD2 (AIS/PIS) agreement or not, the use of widgets and features differ.

Here is a summary table:

PSD2 Agreement (AIS/PIS)No Agreement
Create user outside widgetsYESYES
End user has to validate Linxo Connect terms and conditionsNOYES
Can customize Widgets (color)YESNO
Removal of Linxo Connect logosYESNO
Do aggregation in full API modeYESNO
User can consent per accountsYESNO

You can use the default Linxo Connect behavior or you can have a different consent management. We propose a consent per account. You can use the query string parameter select_accounts. A webview then suggests to the user to choose the accounts he wants to aggregate and for which he consents. On this created connection, the new available accounts will not be added automatically. It will be necessary to use a dedicated widget in the future for this purpose.

When you have an agreement, you can also perform this behavior in full API. When the connection is saved, you will receive an event containing the account list for the client to display an account list selection screen and requisite consent. You will then need to call the consents endpoint /connections/{id}/consents using the word PUT to provide the list of account ids and the decision the user made. After this step, a synchronization is triggered to collect data on this account list.

To notify clients about new accounts that the user needs to give his/her consent to, we now list in the accounts resource the accounts with a status PENDING_CONSENT. An account will stay in this status until a consent decision is made on the endpoint /connections/{id}/consents.

Manage the accounts with the widget webview

(Declination) Display the select accounts widget (You need your own agreement to do this flow)

 captive_modeselect_accountsmultiple_channelsselect_channel
Valuetrue or falsetruefalsefalse
  • The user selects his provider from the list of available providers.
  • Linxo Connect prioritizes channel definitions (in this example, REDIRECT channel is available)
  • The user fills his credentials
  • We validate the credentials, create the connection
  • The list of available accounts is displayed and the user can choose which data he wants to aggregate.

Full API integration flow

API based integration

  1. Create a user: The user is the at the center of the API resources, it will be used to group connections to banking providers and store the accounts and transactions (endpoint)
  2. List available providers: The provider represents a financial institution available in our aggregation platform, when enrolling a user, you may want to list available provider for him add a connection to collect data (endpoint)
  3. Create a new connection
  4. Wait for data to be fetched: Depending on the widget options you choose, you may need to implement a waiting step before the data is collected in our systems.
  5. Access account and transaction data: Once the data is made available, you will be able to collect accounts and transactions to manage your business needs.
  6. Manage connection channels lifecycle using API: PSD2 API tokens, embedded credentials have a lifecycle and needs to be updated periodically. To handle this, an API integration should monitor connection and channel statuses to make the user update its channel when needed.

Manage a connection to bank accounts


Prequisites:


The creation of a banking connection is a multi-step process. A client needs to select a provider and create a connection using one of the channel definition defined in the providers resource.

The channel_definitions property may require the client to redirect its user on a URL using a web browser (REDIRECT channel definition mode) or the client to build a form (EMBEDDED channel definition mode) for the user to authenticate with the provider. The channel definitions are bound to a list of account types, you may need to authenticate your user with both a REDIRECT and a EMBEDDED channel to add all the accounts available on a connection.

On a REDIRECT based channel definition, the connection will be created for you at the end of the process by Linxo Connect. You can choose to implement the creation of connection process.

On the other side, when managing an EMBEDDED channel, you will need to generate an encryption key to encrypt your user's credentials on the client before sending it to our API.

When a new connection is added to a provider's service, two synchronizations will be triggered:

  • At connection creation, a first synchronization of type LIST_ACCOUNTS will retrieve a list of accounts available using the chosen channel. No data is stored at this time.
  • After the client forwards the user consent, a SYNC_ALL synchronization will fetch the account data and the associated transactions.

The client can provide the user consent by using the /connections/{id}/consents endpoint with the list of accounts he agrees to share with the client.

You have the ability to poll the event queue to track progress.

To create a connection, more details on :

And to manage connection channels lifecycle:

Each channel is associated to credentials and synchronization jobs that have statuses to manage. Some statuses requires a user action like:

  • User input and challenge (statuses CHALLENGE_REQUIRED, CHALLENGE_TIMED_OUT, CHALLENGE_FAILED, CHALLENGE_CANCELLED)
  • Updating the credentials (statuses AUTH_FAILED, TOO_MANY_ATTEMPTS, PASSWORD_CHANGE_REQUIRED)
    • Update credentials for a [redirect channel](#update-credentials-for-a-redirect channel)
    • Update credentials for an [embedded channel](#update-credentials-for-an-embedded channel)
  • Asking the user to perform an action on the provider website (USER_ACTION_REQUIRED)

REDIRECT channel creation

A redirect channel definition contains credentials of type AUTHORIZATION_CODE, ACCESS_TOKEN, REFRESH_TOKEN allows to communicate with the PSD2 API of the provider.

You can let Linxo Connect creates the connection for you or you can do the process.

Add a new REDIRECT connection

Let Linxo Connect creates the connection for you

A redirect channel definition contains an endpoint used to produce an authorize URL for the client to redirect the user to input credentials.

In this definition, the user is redirected to authenticate on the bank website. Please refer to the Quickstart or the reference documentation to understand how to create a webview session for your user in order to add it to the redirection query params.

The Linxo Connect callback uri is hosted on the Linxo Connect widget service. You won't see any Linxo Connect UI during this process, but we need the following information in order the callback works correctly :

  • client_id and client_secret: the API keys we provide to you in order to use Accounts API. Those information will allow us to refresh the access_token if it expires during the process.
  • access_token : the user access_token to consume API v2
  • provider_id : the identifier of the provider
  • redirect_uri : a callback uri hosted by you, you will receive the connection_id and some data about the status of the synchronization (connection_id, status, queue_id)
# Example, retrieve the authorization service url for Linxo Test Bank (provider ID = 87, REDIRECT channel definition id = 8701)
curl -skX POST \
{baseUrl}/providers/87/channels/8701/authorize_url \
-H 'authorization: Bearer {access_token}' \
-H 'Content-Type: Application/json'
-d '{
"widget_params": {
"client_id": "{client_id}",
"client_secret": "{client_secret}",
"access_token": "{access_token}",
"provider_id": "87",
"redirect_uri": "https://your.callback.uri"
}
}'

# response
HTTP/2 201

location: https://stettestbank.linxo.com/authorize?create=true&redirect_uri=https%3A%2F%2Fembed.linxo-connect.io%2Foauth2%2Faisp&state=xec4a2pWQ7KlHA5rYMel2wOx9AULqbFc

In this definition, the user is redirected to authenticate on the bank website. When the authentication is done, the user is redirected transparently on our service for us to create the connection and then back in your application.

Your application can retrieve the connection id and a queue id to wait for the data to be collected.

Notice that PSD2 requires that you use some specific technologies for this redirection for security issues. The RFC8252 can provide additional information on this subject.

The browser view will be redirected on the provided URL with the id of the connection we just created.

This connection will not contain data before the synchronization process is over. A client needs to listen to the synchronization events to be aware of the accounts availibility as described in Synchronization section and provide consent of the user.

You want to create the connection

Step one, you need to redirect your user on the authorization service of the provider. Choose the provider in the provider list then call the endpoint authorize_url to retrieve the URL of the authorization service of the provider.

As you won't use Linxo Connect callback, you need to provide some information when calling the endpoint authorize_url

The callback uri is hosted by you and we need the following information in order the callback works correctly :

  • use_client_redirect: When true, we know you will handle the connection creation.
  • redirect_uri: The callback uri which the ASPSP authorization service will contact after a successful authentication.
  • redirect_state: This parameter is optional, it's a data you will provide and you will receive in the callback uri as state query string parameter. Beware, don't use the "pipe |" caracter in your state, this is a reserved caracter for Linxo Connect. We use it as separator.
# First, I retrieve the channel definition for HSBC
curl -sk \
{baseUrl}/providers/119 \
-H 'authorization: Bearer {access_token}'

# Returns the key
{
"id":"119",
"name":"HSBC",
"branch_name":"",
"base_url":"https://www.hsbc.fr/1/2/hsbc-france/particuliers/connexion",
"logo_url": "https://static.linxo-connect.io/common/pictures/providers_logos/119.png",
"country_code":"FRA",
"channel_definitions":[{
"id":"redirect1",
"mode":"REDIRECT",
"account_types": [
"CHECKINGS","CREDIT_CARD"
],
"interactive": false
},{
"id":"embedded1",
"mode":"EMBEDDED",
"account_types": [
"SAVINGS","LOAN"
],
"credentials":[
{
"id":"3500",
"label":"Identifiant",
"regexp":"^[\\a-zA-Z0-9@._-]{7,}$",
"type":"TEXT",
"encrypt":false
},
{
"id":"3501",
"label":"Réponse mémorable",
"regexp":".+",
"type":"PWD",
"encrypt":false
},
{
"id":"3502",
"label":"Mot de passe (8 car. min.)",
"regexp":"^.{8,}$",
"type":"PWD",
"encrypt":true
}
]
}],
"unavailable":false
}

If your are interested in checkings accounts for instance, you will need to provide the redirect channel definition. The URL you need to use for the redirection is produced by calling the endpoint with a redirect url where the user will be redirected at the end of the process and optional widget parameters if you need specific UI.

The authorize URL will contain a widget session id with necessary information to create or update the connection when the bank website will redirect back the user.

Example : Create an authorize URL on HSBC.

# Generate the authorize URL for HSBC
curl -ski POST \
{baseUrl}/providers/119/channel_definitions/100/authorize_url \
-H 'authorization: Bearer {access_token}'
-H 'Content-Type: application/json'
-d '{
"redirect_uri" : "https://<api-client-url>",
"widget_params" : {
"access_token" : "<access_token>",
"refresh_token" : "<refresh_token>",
"client_id" : "<client_id>",
"client_secret' : "<client_secret>",
"captive_mode" : false
}
}'

# Response
HTTP/1.1 201 OK
location: https://hsbc.fr/ca-paris/authorize?response_type=code&client_id=psdfr-bdf-16928&redirect_uri=https%3A%2F%2Fembed.linxo-connect.io%2Foauth2%2Faisp&scope=aisp%20extended_transaction_history&state={session_id}

In this example, we are creating an authorize URL for the redirect channel to create a new connection. We have provided client information to refresh the token if the token expires before the redirect is complete.

Afer the redirect process is complete, the browser view will be redirected on the provided URL with the id of the connection we just created.

This connection will not contain data before the synchronization process is over. A client needs to listen to the synchronization events to be aware of the accounts availibility as described in Synchronization HowTo and provide consent of the user.

Once the account list is available, a client needs to ask the user to consent for each account for Linxo Connect to start collecting the data.

An account is synchronized by Linxo Connect only if a consent has been given. Notice that an account without consent decision is in the status CONSENT_PENDING and will not be synchronized.

# Consent for accounts. Accounts with consent=true will be synchronized and accounts with consent=false will be deleted.
curl -X PUT \
{baseUrl}/connections/{id}/consents \
-H 'authorization: Bearer {access_token}'
-d '{
"consents": [
{
"account_id": "{account_id1}",
"consent": true
},
{
"account_id": "{account_id2}",
"consent": false
}
]
}'
HTTP/1.1 204 No content

When the consent is updated, a full synchronization is made to collect the missing data.

EMBEDDED channel creation

Add a new connection

Create the encryption key

To implement an EMBEDDED channel definition, a client will first need to create a new PGP encryption key. This obtained key will allow you to encrypt the user's bank credentials.

Each banking institution (providers) has a list of identifiers. We know that we must encrypt an identifier its value encrypted is set to true.

The encryption is done on the client side and it is the encrypted value that will be sent in the connection add payload.

Example : I want to create a connection for my client. His bank is Linxo Test Bank.

# First, I retrieve the credentials information from HSBC
curl -sk GET \
{baseUrl}/providers/119 \
-H 'authorization: Bearer {access_token}'

# Response
HTTP/1.1 200 OK
{
"id":"119",
"name":"HSBC",
"branch_name":"",
"base_url":"https://www.hsbc.fr/1/2/hsbc-france/particuliers/connexion",
"country_code":"FRA",
"channel_definitions":[{
"id":"redirect1",
"mode":"REDIRECT",
"account_types": [
"CHECKINGS","CREDIT_CARD"
],
"credentials":[]
},{
"id":"embedded1",
"mode":"EMBEDDED",
"account_types": [
"SAVINGS","LOAN"
],
"credentials":[
{
"id":"3500",
"label":"Identifiant",
"regexp":"^[\\a-zA-Z0-9@._-]{7,}$",
"type":"TEXT",
"encrypt":false
},
{
"id":"3501",
"label":"Réponse mémorable",
"regexp":".+",
"type":"PWD",
"encrypt":false
},
{
"id":"3502",
"label":"Mot de passe (8 car. min.)",
"regexp":"^.{8,}$",
"type":"PWD",
"encrypt":true
}
]
}],
"interactive":false
}

If your are interested in savings accounts for instance, you will need to provide the embedded channel definition. The associated credentials table, the credential of ID 301 has the property encrypted: true. It will be necessary to encrypt the value using a PGP key.

Credentials encryption requires a PGP encryption key that you can generate using our API.

On the client side, you will retrieve the public key you just created to encrypt the credential.

# Creates the encryption key
curl -X POST \
{baseUrl}/keys \
-H 'authorization: Bearer {access_token}' \
-d '{
"type": "PGP"
}'

# it returns the key id in the header location
HTTP/1.1 201 Created
location: /keys/{key_id}

# Gets the encryption key
curl -sk GET \
{baseUrl}/keys/{key_id} \
-H 'authorization: Bearer {access_token}'

# Returns the key
{
"id": "87",
"public_key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: BCPG v1.43\n\nmI0EWxAaPgEEAJXZ9xLObAvsysbK27XAW2JRMVjf4Zh0XnkyDi78d1iIQo7JbKKH\ndUzHFZvXOVkGGaITb3fjozQqAWW1nAuQpXLcQU4rg0nhCU4KYCykK0MulR70Of5/\nReklDBtrbtmctQEsVux4fO+bidha1dz0l/sbpXgpVc4CY8oopjXuQDxBABEBAAG0\nCUxJTlhPIFNBU4icBBABAgAGBQJbEBo+AAoJELqVveObg+d4G74D/i0ikaoiUT6T\nsuo4nYGvcIrphslb+P3WWcP4ITJ7V9+fKLNg0z50ZwRHXs1xu8h/DXAl6qRaKX+j\n0OQmRk6sDkTe229WbIHhK5v572v0jHSOlJvGqGgXgFEMIeAnECKOS+GqZpn/CYRj\nMKe41DKSwo65mEb/Zb4sF41PWh1KntR5\n=2l0S\n-----END PGP PUBLIC KEY BLOCK-----\n",
"type": "PGP",
"expiration_date": 1527785550
}

# Encrypt the credential (encrypt: true) with the PGP library of your choice, here
-----BEGIN PGP MESSAGE-----
Version: BCPG v1.43

hIwDwj9RkuzOAeMBA/9iuYDAGJ6QcZZaGLzF2hLNG+cdCIIZl3Yva9y+q12JpuIz
hlsOuxdYaIQ/KVsQHj7tMULNkKrbLa6mzL2I/tzzbS1ZXXe43Xwcpk76zOPeqikx
gjTT4ND0gz2NWu2rNAml9Fau/1MsMTNBWXQpBFHooa9QkamYB9MBux/BQKp0Mckl
hERvVwT6pbXZu+aomrbksBonZYbFt66DQDq7lv3tpWOJht5m1Q==
=a6mL
-----END PGP MESSAGE-----

Create the connection

To create the connection, you must provide a channel with a list of credentials representing the user input according to the credentials of the provider.

Once the connection is created, a synchronization will be triggered and the associated bank accounts will be automatically listed.

If you wish, you can follow the synchronization progress by subscribing to a queue and poll it every X seconds.

Example :

# [OPTIONAL] Subscribes to a queue with 
curl -X POST \
{baseUrl}/queues/subscribe \
-H 'authorization: Bearer {access_token}' \
-d '{
"topics": ["connections"]
}'

# [OPTIONAL] It returns the queue id in the header location
HTTP/1.1 201 Created
location: /queues/{queue_id}

# [OPTIONAL] If you poll the queue, events stack in the queue
curl -sk {baseUrl}/queues/{queue_id} \
-H 'authorization: Bearer {access_token}'

Whether you decide to follow the triggered synchronization or not, all you have to do is to create the connection.

# To create a connection, you must provide the financial institution identifier, 
# the encryption key identifier and the list of credentials required
# to authenticate the user on the financial institution.
curl -X POST \
{baseUrl}/connections \
-H 'authorization: Bearer {access_token}'
-d '{
"provider_id": "87",
"key_id": "{key_id}",
"credentials": [
{ "id": "300", "value": "dev" },
{ "id": "301", "value": "-----BEGIN PGP MESSAGE-----\nVersion: BCPG v1.43\n\nhIwDwj9RkuzOAeMBA/9iuYDAGJ6QcZZaGLzF2hLNG+cdCIIZl3Yva9y+q12JpuIz\nhlsOuxdYaIQ/KVsQHj7tMULNkKrbLa6mzL2I/tzzbS1ZXXe43Xwcpk76zOPeqikx\ngjTT4ND0gz2NWu2rNAml9Fau/1MsMTNBWXQpBFHooa9QkamYB9MBux/BQKp0Mckl\nhERvVwT6pbXZu+aomrbksBonZYbFt66DQDq7lv3tpWOJht5m1Q==\n=a6mL\n-----END PGP MESSAGE-----\n" },
{ "id": "302", "value": "https://www.dropbox.com/s/2j3d4gcrd031fkc/sanity.txt?dl=1" }
]
}'

# Returns connection id in header
HTTP/1.1 201 Created
location: /connections/{connection_id}

User input and challenge

Some Providers require the user to respond to a challenge to continue synchronization. The user can receive a code on his phone for example. In the API, providers have an interactive property that allows you to know if a challenge will be proposed to the user.

During synchronization, you will receive events with a specific event_status:

  • SYNC_ALL_USER_INPUT_REQUESTED: The user must respond to a challenge during a synchronization
  • LIST_ACCOUNTS_USER_INPUT_REQUESTED: The user must respond to a challenge during the recovery of his accounts at a Provider

Challenge and user input

Identify a challenge

When you poll the queue, you will have an event with event_status: "LIST_ACCOUNTS_USER_INPUT_REQUESTED" (or SYNC_ALL_USER_INPUT_REQUESTED).

This event will contain several pieces of information:

  • the resource property: the connection associated with the event. The id of the connection will be necessary to answer the challenge
  • the event_status property : LIST_ACCOUNTS_USER_INPUT_REQUESTED (or SYNC_ALL_USER_INPUT_REQUESTED)
  • a property containing the challenges called list_accounts_user_input_requested (or sync_all_user_input_requested)

Here is an example of an event:

{
"id":"14",
"event_type":"LIST_ACCOUNTS_USER_INPUT_REQUESTED",
"resource_type":"CONNECTION",
"creation_date":1528199358,
"channel_definition_id":"embedded1",
"resource":{
"id":"17730",
"provider_id":"87",
"name":"Test Bank",
"status":"SUCCESS",
"channels": [
{
"id": "redirect1",
"expires": 1528106353
"status": "SUCCESS"
},
{
"id": "embedded1",
"status": "RUNNING"
}
],
"creation_date":0,
"last_success_date":1528199340,
"last_end_date":1528199340
},
"list_accounts_user_input_requested":{
"challenge":[
{
"id":"303",
"label":"La connexion à Banque demande la saisie d’un code envoyé par SMS sur votre téléphone au {phone}. Souhaitez vous recevoir ce code maintenant ?",
"regexp":".*",
"type":"INFO_MSG",
"encrypt":false,
"params":{
"phone":"0606060606"
}
},
{
"id":"304",
"label":"Envoyer le SMS",
"regexp":".*",
"type":"OK_CANCEL",
"encrypt":false
}
]
}
}

list_accounts_user_input_requested (or sync_all_user_input_requested) is a challenge array. The type property informs about the type of challenge:

  • INFO_MSG: This challenge is an informative message (example: a code has been sent on your phone)
  • OK_CANCEL: This challenge simulates the action of a user who would have answered OK (true) or CANCEL (false)
  • NUMERIC: This challenge expects the answer provided is a number
  • TEXT: This challenge expects the answer provided is a text
  • PWD: This challenge expects the answer provided is a password
  • NUMERIC_PWD: This challenge expects the answer provided is a numeric password
  • DATE: This challenge expects the answer provided is a date
  • TIMEOUT_MSG: In general, the answers to a challenge are limited in time, this message informs about the remaining duration
  • ERROR_MSG: This message is an error message. It happens when the response to a challenge is wrong

Challenges can have a params property. These parameters are information to be integrated in challenges displaying messages. The label property of the challenge will contain a moustache variable (example: {phone}) and in the parameters is the value of this variable

Example:

{
"id":"303",
"label":"La connexion à Banque demande la saisie d’un code envoyé par SMS sur votre téléphone au {phone}. Souhaitez vous recevoir ce code maintenant ?",
"regexp":".*",
"type":"INFO_MSG",
"encrypt":false,
"params":{
"phone":"0606060606"
}
}

# You should replace {phone} by 0606060606 in your interface

Respond to challenge

During a synchronization, you will receive this challenge :

{
"id":"14",
"event_type":"LIST_ACCOUNTS_USER_INPUT_REQUESTED",
"resource_type":"CONNECTION",
"channel_definition_id":"embedded1",
"creation_date":1528199358,
"resource":{
"id":"17730",
"provider_id":"87",
"name":"Test Bank",
"channels": [
{
"id": "redirect1",
"expires": 1528106353
"status": "SUCCESS",
"last_success_date":1528199340,
"last_end_date":1528199340
},
{
"id": "embedded1",
"status": "RUNNING",
"last_success_date":1528199340,
"last_end_date":1528199340
}
],
"status":"SUCCESS",
"creation_date":0
},
"list_accounts_user_input_requested":{
"challenge":[
{
"id":"303",
"label":"La connexion à Banque demande la saisie d’un code envoyé par SMS sur votre téléphone au {phone}. Souhaitez vous recevoir ce code maintenant ?",
"regexp":".*",
"type":"INFO_MSG",
"encrypt":false,
"params":{
"phone":"0606060606"
}
},
{
"id":"304",
"label":"Envoyer le SMS",
"regexp":".*",
"type":"OK_CANCEL",
"encrypt":false
}
]
}
}

This challenge proposes to the user to receive a code on his phone number. This is the information we retrieved from the Provider. You must propose to the user to answer "OK" (true) or "CANCEL" (false).

If the user answers "OK", synchronization continues. If he answers "CANCEL", the synchronization stops. If he does not respond, synchronization will fail and the connection will have the status: "CHALLENGE_TIMED_OUT".

# The user respond "OK" on your interface, you have to send 
curl -X POST \
{baseUrl}/connections/{connection_id}/channels/{channel_definition_id}/user_input \
-H 'authorization: Bearer {access_token}' \
-d '{"credentials":[{"id":"304","value":"true"}]}'

# The user respond "CANCEL" on your interface, you have to send
curl -X POST \
{baseUrl}/connections/{connection_id}/channels/{channel_definition_id}/user_input \
-H 'authorization: Bearer {access_token}' \
-d '{"credentials":[{"id":"304","value":"false"}]}'

# The synchronization continues an new events are queued
HTTP/1.1 204 No-Content

In this example, the user has just accepted a code to be sent to him on his phone. Synchronization will continue and another challenge will be proposed to the user. You will have to adapt your interface to offer him the input of the code he will receive.

{
"id":"17",
"event_type":"LIST_ACCOUNTS_USER_INPUT_REQUESTED",
"resource_type":"CONNECTION",
"channel_definition_id":"embedded1",
"creation_date":1528199358,
"resource":{
"id":"17730",
"provider_id":"87",
"name":"Test Bank",
"channels": [
{
"id": "redirect1",
"expires": 1528106353
"status": "SUCCESS",
"creation_date":0,
"last_success_date":1528199340,
"last_end_date":1528199340
},
{
"id": "embedded1",
"status": "RUNNING",
"creation_date":0,
"last_success_date":1528199340,
"last_end_date":1528199340
}
],
"status":"SUCCESS"
},
"list_accounts_user_input_requested":{
"challenge":[
{
"id":"305",
"label":"Un code a été envoyé par SMS sur votre téléphone au {phone}.",
"regexp":".*",
"type":"INFO_MSG",
"encrypt":false,
"params":{
"phone":"0606060606"
}
},
{
"id":"309",
"label":"Code invalide. Encore {remaining_attempts} tentatives",
"regexp":".*",
"type":"ERROR_MSG",
"encrypt":false,
"params":{
"remaining_attempts":"1"
}
},
{
"id":"306",
"label":"Code",
"regexp":"^[0-9]{6}$",
"type":"NUMERIC",
"encrypt":false
},
{
"id":"308",
"label":"Il vous reste {timeout} pour valider votre code.",
"regexp":".*",
"type":"TIMEOUT_MSG",
"encrypt":false,
"params":{
"timeout":"120"
}
},
{
"id":"307",
"label":"Valider",
"regexp":".*",
"type":"OK_CANCEL",
"encrypt":false
}
]
}
}

This event contains 4 challenges. 2 are messages :

  • INFO_MSG (identifier 305): We learn that the code has been sent on the phone number
  • TIMEOUT_MSG (identifier 308) : We learn that the user still has {timeout} seconds to send the received code by message. You can replace the mustache variable by the value provided in the property params of the challenge

So there are only two remaining challenges to deal with:

  • NUMERIC (identifier 306): This is the value that the user must enter. The encrypt: false property allows us to understand that the message does not have to be encrypted. It is accompanied by a regexp property allowing you to validate the user's entry
  • OK_CANCEL (identifier 307): We have already encountered this case in the previous event. The user's action is simulated. He enters his code and clicks on "OK" or he decides to abandon synchronization and clicks on "CANCEL"
# Send the input of the user to continue synchronization.
curl -X POST \
{baseUrl}}/connections/{connection_id}/channels/{channel_definition_id}/user_input \
-H 'authorization: Bearer {access_token}' \
-d '{"credentials":[{"id":"306","value":"123456","id":"307","value":"true"}]}'

# Send the cancel action from the user
curl -X POST \
{baseUrl}}/connections/{connection_id}/channels/{channel_definition_id}/user_input \
-H 'authorization: Bearer {access_token}' \
-d '{"credentials":[{"id":"307","value":"false"}]}'

# The input has been received and the synchronization will continue
HTTP/1.1 204 No-Content

And what happens if the user enters the wrong code?

Synchronization brings up a new event containing a challenge that is an error message. You can display it on your interface.

{
"id":"17",
"event_type":"LIST_ACCOUNTS_USER_INPUT_REQUESTED",
"channel_definition_id":"embedded1",
"resource_type":"CONNECTION",
"creation_date":1528199358,
"resource":{
"id":"17730",
"provider_id":"87",
"name":"Test Bank",
"channels": [
{
"id": "redirect1",
"expires": 1528106353
"status": "SUCCESS",
"last_success_date":1528199340,
"last_end_date":1528199340
},
{
"id": "embedded1",
"status": "RUNNING",
"last_success_date":1528199340,
"last_end_date":1528199340
}
],
"status":"SUCCESS",
"creation_date":0
},
"list_accounts_user_input_requested":{
"challenge":[
{
"id":"305",
"label":"Un code a été envoyé par SMS sur votre téléphone au {phone}.",
"regexp":".*",
"type":"INFO_MSG",
"encrypt":false,
"params":{
"phone":"0606060606"
}
},
{
"id":"309",
"label":"Code invalide. Encore {remaining_attempts} tentatives",
"regexp":".*",
"type":"ERROR_MSG",
"encrypt":false,
"params":{
"remaining_attempts":"1"
}
},
{
"id":"306",
"label":"Code",
"regexp":"^[0-9]{6}$",
"type":"NUMERIC",
"encrypt":false
},
{
"id":"308",
"label":"Il vous reste {timeout} pour valider votre code.",
"regexp":".*",
"type":"TIMEOUT_MSG",
"encrypt":false,
"params":{
"timeout":"120"
}
},
{
"id":"307",
"label":"Valider",
"regexp":".*",
"type":"OK_CANCEL",
"encrypt":false
}
]
}
}

The new event contains an event with a type property: "ERROR_MSG". The event explains that there are still {remaining_attempts} attempts to the user. He must resubmit his code, but it must be correct this time.

Add a channel to an existing connection

Adding a channel to an existing connection follows the same procedure as updating credentials for an EMPTY channel in a connection:

Example : Get a connection status:

# List channels in a connection
curl -s {baseUrl}/v2.1/connectionconnections/18902 -H "authorization: Bearer {access_token}"

# Response
HTTP/1.1 200 OK
{
"id" : "18902",
"provider_id" : "87",
"name" : "Linxo Test Bank",
"status" : "SUCCESS",
"creation_date" : 1562233640,
"auto_sync" : true,
"logo_url" : "https://static.linxo-connect.io/common/pictures/providers_logos/87.png",
"channels" : [ {
"channel_definition_id" : "8701",
"mode" : "REDIRECT",
"expires" : 1569974400,
"status" : "NEVER",
"credentials" : [ ],
"account_types" : [ "CHECKINGS", "CREDIT_CARD" ]
}, {
"channel_definition_id" : "13400",
"mode" : "EMBEDDED",
"status" : "EMPTY",
"account_types" : [ "LOAN", "CREDIT_CARD" ]
} ],
"owner" : { }
}

In this example, updating credentials for channel_definition_id=13400 will add an embedded channel on this conection.

Update credentials for a channel

Leaving a channel in a failure state leads to a break in the data sync. On a REDIRECT channel, credential expiration can be prevented by renewing the authentiction before the expiration date. This is made by using the expires property of the channel in the connection resource.

Example: Fetch status for a specific connection:

#
curl -s {baseUrl}/v2.1/connections/18903 -H "authorization: Bearer {access_token}"
{
"id" : "18903",
"provider_id" : "182",
"name" : "Demo Bank",
"status" : "FAILED",
"creation_date" : 1562233721,
"auto_sync" : true,
"logo_url" : "https://static.linxo-connect.io/common/pictures/providers_logos/182.png",
"channels" : [ {
"channel_definition_id" : "17650",
"mode" : "EMBEDDED",
"status" : "AUTH_FAILED",
"last_success_date" : 1562233742,
"last_end_date" : 1562233742,
"credentials" : [ {
"id" : "10001",
"masked_value" : "**mo"
} ],
"account_types" : [ "CHECKINGS", "SAVINGS", "LOAN", "CREDIT_CARD" ]
} ],
"owner" : {
"name" : "Mr Test",
"address" : "address test",
"birth_date" : 1562233742,
"birth_place" : "birth place test",
"phone_number" : "06******1"
}
}

In this example, the connection is in FAILED status because its only channel is in AUTH_FAILED status. To fix the issue and restore the link with the bank, the user needs to update its password using an embedded form.

Updating credentials is made using a web redirection for REDIRECT channels and using a form for EMBEDDED channels in the same way we used to create the channel.

Update credentials for a redirect channel

For a REDIRECT channel, we will generate a new authorize URL using our connection_id and channel_definition_id. After the authentication and the redirect is made, our system will update the credentials.

Example : Create an authorize URL on HSBC.

# Generate the authorize URL for HSBC on existing connection
curl -ski POST \
{baseUrl}/providers/119/channel_definitions/100/authorize_url \
-H 'authorization: Bearer {access_token}'
-H 'Content-Type: application/json'
-d '{
"connection_id" : "123",
"channel_definition_id" : "redirect1",
"redirect_uri" : "https://<api-client-url>",
"widget_params" : {
"access_token" : "<access_token>",
"refresh_token" : "<refresh_token>",
"client_id" : "<client_id>",
"client_secret' : "<client_secret>",
"captive_mode" : false
}
}'

# Response
HTTP/1.1 201 OK
location: https://hsbc.fr/ca-paris/authorize?response_type=code&client_id=psdfr-bdf-16928&redirect_uri=https%3A%2F%2Fembed.linxo-connect.io%2Foauth2%2Faisp&scope=aisp%20extended_transaction_history&state={session_id}

Update credentials for an embedded channel

For an embedded channel, you will have to buid the form like in the channel creation but the credentials will be updated using PUT /connections/{id}/channels/{channel_definition_id}.

Example: Update all credentials for a channel

curl -X PUT \
{baseUrl}/connections/{id}/channels/{channel_id} \
-H 'authorization: Bearer {access_token}'
-d '{
"id": "{channel_definition_id}",
"key_id": "{key_id}",
"credentials": [
{ "id": "3500", "value": "0123456" },
{ "id": "3501", "value": "test" },
{ "id": "3502", "value": "-----BEGIN PGP MESSAGE-----\nVersion: BCPG v1.43\n\nhIwDwj9RkuzOAeMBA/9iuYDAGJ6QcZZaGLzF2hLNG+cdCIIZl3Yva9y+q12JpuIz\nhlsOuxdYaIQ/KVsQHj7tMULNkKrbLa6mzL2I/tzzbS1ZXXe43Xwcpk76zOPeqikx\ngjTT4ND0gz2NWu2rNAml9Fau/1MsMTNBWXQpBFHooa9QkamYB9MBux/BQKp0Mckl\nhERvVwT6pbXZu+aomrbksBonZYbFt66DQDq7lv3tpWOJht5m1Q==\n=a6mL\n-----END PGP MESSAGE-----\n" }
]
}'

HTTP/1.1 204 No Content

Alternatively, you can update a single credential using PUT /connections/{connection_id}/credentials/{credential_id} to avoid making the user input its identifier for instance. You can also display the masked_value of the identifier present in the connection resource.