It is only possible to import a bank connection. There are no services for importing or updating individual accounts. Accounts relate to bank connections, and whenever you import or update a bank connection, all accounts associated with this bank connection are imported/updated.

Prerequisites

Step 1 - Initiate a bank connection import

To initiate a bank connection import, please use Import a new bank connection endpoint:

POST /api/v1/bankConnections/import
CODE

The payload and the flow varies based on the SCA approach offered by the bank (in the API: properties of the bank interface - bank.interface.properties).

Some banks have implemented the Embedded SCA approach, where the user credentials and the second factor can be submitted to the bank via the TPP.

Some banks will require a redirect to the bank server to complete the authentication and second-factor verification. This is the so-called Redirect SCA.

Some banks allow the authorisation with the Decoupled SCA approach, where users could authenticate and authorize a transaction via the mobile app or an authorisation device.

The combination of different SCA approaches is also possible. For example Embedded + Decoupled: a user will provide the login credentials to a TPP and then a push notification will be sent to the mobile application.

Please make sure your application is able to dynamically handle all variations.

Please refer to the API specification for more details.

It is mandatory to indicate the interface that should be used for the import.

If you are not familiar with the interfaces which are supported by finAPI, please check Interfaces .

Please see below the examples of the flows for each SCA approach: Redirect, Embedded and Decoupled.

Embedded approach

When applicable?

If a bank interface has neither DECOUPLED_APPROACH nor REDIRECT_APPROACH properties.

Step

Request/response example

Step #1
Import a new bank connection

Mandatory request fields

  • bankId

  • interface

  • loginCredentials

    • if the chosen bank interface has any items inloginCredentials field

  • accountReferences

    • if the chosen bank interface has DETAILED_CONSENT property

Explanation

The client application loads a bank chosen by the end-user. Then the application asks the end-user for credentials if they are required by the bank interface. Also, the application checks whether the chosen bank interface has DETAILED_CONSENT property: if it’s presented, the app asks the end-user for a list of IBANs he wants to import. Finally, the application triggers the “Import a new bank connection” REST service.

POST /api/v1/bankConnections/import HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <user's access token>

{
  "bankId": 280001,
  "interface": "XS2A",
  "loginCredentials": [
    {
      "label": "Onlinebanking-ID",
      "value": "demo"
    },
    {
      "label": "PIN",
      "value": "123456"
    }
  ],
  "accountReferences": [
    {
      "iban": "DE89370400440532013000"
    }
  ]
}
JSON

Step #2
Receive a list of two step procedures
(an optional step)

How to recognise the step

Field errors.multiStepAuthentication.status has TWO_STEP_PROCEDURE_REQUIRED value.

Mandatory response fields of multiStepAuthentication object:

  • hash

  • status

  • twoStepProcedures

Explanation

If the bank decides, it responds with a list of available two-step procedures (aka SCA methods - Strong Customer Authentication methods). And, then the client application should ask the end-user to choose one of the offered two-step procedures.

HTTP/1.1 510

{
  "errors": [
    {
      "message": "SCA method selection is required",
      "code": "ADDITIONAL_AUTHENTICATION_REQUIRED",
      "type": "BUSINESS",
      "multiStepAuthentication": {
        "hash": "112c3581b39fc95a1f979d0d73f14dfb",
        "status": "TWO_STEP_PROCEDURE_REQUIRED",
        "challengeMessage": null,
        "answerFieldLabel": null,
        "redirectUrl": null,
        "redirectContext": null,
        "redirectContextField": null,
        "twoStepProcedures": [
          {
            "procedureId": "DEMO-TSP-01",
            "procedureName": "SMS",
            "procedureChallengeType": "TEXT",
            "implicitExecute": false
          },
          {
            "procedureId": "DEMO-TSP-02",
            "procedureName": "PUSH",
            "procedureChallengeType": "TEXT",
            "implicitExecute": false
          }
        ],
        "photoTanMimeType": null,
        "photoTanData": null,
        "opticalData": null
      }
    }
  ],
  "date": "2019-11-27 08:13:32.155",
  "requestId": "selfgen-3c81395b-7e01-40d2-835e-300ba9af1399",
  "endpoint": "POST /api/v1/bankConnections/import",
  "authContext": "1/18",
  "bank": "DEMO0001- FinAPI Test Bank"
}
JSON

