NAV Navbar
shell

Introduction

The Flinks API mirrors the complete authentication process for a bank. Beginning with a username and password, the API allows your code to log in, respond to security challenges (such as two-factor authentication), and finally retrieve data.

During this process, you can tell Flinks to securely store the username and password, allowing us to refresh data in the background.

While we provide SDKs for various languages, this guide will focus on using the API directly. Guides for specific SDKs are also available, if you choose to use them.

See the following Swagger document for further details

Important note

The sandbox endpoint here is use only as an example. Please use the endpoint we provided you at the integration process.

Flinks Connect

Flinks Connect is your ready-to-use solution, allowing you to integrate Flinks without having to handle all of the edge-cases that come with integrating a Financial API.

Flinks Connect offers the user a simpler, more pleasant experience than a regular connection to their online banking.

Flinks Connect will handle credential validation, multi-factor authentication, and error handling for each institution that we support. It works across all modern browsers and platforms, including on iOS and Android.

Note that an end-to-end integration involves client-side and server-side configurations.

Service terms and conditions
If your user has not opted in to your service terms and conditions in a previous step, you will need to add them on the Login page. You can do so using the following parameters:

termsUrl: url of your service terms, so your user can access it from the login page.

customerName: name of your company, as you want it to appear in the Login page for the terms sentence.

Redirect
Once your user has successfully logged in (meaning the user has inputed credentials and answered all MFA questions), you will want her to be automatically directed to the next step of your online flow.

redirectUrl: use this parameter to redirect your user on your next step or thank you page.

Note that the loginId will be appended to the url.

Note also that a LoginId refers to a unique set of credentials used to access the bank session of your user. You can use the LoginId to schedule refreshes for that same session.

Transactions
You may or may not want to access the transaction history of your user.

withTransactions (true or false): use this parameter to disable transactions gathering (this parameter is set at “false” by default).

Language
If you have French users, you can use the following parameter to adjust the language for the institutions that support French:

language (fr or en): this parameter is set at “en” by default.

Background color
This parameter helps you integrate Flinks Connect while maintaining excellent user-experience and continuity in the interfaces you present to your users.

backgroundColor: We support all hexadecimal values.

Examples

Authorize

Exchange credentials for a LoginId and RequestId

Example of an Authorize request

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/Authorize' \
  -H 'content-type: application/json' \
  -d '{
        "Institution"       : "AwesomeBank",
        "Username"          : "1234567890123456",
        "Password"          : "a1b2c3",
        "Save"              : true,
        "MostRecentCached"  : false
      }'

Note that Save was set to true. This tells Flinks to save this user’s details, which means she won’t have to re-enter her credentials every time she uses your app. You can use the LoginId from LoginResponse instead.

Suppose you have a new user who wants to connect her bank to your app. After you’ve collected her username and password, you’ll need to authorize Flinks to access her data. For a first Authorize call with a new user, you always need the user’s institution, username, and password. You can refer to our list of institutions to call our API with the correct institution name (e.g. we use ‘TD’ instead of ‘TD Canada Trust’).

Every workflow begins with Authorize. It’s impossible to use other parts of the API without calling this endpoint first. Think of this endpoint as the “login screen” of the Flinks API. You always have to start here, and you’ll have to come back and log in again if your session expires.

To track your session, the Authorize endpoint will provide you with a RequestId, regardless of whether the authorization attempt succeeded or failed. This RequestId must be sent with every request until your workflow is finished. If your RequestId expires or isn’t valid, you’ll have to call Authorize again to get a new one.

Most Recent Cached transactions

If you put MostRecentCached: true into the request it tell to the API to returns you the cached transactions. Normally that will come from a scheduled refresh.

Possible Authorize responses

The Authorize endpoint will respond one of 3 ways.

Code Description
200 LoginResponse – Flinks was able to connect to the user’s account without any security challenges. You can now retrieve some data using the RequestId you received in the response.
203 ChallengeResponse – More data is needed before the user can log in. You need to show the challenges to the user and then send her responses back to Flinks in order to finish the authorization process. This response will contain a RequestId that you’ll need to use in your next call to make sure we pick up where we left off.
401 ReauthorizeResponse – The user’s credentials or security responses were rejected. You need to tell the user to enter new credentials or responses and then re-submit the request. The FlinksCode in the response will tell you which part of the request was rejected.

More about LoginId

If you add the parameter Save=True to a user’s first Authorize call, we will provide you with a LoginId specific to that user. The Save parameter allows us to safely store the username, password and MFAs, to facilitate any future calls for this user. It is also essential to access certain features, such as scheduling background refresh.