Step #3
Import a new bank connection
(an optional step)

Mandatory request fields

  • all fields from the previous request

  • multiStepAuthentication.hash

    • the value should be taken from the response on step #2

  • twoStepProcedureId

    • field procedureId of the chosen two-step procedure

Explanation

The client application asks the end-user to choose a two-step procedure and then submits it to the API. Value of hash field points to the original request.

POST /api/v1/bankConnections/import HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <user's access token>

{
  "bankId": 280001,
  "interface": "XS2A",
  "loginCredentials": [
    {
      "label": "Onlinebanking-ID",
      "value": "demo"
    },
    {
      "label": "PIN",
      "value": "123456"
    }
  ],
  "accountReferences": [
    {
      "iban": "DE89370400440532013000"
    }
  ],
  "multiStepAuthentication": {
    "hash": "112c3581b39fc95a1f979d0d73f14dfb",
    "twoStepProcedureId": "DEMO-TSP-01"
  }
}
JSON

Step #4
Receive an MSA challenge message

How to recognise the step

Field errors.multiStepAuthentication.status has CHALLENGE_RESPONSE_REQUIRED value.

Mandatory response fields of multiStepAuthentication object:

  • hash

  • status

  • the following fields are presented depending on the two-step procedure type:

    • for type = TEXT:

      • challengeMessage

    • for type = PHOTO:

      • photoTanMimeType

      • photoTanData

    • for type = FLICKER_CODE*:

      • opticalData

*Note: feel free to use the flicker code template prepared by finAPI: Flicker Code Template

Explanation

When the two-step procedure is chosen (either by the bank or by the end-user), the API responds with details for the end-user. The client application should show this info to the end-user and ask for an answer.

HTTP/1.1 510

{
  "errors": [
    {
      "message": "Es ist eine zusätzliche Authentifizierung erforderlich. Bitte geben Sie folgenden Code an: demo",
      "code": "ADDITIONAL_AUTHENTICATION_REQUIRED",
      "type": "BUSINESS",
      "multiStepAuthentication": {
        "hash": "112c3581b39fc95a1f979d0d73f14dfb",
        "status": "CHALLENGE_RESPONSE_REQUIRED",
        "challengeMessage": "Es ist eine zusätzliche Authentifizierung erforderlich. Bitte geben Sie folgenden Code an: demo",
        "answerFieldLabel": "TEXT",
        "redirectUrl": null,
        "redirectContext": null,
        "redirectContextField": null,
        "twoStepProcedures": null,
        "photoTanMimeType": null,
        "photoTanData": null,
        "opticalData": null
      }
    }
  ],
  "date": "2019-11-27 08:19:23.957",
  "requestId": "selfgen-e5a38d80-bf99-47f2-b4f0-1e32717de72a",
  "endpoint": "POST /api/v1/bankConnections/import",
  "authContext": "1/18",
  "bank": "DEMO0001- FinAPI Test Bank"
}
JSON

Step #5
Import a new bank connection

Mandatory request fields

  • all fields from the previous request

  • challengeResponse

    • the answer from the end-user

Explanation

The client application asks for the challenge reponds and submits it back to the API. Value of hash field points to the original request.

POST /api/v1/bankConnections/import HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <user's access token>

{
  "bankId": 280001,
  "interface": "XS2A",
  "loginCredentials": [
    {
      "label": "Onlinebanking-ID",
      "value": "demo"
    },
    {
      "label": "PIN",
      "value": "123456"
    }
  ],
  "accountReferences": [
    {
      "iban": "DE89370400440532013000"
    }
  ],
  "multiStepAuthentication": {
    "hash": "112c3581b39fc95a1f979d0d73f14dfb",
    "twoStepProcedureId": "DEMO-TSP-01",
    "challengeResponse": "demo"
  }
}
JSON

Step #6
Bank connection

The API completes the import process and returns a bank connection resource.

HTTP/1.1 201

{
  "id": 21,
  "bankId": 280001,
  "name": null,
  "bankingUserId": null,
  "bankingCustomerId": null,
  "bankingPin": null,
  "type": "DEMO",
  "updateStatus": "IN_PROGRESS",
  "categorizationStatus": "READY",
  ...
}
JSON

Redirect approach

When applicable?

If a bank interface has REDIRECT_APPROACH property.

Step

Request/response example

Step #1
Import a new bank connection.

Mandatory request fields

  • bankId

  • interface

  • redirectUrl

    • URL of the client’s endpoint that handles a redirect from the bank

  • loginCredentials

    • if the chosen bank interface has any items in

    loginCredentials field

  • accountReferences

    • if the chosen bank interface has

    DETAILED_CONSENT property

Explanation

The client application loads a bank, chosen by the end-user. Then the application asks the end-user for credentials if they are required by the bank interface. Also, the application checks whether the chosen bank&interface has DETAILED_CONSENT property: if it’s presented, the app asks the end-user for a list of IBANs he wants to import. Finally, the application triggers the “Import a new bank connection” REST service.

POST /api/v1/bankConnections/import HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <user's access token>

{
  "bankId": 280002,
  "interface": "XS2A",
  "redirectUrl": "https://customer1.io",
  "loginCredentials": [
    {
      "label": "Onlinebanking-ID",
      "value": "idontexist"
    }
  ],
  "accountReferences": [
    {
      "iban": "DE89370400440532013000"
    }
  ]
}
JSON

Step #2
Receive a redirect URL

How to recognise the step

Field errors.multiStepAuthentication.status has REDIRECT_REQUIRED value.

Mandatory response fields of multiStepAuthentication object:

  • hash

  • status

  • redirectUrl

  • redirectContext

  • redirectContextField

Explanation

The API builds a redirect URL that will route the end-user to a page on the bank side, where the user can complete the authentication process. In this step, the client’s application should store values from redirectContext and redirectContextField fields internally, as they will be required in the subsequent steps.

HTTP/1.1 510 

{
  "errors": [
    {
      "message": null,
      "code": "ADDITIONAL_AUTHENTICATION_REQUIRED",
      "type": "BUSINESS",
      "multiStepAuthentication": {
        "hash": "288c0a78c6596e8f02f70a21e731d46a",
        "status": "REDIRECT_REQUIRED",
        "challengeMessage": null,
        "answerFieldLabel": null,
        "redirectUrl": "https://demobank.finapi.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0",
        "redirectContext": "976641d2-c03f-4919-8dac-16ccfd24b4e0",
        "redirectContextField": "state",
        "twoStepProcedures": null,
        "photoTanMimeType": null,
        "photoTanData": null,
        "opticalData": null
      }
    }
  ],
  "date": "2019-11-27 11:20:21.261",
  "requestId": "selfgen-fece3d6c-a0f0-43ea-a910-7e9ca7a7b1f6",
  "endpoint": "POST /api/v1/bankConnections/import",
  "authContext": "1/18",
  "bank": "DEMO0002 - finAPI Test Redirect Bank"
}
CODE

Step #3
Redirect to bank

The client application should redirect the end-user to the given redirectUrl.

Example

GET https://demobank.finapi.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0 HTTP/1.1
CODE

Step #4
Redirect back