This LoginId will be useful to respond to any ChallengeResponses (code 203), or to initiate new Authorize calls for that same user.

A LoginId is created every time our API faces a unique combination of institution + username. As a user might trigger multiple Authorize calls during her time using your app, Flinks will recognize the combination, and always update the LoginId with the latest successful password.

Note: we use the term ‘username’ to unify banks’ Client Card (RBC), Access Card (TD), Card Number (BMO), etc.

Respond to security challenges

Example of a security response using Institution, Username, and Password

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/Authorize' \
  -H 'content-type: application/json' \
  -d '{
        "RequestId"   : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
        "Institution" : "AwesomeBank",
        "Username"    : "1234567890123456",
        "Password"    : "a1b2c3",
        "SecurityResponses" : {
          "What was the color of your first car?" : [
            "Red"
          ]
        }
      }'

Example of a security response using LoginId

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/Authorize' \
  -H 'content-type: application/json' \
  -d '{
        "RequestId"         : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
        "LoginId"           : "f51a811f-6e01-a901-bf33-352abf17bbe1"
        "SecurityResponses" : {
          "What was the color of your first car?" : [
            "Red"
          ]
        }
      }'

Flinks needs a little more data to finish the authorization process. We use the same endpoint, Authorize, for all authorization-related requests.

This time, you’ll need to submit the RequestId that was returned by LoginResponse.

Security challenges

Security challenges are returned as objects with helpful details that you should use when displaying them to your users:


{
  "SecurityChallenges": [
    {
      "Type"   : "QuestionAndAnswer",
      "Prompt" : "What was the color of your first car?"
    }
  ]
}

Security responses

Security responses are sent as dictionaries. The keys of the dictionary are the prompts from the security challenges. The values of the dictionary are arrays of answers (since some challenges require multiple answers).


{
  "SecurityResponses" : {
    "What was the color of your first car?" : [
      "Red"
    ]
  }
}


You must submit a response for every security challenge. No challenge is optional! If responding to the challenge fails, never try the failing answers again. This often results in accounts getting locked!

You can return a security response using either your user’s LoginId, or her Institution, Username, and Password.

Special Authorize Flows

Certain banks offer unique Authorize challenges. While we did our best to build the simplest API possible, there are still a few specific cases you need to be able to handle. This section will tell you all about those cases.

Example Questions/Answers Reset (RBC)

RBC is not outdone in this category, and offers truly unique cases. When RBC detects bad MFA answers and/or password when trying to login, it might offer the next session one of these two more complex cases:

  1. Reset Questions/Answers when questions are provided.
  2. Reset Questions/Answers when user has to select new questions.

If you extensively test an RBC account, you’ll likely face one of these two cases.

Case 1: Reset Questions/Answers when the questions are provided.

Example of a security request for RBC reset

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/Authorize' \
  -H 'content-type: application/json' \
  -d '{
        "RequestId"         : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
        "LoginId"           : "f51a811f-6e01-a901-bf33-352abf17bbe1",
        "SecurityResponses" : {
              "What is the name of your mother" : [ "Louise" ],
              "What is the name of your father" : [ "Paul" ],
              "What is the name of your dog"    : [ "Wouf" ]
        }
      }'

Note that the format of your response will be the same either for Case 1 or Case 2

You can see this as a triple MFA: instead of having to give one answer to a single question, the user needs to give an answer to three different questions. It’s important that you return all three answers in the same call.


{ ...
  "RequestId"           : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
  "SecurityChallenges"  : [
    {
      Type              : "QuestionAndAnswer",
      Prompt            : "What is the name of your mother"
    },
    {
      Type              : "QuestionAndAnswer",
      Prompt            : "What is the name of your father"
    },
    {
      Type              : "QuestionAndAnswer",
      Prompt            : "What is the name of your dog"
    }
  ]
}

Case 2: Reset Questions/Answers when user has to select new questions.

So RBC has another trick up its sleeve: now, it wants the user to select three new questions on top of providing three answers. When this case arises, we’ll send you three lists of questions; from each list, your user has to choose one question, and then provide an answer.

A SecurityChallenges object will be returned:


{ ...
  "RequestId"           : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
  "SecurityChallenges"  : [
    {
      Type              : "QuestionAndAnswer",
      Prompt            : "Personal Verification Question 1",
      Iterables         : [
        "What is the name of my mother",
        "What is the name of my dog",
        "..."
      ]
    },
    {
      Type              : "QuestionAndAnswer",
      Prompt            : "Personal Verification Question 2",
      Iterables: [
        "What is the name of my mother",
        "What is the name of my dog",
        "..."
      ]
    },  
    {
      Type              : "QuestionAndAnswer",
      Prompt            : "Personal Verification Question 3",
      Iterables: [
        "What is the name of my mother",
        "What is the name of my dog",
        "..."
      ]
    }
  ]
}