When the end-user successfully completes the authentication process on the bank’s side, he is redirected to the URL given in the step #1. Additionally, the bank adds some more data to the URL (as query parameters). But the most important part for the client application is this state parameter (generally speaking, the name of the parameter is provided on step #2 as a value of redirectContextField field): the client application can use its value to recognize the end-user that was redirected by the bank - the value should match the one given on a step #2 in redirectContext field.

Example

GET https://customer.io?state=976641d2-c03f-4919-8dac-16ccfd24b4e0&code=1e065516-0e9a-4f53-b5a6-140e69a3bf70 HTTP/1.1
CODE

Step #5
Import a bank connection

Mandatory request fields

  • all fields from the previous request

  • hash

  • redirectCallback

    • the whole query string received on a step #4

Explanation

The client application submits a query string as a value of redirectCallback field. The API processes the given string, extracts required data and continues the authentication process.

POST /api/v1/bankConnections/import HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <user's access token>

{
  "bankId": 280002,
  "interface": "XS2A",
  "redirectUrl": "https://customer1.io",
  "loginCredentials": [
    {
      "label": "Onlinebanking-ID",
      "value": "idontexist"
    }
  ],
  "accountReferences": [
    {
      "iban": "DE89370400440532013000"
    }
  ],
  "multiStepAuthentication": {
    "hash": "288c0a78c6596e8f02f70a21e731d46a",
    "redirectCallback": "state=976641d2-c03f-4919-8dac-16ccfd24b4e0&code=1e065516-0e9a-4f53-b5a6-140e69a3bf70"
  }
}
CODE

Step #6
Bank connection

The API completes the import process and returns a bank connection resource.

HTTP/1.1 201

{
  "id": 46,
  "bankId": 280002,
  "name": null,
  "bankingUserId": null,
  "bankingCustomerId": null,
  "bankingPin": null,
  "type": "ONLINE",
  "updateStatus": "IN_PROGRESS",
  "categorizationStatus": "READY",
  ...
}
CODE

Decoupled approach

When applicable?

If a bank interface has DECOUPLED_APPROACH property.

Step

Request/response example

Step #1
Import a new bank connection

Mandatory request fields

  • bankId

  • interface

  • loginCredentials

    • if the chosen bank interface has any items in

    loginCredentials field

  • accountReferences

    • if the chosen bank interface has

    DETAILED_CONSENT property

Explanation

The client application loads a bank, chosen by the end-user. Then the application asks the end-user for credentials if they are required by the bank interface. Also, the application checks whether the chosen bank interface has DETAILED_CONSENT property: if it’s presented, the app asks the end-user for a list of IBANs he wants to import. Finally, the application triggers the “Import a new bank connection” REST service.

POST /api/v1/bankConnections/import HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <user's access token>

{
  "bankId": 277672,
  "interface": "XS2A",
  "loginCredentials": [
    {
      "label": "Onlinebanking-ID",
      "value": "idontexist"
    },
    {
      "label": "PIN",
      "value": "1337"
    }
  ],
  "accountReferences": [
    {
      "iban": "DE89370400440532013000"
    }
  ]
}
CODE

Step #2
Receive a list of two step procedures
(an optional step)

How to recognise the step

Field errors.multiStepAuthentication.status has TWO_STEP_PROCEDURE_REQUIRED value.

Mandatory response fields of multiStepAuthentication object:

  • hash

  • status

  • twoStepProcedures

Explanation

If the bank decides, it responds with a list of available two-step procedures (aka SCA methods - Strong Customer Authentication methods). And, then the client application should ask the end-user to choose one of the offered two-step procedures.

HTTP/1.1 510

{
  "errors": [
    {
      "message": "SCA method selection is required",
      "code": "ADDITIONAL_AUTHENTICATION_REQUIRED",
      "type": "BUSINESS",
      "multiStepAuthentication": {
        "hash": "112c3581b39fc95a1f979d0d73f14dfb",
        "status": "TWO_STEP_PROCEDURE_REQUIRED",
        "challengeMessage": null,
        "answerFieldLabel": null,
        "redirectUrl": null,
        "redirectContext": null,
        "redirectContextField": null,
        "twoStepProcedures": [
          {
            "procedureId": "DEMO-TSP-01",
            "procedureName": "SMS",
            "procedureChallengeType": "TEXT",
            "implicitExecute": false
          },
          {
            "procedureId": "DEMO-TSP-02",
            "procedureName": "PUSH",
            "procedureChallengeType": "TEXT",
            "implicitExecute": false
          }
        ],
        "photoTanMimeType": null,
        "photoTanData": null,
        "opticalData": null
      }
    }
  ],
  "date": "2019-11-27 08:13:32.155",
  "requestId": "selfgen-3c81395b-7e01-40d2-835e-300ba9af1399",
  "endpoint": "POST /api/v1/bankConnections/import",
  "authContext": "1/18",
  "bank": "00000000 - FinAPI Test Bank"
}
CODE

Step #3
Import a new bank connection
(an optional step)

Mandatory request fields

  • all fields from the previous request

  • multiStepAuthentication.hash

    • the value should be taken from the response on step #2

  • twoStepProcedureId

    • field

    procedureId of the chosen two-step procedure

Explanation

The client application asks the end-user to choose a two-step procedure and then submits it to the API. Value of hash field points to the original request.

POST /api/v1/bankConnections/import HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <user's access token>

{
  "bankId": 277672,
  "interface": "XS2A",
  "loginCredentials": [
    {
      "label": "Onlinebanking-ID",
      "value": "idontexist"
    },
    {
      "label": "PIN",
      "value": "1337"
    }
  ],
  "accountReferences": [
    {
      "iban": "DE89370400440532013000"
    }
  ],
  "multiStepAuthentication": {
    "hash": "112c3581b39fc95a1f979d0d73f14dfb",
    "twoStepProcedureId": "DEMO-TSP-01"
  }
}
CODE

Step #4
Receive an error message that the decoupled approach is required

How to recognise the step

Field errors.multiStepAuthentication.status has DECOUPLED_AUTH_REQUIRED value.

Mandatory response fields of multiStepAuthentication object:

  • hash

  • status

  • challengeMessage

    • if any message was provided by the bank

Explanation

If the chosen two-step procedure was of a decoupled type, the API responds with this error. The client application should notify the end-user that the bank will send a notification.

HTTP/1.1 510

{
  "errors": [
    {
      "message": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung",
      "code": "ADDITIONAL_AUTHENTICATION_REQUIRED",
      "type": "BUSINESS",
      "multiStepAuthentication": {
        "hash": "8f3bb2a7a1c6fec906c62465562e1dba",
        "status": "DECOUPLED_AUTH_REQUIRED",
        "challengeMessage": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung",
        "answerFieldLabel": null,
        "redirectUrl": null,
        "redirectContext": null,
        "redirectContextField": null,
        "twoStepProcedures": null,
        "photoTanMimeType": null,
        "photoTanData": null,
        "opticalData": null
      }
    }
  ],
  "date": "2019-11-27 10:35:17.682",
  "requestId": "selfgen-9f035aca-d094-42d7-9285-a3eae9d5a4a9",
  "endpoint": "POST /api/v1/bankConnections/import",
  "authContext": "1/18",
  "bank": "DEMO0001 - finAPI Test Bank"
}
CODE

Step #5
Import a new bank connection

Mandatory request fields

  • all fields from the previous request

  • decoupledCallback

    • this is a boolean field that signals to the API that the end-user is already informed about the decoupled authorization and might have already approved it.

Explanation

The client application asks the API to check the status of the authentication process. Value of hash field points to the original request.

POST /api/v1/bankConnections/import HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <user's access token>