Image selection MFA (Laurentienne)

The Authorize flow for Laurentienne Bank presents the user with an additional security challenge in the form of an image selection from a list of 16 different images. So the Laurentienne Authorize flow looks like this:

  1. Login credentials (username + password)
  2. 1st MFA (security question)
  3. 2nd MFA (image selection)

For example, a security challenge object will be presented as such: Type ImageSelection with a Prompt and a list of Iterables comprised of strings in base64 encoding.


"SecurityChallenges": [
  {
    "Type"      : "ImageSelection",
    "Prompt"    : "Select an image",
    "Iterables" : [
        "base64ImageString1", 
        "base64ImageString2", 
        ...
    ]
  }
]

Note: The image strings within the list of Iterables can be quite lengthy (like 4,000-character-per-image-lengthy).

SecurID MFA (National)

The initial Authorize call (login credentials) for National Bank is the same for every accounts, personal or business. What is unique to National Bank is that business account holders have two ways to log into their online banking: the regular way (normal Authorize flow), and the SecurID way (special Authorize flow).

When Flinks detects its facing a business account with SecurID, it will return any initial Authorize call with a security challenge asking for the 6-figure SecurID code. Then, you might be presented with a second security challenge (in the form of a security question). The SecurID Authorize flow thus looks like this:

  1. Login credentials (username + password)
  2. 1st MFA (SecurID code)
  3. 2nd MFA (regular security question)

 {
    "SecurityChallenges": [
      {
        "Type"   : "QuestionAndAnswer",
        "Prompt" : "Enter your SecurID"
      }
    ]
  }

Note that it’s impossible to schedule automatic background refreshes with accounts using SecurID, as a new 6-figure code is generated every minute, and only accessible from the SecurID device that the end-user has.

Get Accounts Summary

Retrieve quick details about a user

Example of a GetAccountsSummary request

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetAccountsSummary' \
  -H 'content-type: application/json' \
  -d '{
        "RequestId"  : "2b000833-0bf4-4705-9ef8-80d4572af4c4"
      }'

Now you’re ready to retrieve data for your user! You can call either GetAccountsSummary or jump straight to GetAccountsDetail, depending on the needs of your app.

GetAccountsSummary will give you the following information about each of the accounts linked to the session:

If you put Save=true in your Authorize call, you have the option to get a blazing-fast response by setting MostRecent=true. This tells Flinks to send you the latest data stored for this particular LoginId. If it’s your first request using this LoginId, data will be fetched in real time. But if Flinks has been running background refreshes, the most recent data set will be returned almost instantly from the cache.

To GetAccountsSummary, you only need the RequestID of your user’s session, not her LoginID.

Get Accounts Detail

Retrieve complete details about a user

Example of GetAccountsDetail request

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetAccountsDetail' \
  -H 'content-type: application/json' \
  -d '{
            "RequestId"           : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
            "WithAccountIdentity" : true,
            "WithTransactions"    : true,
            "DaysOfTransactions"  : "Days90",
            "AccountsFilter"      : ["31ed3d3f-5705-4923-a499-7bb2e2da6b4d", "a5fa9874-19cc-4a6a-9e5a-34e0a65030a1", ...]
      }'

Calling this endpoint will give you the same information as GetAccountsSummary for each account linked to the session, plus the following:

You can decide to add to the response the information about the account such as : Transit, Institution, Holder name, and Account Number by addind WithAccountIdentity to true You can decide to add to the response the account transactions or not by adding WithTransactions to true You can filter the account we return you in the response by adding AccountsFilter with the unique identifier that we provided you into GetAccountsSummary

All theses parameters are existing to increase the speed of the call, less stuff you need, faster it will be.

To set the number of days of transactions you need, you must add the parameter DaysOfTransactions with a corresponding Days90 or Days360 value in the request. Note: if no parameters is provided, “Days90 of transactions will be provided by default.

To GetAccountsDetail, you only need the RequestID of your user’s session, not her LoginID.

Example of GetAccountsDetailAsync request

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetAccountsDetailAsync/{RequestId}'

At that point you made the request of what you need, from that point 2 things can happen.

First, you can receive OPERATION_DISPATCHED code that means that you will need to call the Async endpoint in a long pooling fashion.
It’s a GET call to https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetAccountsDetailAsync/{RequestId}