{
  "bankId": 277672,
  "interface": "XS2A",
  "loginCredentials": [
    {
      "label": "Onlinebanking-ID",
      "value": "idontexist"
    },
    {
      "label": "PIN",
      "value": "1337"
    }
  ],
  "accountReferences": [
    {
      "iban": "DE89370400440532013000"
    }
  ],
  "multiStepAuthentication": {
    "hash": "112c3581b39fc95a1f979d0d73f14dfb",
    "twoStepProcedureId": "DEMO-TSP-01",
    "decoupledCallback": true
  }
}
CODE

Step #6
Receive an error message that the decoupled authentication is still in progress
(an optional step)

How to recognise the step

Field errors.multiStepAuthentication.status has DECOUPLED_AUTH_IN_PROGRESS value.

Mandatory response fields of multiStepAuthentication object:

  • hash

  • status

Explanation

The API returns this error if the authentication is still not completed on the bank side. The client application should continue repeating step #5 while the API returns this error.

HTTP/1.1 510

{
  "errors": [
    {
      "message": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung",
      "code": "ADDITIONAL_AUTHENTICATION_REQUIRED",
      "type": "BUSINESS",
      "multiStepAuthentication": {
        "hash": "8f3bb2a7a1c6fec906c62465562e1dba",
        "status": "DECOUPLED_AUTH_IN_PROGRESS",
        "challengeMessage": "Bitte bestätigen Sie auf ihrem externen Gerät die Anmeldung",
        "answerFieldLabel": null,
        "redirectUrl": null,
        "redirectContext": null,
        "redirectContextField": null,
        "twoStepProcedures": null,
        "photoTanMimeType": null,
        "photoTanData": null,
        "opticalData": null
      }
    }
  ],
  "date": "2019-11-27 10:42:54.468",
  "requestId": "selfgen-5801b1be-0e09-4d2a-99a2-a748d7ee6d7e",
  "endpoint": "POST /api/v1/bankConnections/import",
  "authContext": "1/18",
  "bank": "DEMO0001 - finAPI Test Bank"
}
JSON

Step #7
Import a bank connection
(an optional step)

Mandatory request fields

  • all fields from the previous request

  • decoupledCallback

    • this is a boolean field that signals to the API that the end-user is already informed about the decoupled authorization and might have already approved it.

Explanation

The client application asks the API to continue the authentication process and check the authentication status on the bank side.

POST /api/v1/bankConnections/import HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer <user's access token>

{
  "bankId": 277672,
  "interface": "XS2A",
  "loginCredentials": [
    {
      "label": "Onlinebanking-ID",
      "value": "idontexist"
    },
    {
      "label": "PIN",
      "value": "1337"
    }
  ],
  "accountReferences": [
    {
      "iban": "DE89370400440532013000"
    }
  ],
  "multiStepAuthentication": {
    "hash": "112c3581b39fc95a1f979d0d73f14dfb",
    "twoStepProcedureId": "DEMO-TSP-01",
    "decoupledCallback": true
  }
}
CODE

Step #8
Bank connection

The API completes the import process and returns a bank connection resource.

HTTP/1.1 201

{
  "id": 46,
  "bankId": 280002,
  "name": null,
  "bankingUserId": null,
  "bankingCustomerId": null,
  "bankingPin": null,
  "type": "ONLINE",
  "updateStatus": "IN_PROGRESS",
  "categorizationStatus": "READY",
  ...
}
JSON

Step 2 - Check the status of the bank connection

To retrieve the status of the bank connection, get the bankConnectionId from the previous step and execute Get a bank connection:

GET /api/v1/bankConnections/{id}
CODE

Please beware that it takes some time to download the accounts and transactions from the bank. For more details, please check Post Processing of Bank Account Import/Update.

Step 3 - Get Accounts and Transactions

To query the account data for the imported bank connection, please use Get and search all accounts endpoint. There are many filtering options available such as by accountTypes, id, and more. Please refer to the API documentation for all available filters.

GET /api/v1/accounts
CODE

You can query transactions for one of the imported account/bank or all imported accounts/banks.

Please use Get and search all transactions endpoint.

GET /api/v1/transactions
CODE