By calling that endpoint you can receive OPERATION_PENDING code. Meaning that you need to continue calling that endpoint until you receive a 200 OK response.

Or, you can receive directly the 200 OK if the request is process under 210 seconds. In any case you use the async endpoint with the requestId to retrieve your data.

Get Statements

Retrieve the Official Bank Statement of an account

Example of a GetStatements request

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetStatements' \
  -H 'content-type: application/json' \
  -d '{
        "RequestId"           : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
        "NumberOfStatements"  : "MostRecent",
        "AccountsFilter"      : ["31ed3d3f-5705-4923-a499-7bb2e2da6b4d", "a5fa9874-19cc-4a6a-9e5a-34e0a65030a1", ...]
      }'

Flow

  1. /Authorize
  2. /GetStatements

Parameters for /GetStatements:

RequestId
Type: Guid, Required
You must provide the RequestId returned by the /Authorize call

NumberOfStatements
Type: String (enum), Optional
Values: MostRecent, Months3, Months12
Default value: MostRecent
You can provide this parameter to control the number of statements per account you want.
The system will try to get the X most recent statements available per account for the given credentials

AccountsFilter
Type: Array of Guids, Optional
If provided, it will restrict the statements returned for the given account(s).
To use this parameter, you must know the account id(s) for the accounts you want info,
meaning that you will likely have done a /GetSummary with Save=true call before /GetStatements to get the ids.

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetStatementsAsync/{RequestId}'

At that point you made the request of what you need, from that point 2 things can happen.

First, you can receive OPERATION_DISPATCHED code that means that you will need to call the Async endpoint in a long pooling fashion.
It’s a GET call to https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetStatementsAsync/{RequestId}

By calling that endpoint you can receive OPERATION_PENDING code. Meaning that you need to continue calling that endpoint until you receive a 200 OK response.

Or, you can receive directly the 200 OK if the request is process under 210 seconds. In any case you use the async endpoint with the requestId to retrieve your data.

Scheduling background refresh

 Example of an Authorize call with ScheduleRefresh=true

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/Authorize' \
      -H 'content-type: application/json' \
      -d '{
            "Institution"         : "AwesomeBank",
            "Username"            : "1234567890123456",
            "Password"            : "a1b2c3",
            "Save"                : true,
            "ScheduleRefresh"     : true
          }'

 Example of Activating ScheduleRefresh directly through the endpoint

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/ActivateScheduledRefresh?loginId=abcdef'

Here we allow you to automate refreshes of your user’s data. Say you need to have your user’s data to be up-to-date once a day, then during an Authorize call, you must set the parameter ScheduleRefresh=true.

If you wish to activate this feature without passing through an Authorize call, you can do so by calling the ActivateScheduledRefresh endpoint using your user’s LoginID.

Once turned on, the ScheduleRefresh will remain activated until you decide to turn it off.

Note that to use the refresh feature, you need to set Save=true.

Example:


{
  "Institution"     : "AwesomeBank",
  "Username"        : "1234567890123456",
  "Password"        : "a1b2c3",
  "Save"            : true,
  "ScheduleRefresh" : true
}

Real-time vs. most recent data

Example of MostRecentCached=true for a GetAccountsSummary call

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetAccountsSummary' \
  -H 'content-type: application/json' \
  -d '{
        "RequestId"  : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
        "MostRecent" : true
      }'

Any initial calls for a new user will be done in what we call real-time. If you frequently need to refresh your user’s data, you may consIder using the parameter MostRecentCached=true, which gives you blazing-fast access to the data pulled in the most recent scheduled background refresh.

If you want to allow your user to refresh her account in real-time, or if you need to see a transaction that your user made minutes ago for example, you can turn the MostRecentCached flag to false.

Changing the language

You can allow your user to answer her security challenges in either English or French. While not all institutions have a bilingual interface, we do support bilingual MFAs for the ones that do. Note that our API will work even if you use a language parameter that the bank doesn’t support.

Error codes

Flinks uses the HTTP status code spec whenever possible. In addition to the responses above, you may receive a server error (500) or a request error (400).

If you ever receive a server error from Flinks, our team has already been notified and our 24/7 uptime crew will be working to resolve your issue.

If you ever receive a client error, the response will include a string FlinksCode that will give you a named constant to explain the cause of the error. It’s safe to use these in your code and check for them.

Possible values for FlinksCode are:

Supported Institutions

The following is a list of supported Canadian Financial Institutions:

Get help from a human being!

Stuck? We’ve simplified our API as best we can, but we understand that the increased security requirements for banks can cause a confusing workflow.

Contact help@flinks.io to let us know of any issues, and our team will help you over the hurdle.