NAV Navbar
shell

Introduction

Flinks’ 4 differentiators

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.

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. The whole parent page from the iframe will be redirected.

Note that the loginId and the tag will be appended to the url, and only secure URLs are supported (HTTPs).

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.

innerRedirect (Optional parameter for redirectUrl): If you want to have only the iframe being redirected, add this parameter with the set as “true”. (For this parameter to work, RedirectUrl also must be used)

jsRedirect (Optional parameter for redirectUrl): Use this parameter if you prefer using a javascript based redirect instead of a HTTP redirect. (For this parameter to work, RedirectUrl also must be used)

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 “true” by default).

Amount of transactions
You can specify the amount of transactions you want by choosing between 90 days or 360 days.

daysOfTransactions (Days90 or Days360): use this parameter to change the number of days to look in the past for transactions (this parameter is set at “Days90” by default).

Statement
This parameter, when set to true, will trigger the retrievement of PDF statements from the financial institution instead of the accounts detail (transactions). You will have to call the Authorize with parameter MostRecentCached: true followed by GetStatements to get the statements.

statement (true or false): use this parameter to enable statements gathering (this parameter is set to “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. Notice that you will be able to refresh a card exclusively in the language that was chosen the very first time.

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.

Text color
There are 2 parameters available to control the text color.

foregroundColor1 (header text) and foregroundColor2 (normal text): Works the same as the backgroundColor parameter (hexadecimal values).

Schedule automatic refresh

If set to true, it will activate that card in our nightly automatic refresh. This refresh allows you to ping the API in “cached” mode the morning after and gather all the transactions we got from that day.

scheduleRefresh (true or false): this parameter is set at “false” by default.

Wait for get summary completed

If set to true, it will wait that the summary information is accessible before redirecting your user to your system endpoint. This allows you to ping the API in “cached” mode and gather all the summary information we fetched.

waitSummary (true or false): this parameter is set at “false” by default.

Maximum number of retries

If set, it will informally block the user from reentering any credentials during a session after a series of invalid logins (username or password). This will help prevent the user from locking themselves out of their own account

maximumRetry (any number): this parameter is set at 99 by default.

Events as strings

If you are using the Event Listener feature (followning section in the Documentation) and you need its output as strings instead of JSON objects.

stringify (true or false): this parameter is set at “false” by default.

Get MFA Questions

When this parameter is set to true, the loginId from the connected account will retrieve the security questions in the GetMFAQuestions endpoint when calling the API.

withMFAQuestions (true or false): This parameter is set at “false” by default.

Disable Back Button

When this parameter is set to false, the back button will be hidden.

This parameter needs to be set on the credential form page of a specific institution.
Ex.: "{{your-domain}}/Credential/{{institution}}/?backEnable=false"

backEnable (true or false): This parameter is set at “true” by default.

Enable Close Button

When this parameter is set to true, the close button will be showned.

This parameter needs to be set on the credential form page of a specific institution.
Ex.: "{{your-domain}}/Credential/{{institution}}/?closeEnable=true"

Note that the close button doesn’t perform any action, it just sends an event to the event listener for you to perform your own custom action.

closeEnable (true or false): This parameter is set at “false” by default.

Custom tag

If set, the redirect url will be appended with the query parameter “tag” and the the value of the tag.

tag (string no longer than 254 characters): this parameter is null or empty by default.

Event Listener

Example of a Event Listener Script

<iframe src="https://demo.flinks.io/?redirectUrl=https://example.com" id="frameFlks" width="800" height="800"></iframe>
<script>
    window.addEventListener('message', function(e) { 
        console.log(e.data) 
    });
</script>

If you want to have the Authorize process output in the browser console, add the Event Listener script as the example.

Example of a console output when the Event Listener script is used:


{requestId: "7cdb1459-1222-4833-9848-58dd6624f084", loginId: "9a85d177-2303-4b79-c74b-08d589d604f1", institution: "FlinksCapital"}

If you need to have the output from the events as a string instead of JSON objects, you have to set the parameter stringify=true in your iframe URL.

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,
        "Tag"               : "someValue"
      }'

Note that Save was set to true. This tells Flinks to save this user’s details (including the PDF statements if you call GetStatements), 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.

Bank website language

Some bank websites have an English and a French version, and there could be some small differences between the two (account names for example). You can choose which version to use for the scraping with the language parameter. The default value is English (“en”) if omitted but you can use the French version of the bank website for example by providing Language: "fr".

Note that you will only be able to refresh (or scrape again) a card with the language chosen initially on the first scraping. Also note that some bank websites only provide an English version, so only the “en” value is working for these.

Retrieve all the security questions

In addition to the security question (MFA) that could be asked by the financial institution during the Authorize process, you can use the parameter WithMFAQuestions: true to trigger a special action at the end of the authorization process. Our API will try to retrieve all end user’s security questions and save them for later reuse. Notice that this will only happen if the parameter ‘save’ is at true. The ‘save’ and ‘GetMFAQuestions’ parameters are set to false by default. Note that the questions will be saved without answers at this first step (except for the security question that was asked during the Authorize process for which we saved the answer). To get the unanswered questions and answer them, you’ll need to call the endpoints /GetMFAQuestions and /AnswerMFAQuestions.

Most Recent Cached transactions

If you put MostRecentCached: true into the request it tell to the API to returns you the cached transactions or cached PDF statements. Normally, you would use this after transactions have been updated from a scheduled refresh.

Custom tag

If you put Tag: "someValue" into the request, all subsequent successful requests using the same request id will return the tag, including the authorize request.

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 '{
        "LoginId"           : "f51a811f-6e01-a901-bf33-352abf17bbe1"
        "MostRecentCached"  : false
      }'

Login with saved credentials. Put MostRecentCached: true if you come from FlinksConnect

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" ]
        }
      }'

Answers MFA steps, 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",
        "..."
      ]
    }
  ]
}

Case 3: 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).

Case 4: 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.

Case 5: Reset Security Questions (Scotia)

With Scotia, a user may be prompted to reset their security questions.

The user may be presented with a set of multiple choice questions. There are two distinct types: MultipleChoice, and MultipleChoiceMultipleAnswers wherein MultipleChoice responses expect only one answer, and the MultipleChoiceMultipleAnswers expect one or more answers.

The procedure would be as follows:

  1. Login credentials (username + password)

  2. 1st set of Security Challenges : Personal Multiple Choice Questions

  3. 2nd set of Security Challenges : Choosing a set of new Security Questions

Step 1:

Login credentials

Step 2 Response

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" : {
          "Choose one of the following:" : [
            "None of the above"
          ]
          "What purchases did you make over the last 10 days?" : [ 
            "Purchase 1: $10.35", 
            "Purchase 3: $143.86" 
          ]
        }
      }'

Step 2:

Personal Multiple Choice Questions

 
{ ...
  "RequestId"           : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
  "SecurityChallenges": [
    {
      "Type"   : "MultipleChoice",
      "Prompt" : "Choose one of the following:",
      "Iterables" : [
        "Something",
        "Something else",
        "...",
        "None of the above"
      ]
    },
    {
      "Type"   : "MultipleChoiceMultipleAnswers",
      "Prompt" : "What purchases did you make over the last 10 days?",
      "Iterables" : [
        "Purchase 1: $10.35",
        "Purchase 2: $73.42",
        "Purchase 3: $143.86",
        "...",
        "None of the above"
      ]
    }
  ]
}

Step 3 Response

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" ]
        }
      }'

Step 3: Choosing a set of new Security Questions
Note: this is identical to the procedure as described above with Case 2: Reset Questions/Answers when user has to select new questions.


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

Case 6: 2 Step Verification Security Code (TD)

TD users may be prompted to enter a security code sent to their phone via a text message or phone call. The API will present a SecurityChallenge of type TextOrCall

Step 1:

After your regular first Authorize call, the API will prompt the 2 Step Verification Security Code in the API response.

Regular first Authorize call.

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/Authorize' \
  -H 'content-type: application/json' \
  -d '{
        "Institution" : "TD",
        "Username"    : "{username}",
        "Password"    : "{password}",
        "save"      : true
    }'

API Response:

{ ...
  "RequestId"           : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
  "SecurityChallenges": [
    {
      "Type"   : "TextOrCall",
      "Prompt" : "Choose a phone number",
      "Iterables" : [
        "PhoneNumber #1",
        "PhoneNumber #2",
        "PhoneNumber #3",
        ...
      ]
    }
  ]
}

Step 2: Selecting a phone number and how to be contacted

In the next Authorize call, you have to pass the registered telephone number and the method of receiving the security code. There are two means by which a user can be contacted: Text or Call.

After that, the enduser will receive the code from the chosen method and phone number, which will be used for the next step.

Step 2 Request

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" : {
          "PhoneNumber #2" : [ "Text" ]
       }
    }'

API Response:

{ ...
  "RequestId"           : "2b000833-0bf4-4705-9ef8-80d4572af4c4",
  "SecurityChallenges"  : [
    {
      "Type"              : "QuestionAndAnswer",
      "Prompt"            : "Enter the security code"
    }
  ]
}

Step 3: Entering the security code

Step 3 Requests

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" : {
          "Enter the security code" : [ "123456" ]
        }
      }'

Once TD validates the sent security code, you will receive a 200 response from the API.


API Response:

{
    "Links": [
        {
            "rel": "AccountsDetail",
            "href": "/GetAccountsDetail",
            "example": null
        },
        {
            "rel": "AccountsSummary",
            "href": "/GetAccountsSummary",
            "example": null
        },
        {
            "rel": "Statements",
            "href": "/GetStatements",
            "example": null
        }
    ],
    "HttpStatusCode": 200,
    "Login": {
        "Username": "{username}",
        "IsScheduledRefresh": false,
        "LastRefresh": "2018-05-23T15:10:51.65608",
        "Id": "f51a811f-6e01-a901-bf33-352abf17bbe1"
    },
    "Institution": "TD",
    "RequestId": "2b000833-0bf4-4705-9ef8-80d4572af4c4"
}

Authorize Multiple

If you need to retrieve data from a previous call and stored in the database, you could of course make a a request to the Authorize endpoint using MostRecentCached:true. But if you need to retrieve data stored in the database for multiple cards, you can save you some time by authorizing all your cards at once by making a request to the AuthorizeMultiple endpoint.

Example of a AuthorizeMultiple with multiple LoginIds

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/AuthorizeMultiple' \
  -H 'content-type: application/json' \
  -d '{
        LoginIds: [
          "9A90A45F-38BD-4C33-B1CA-8F66550D05DC",
          "72B85B70-2A6F-4809-AE26-A68BC7E87754"
        ]
    }'

This will generate a RequestId for each valid LoginId that you provide. Here is a response example:


{
   ValidLoginIds:
   [
      {
         LoginId: "9A90A45F-38BD-4C33-B1CA-8F66550D05DC",
         RequestId: "F06C2C70-22F7-4C24-8A1F-B116AB7448ED"
      }
   ],
   InvalidLoginIds: [ "72B85B70-2A6F-4809-AE26-A68BC7E87754" ]
}

You will receive a RequestId for each valid LoginId you provided. In this example, it means that one LoginId provided was not found in the database and is thus unusable. From this point, you can use each RequestId to call an endpoint of our API that will retrieve data, for example by calling GetAccountsDetail. Remember that using AuthorizeMultiple is only for retrieving data from the database as it will use an implicit MostRecentCached:true parameter. Any call to our API you do with the RequestId generated from the AuthorizeMultiple endpoint won’t do any live scraping.

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:

To GetAccountsSummary, you only need the RequestID of your user’s session, not its 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

If WithAccountIdentity or WithTransactions are set to false, it will have a increase of speed in your request. The less information you need, it will be faster.

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.

Also, you can use the parameter WithBalance set to true (default) or false. The value true indicates to return all balances (from each transaction and account) as well as overdraft protection information.

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

After the call is made, you can expect two different responses:

Get Accounts Detail Async endpoint

Example of GetAccountsDetailAsync request

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

It’s a GET call to https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetAccountsDetailAsync/{RequestId}

After calling the async endpoint, you will either receive a 202 OPERATION_PENDING code, meaning that your request is still not ready and you need to continue calling the async endpoint, or a 200 OK response meaning your request is completed.

We recommend making an async call every 30 seconds with a timeout of 30 minutes, even though your requests usually will take in average between 2 and 3 minutes.

Webhook

When this feature is enabled, Flinks will send all completed processes responses to the designated address. In this case, instead of polling the results in cached mode, you will actively receive it as soon as it’s completed.

For the webhooks to be available, you need to inform us the address of the webhook endpoint in your side in order for us to configure your private instance.

Once the webhook is activated, all API to GetAccountsDetail calls will return the 202 code and the response will be sent to the webhook response catcher.

Note:

All direct API calls to GetAccountsDetail endpoint will return the Flinks Code OPERATION_PENDING with 202. This includes both requests in live or cached mode, but it’s still possible to retrieve the data throught the API if you follow this particular flow with the GetAccountsDetailAsync endpoint.

Nightly Refreshes with Webhooks

If you are using Flinks’ automatic refresh feature, you are also going to receive all successful results via Webhooks.

In order to verify if all LoginIds were successful refreshed, we still recommend a daily Authorized cached call for each one.

Specify range for your transactions

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,
            "DateFrom"            : "2017-09-01",
            "DateTo"              : "2017-09-23"
      }'
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,
            "RefreshDelta": [
                {
                    "AccountId": "50F9EBD4-EAC8-406C-44A4-08D4FA121A72",
                    "TransactionId": "1E0FA7D7-DC6D-490F-58D3-08D4FF601727"
                },
                {
                    "AccountId": "7EC1D3C5-4A42-4863-44A5-08D4FA121A72",
                    "TransactionId": "6FD26505-3CC2-4FCB-58DA-08D4FF601727"
                }
            ]
      }'

There are actually two other ways of getting a certain range of transactions.

  1. You can use a date range with the parameters DateFrom and DateTo:

  2. Or you can use the RefreshDelta parameter. This allows to retrieve only new transactions after a given transaction. As you can see from the request example, you have to provide a list of tuples (AccountId and TransactionId. For each account, you will get only the transactions that were made after the transaction that was specified.

Delete card information

If you want to delete all trace of information about a card in our database, you can call the DeleteCard endpoint. Just make a DELETE call to the endpoint, see the example on the right.

curl --request DELETE 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/DeleteCard/{LoginId}'

Get PDF Statements

Retrieve the Official PDF 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. Note that if MostRecentCached was set to true in the Authorize call, the NumberOfStatements parameter will be ignored and all the cached statements per account will be returned.
Important: If you use Months12, the AccountsFilter will be mandatory and must contain only a single account.

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 polling 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.

Get unanswered MFA questions

Example of a GetMFAQuestions request

curl 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/GetMFAQuestions/{loginId}'

If you’ve used WithMFAQuestions: true and Save: true in the Authorize request, all the security questions of the end user should have been stored (note that a few banks - HSBC, CIBC, Laurentienne and Simplii - do not provide the security questions so they will not be available).

Here is an example of response:


{
    "Message": "SUCCESS",
    "Questions": [
        {
            "Question": "What was your first pet's name?"
        },
        {
            "Question": "What is the name of your best childhood friend?"
        },
        {
            "Question": "What is your favourite wild animal. Please no dogs or cats or parakeets"
        },
        {
            "Question": "What city were you born in?"
        },
        {
            "Question": "What is your favourite actor or actress or celebrity?"
        }
    ]
}

This way, you can ask your user to answer them in advance and this will greatly improve the success rate of future accesses, most notably nightly refreshes for example.

Set answers in advance to MFA questions

If you ask your end user to provide answers to his security questions (through the use of the GetMFAQuestions endpoint), you can then save his answers with the /AnswerMFAQuestions endpoint. If the questions are answered with wrong responses, they will still be updated and you will then probably face the mfa again later on.

Example of a AnswerMFAQuestions request

curl --request PATCH 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/AnswerMFAQuestions' \
  -H 'content-type: application/json' \
  -d '{
        "LoginId"   : "{loginId}",
        "Questions" : [
           {
              "Question": "The first question",
              "Answer": "Answer1"
           },
           {
              "Question": "The second question",
              "Answer": "Answer2"
           }
        ]
      }'

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
          }'
curl --request PATCH 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/SetScheduledRefresh' \
      -H 'content-type: application/json' \
      -d '{
            "LoginId"         : "a9be24a3-09c5-4b8c-a0a6-4f01b7f9c62f",
            "IsActivated"     : true
          }'

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. Please note that this parameter will have an effect only for brand new cards. You cannot alter the value of the parameter from here.

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.

If you wish to activate or deactivate this feature for a card that already exist, you can do so by calling the SetScheduledRefresh endpoint using your user’s LoginID and the desired value. Please note that the request type for this enpoint is PATCH.

Example:


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

SetScheduledRefresh endpoint

With this endpoint you can deactivate (or activate) the automatic refresh for a given loginId (see example to the right).

 Example of Activating ScheduleRefresh directly through the endpoint

curl --request PATCH 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/SetScheduledRefresh' \
      -H 'content-type: application/json' \
      -d '{
            "LoginId"         : "a9be24a3-09c5-4b8c-a0a6-4f01b7f9c62f",
            "IsActivated"     : false
          }'

Example of Deactivating ScheduleRefresh directly through the endpoint

curl --request PATCH 'https://sandbox.flinks.io/v3/{CustomerId}/BankingServices/SetScheduledRefresh?loginId={loginId}&isActivated=false'

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. Our API will work even if you use a language parameter that the bank doesn’t support.

Note: Once a user’s credentials are saved, any subsequent requests made thereafter will be enforced to use the same language as the one used for the initial call. i.e.: If the user’s first call was made with the language paramater set to "en" and an attempt is made to log in again but with the language parameter set to "fr", an error message will be returned.

English: "You must use the 'French' (fr) language parameter to refresh this card."

French: "Vous devez utiliser le paramètre de langue 'English' (en) pour rafraîchir les données de cette carte."

Insight

Insight endpoints can be called in 2 different ways:

For all Insight endpoints calls to be successful, you have to call the GetAccountsDetail endpoint at least one time beforehand so Flinks API can get user’s transactions from the financial institutions website.

Also, all calls to the Insight endpoints will have to be authorized first.

To a request to be authorized, you have to call Authorize endpoint first to get a valid requestId. The call to Authorize will need, as input parameters, the end user loginId and MostRecentCached set to true. The requestId received after a successful Authorize request will have to be passed as a parameter to the Insight endpoint you need to call.

/transaction/oldest

Detect the oldest transaction available to Flinks for each operations account if you specify the loginId or for one specific operations account if you specify the accountId.

Example of a getting the oldest transaction for each operations account request

curl 'https://sandbox.flinks.io/v3/{customerId}/insight/login/{loginId}/transaction/oldest/{requestId}'



/{customerId}/insight/login/{loginId}/transaction/oldest/{requestId}

Detect the oldest transaction available to Flinks for each operations account.

Request Parameters

Name Type Description
customerId string GUID representing your customer ID (provided by Flinks)
loginId string GUID representing end user’s login ID. You get this value after a successful Authorize request.
requestId string GUID representing an authorized request to the API. You get this value after a successful Authorize request.

Response Fields

array

Name Type Description
transaction object Object representing the account’s oldest transaction (available to Flinks). See below for the fields in the Oldest object.

Example of a getting the oldest transaction for one operations account request

curl 'https://sandbox.flinks.io/v3/{customerId}/insight/account/{accountId}/transaction/oldest/{requestId}'



/{customerId}/insight/account/{accountId}/transaction/oldest/{requestId}

Detect the oldest transaction available to Flinks for one operations account.

Request Parameters

Name Type Description
customerId string GUID representing your customer ID (provided by Flinks)
accountId string GUID representing an account ID. You get this value for each account after a successful call to GetAccountsSummary or GetAccountsDetail.
requestId string GUID representing an authorized request to the API. You get this value after a successful Authorize request.

Response Fields

Name Type Description
transaction object Object representing the account’s oldest transaction (available to Flinks). See below for the fields in the Oldest object.

transaction object

Name Type Description
id string GUID representing the transaction.
accountId string GUID representing an account ID. You get this value for each account after a successful call to GetAccountsSummary or GetAccountsDetail.
periodDetected integer Period (transaction date range). Possible values (in days) 30 (less than), 90 (less than), 365 (less or more than)
date date Date of the transaction.
description string Transaction description as it is on bank website.
debit decimal The amount of the transaction. The value will be null if the transaction is a credit.
credit decimal The amount of the transaction. The value will be null if the transaction is a debit.
balance decimal Account balance after the transaction has been processed.

/transaction/categorized

Return the categorized transactions available to Flinks for given loginId or accountId.

Example of a getting the categorized transaction for each operations account request

curl 'https://sandbox.flinks.io/v3/{customerId}/insight/login/{loginId}/transaction/categorized/{requestId}'


Example
/{customerId}/insight/login/{loginId}/transaction/categorized/{requestId} Return the categorized transactions available to Flinks for given loginId.

Request Parameters

Name Type Description
customerId string GUID representing your customer ID (provided by Flinks)
loginId string GUID representing end user’s login ID. You get this value after a successful Authorize request.
requestId string GUID representing an authorized request to the API. You get this value after a successful Authorize request.

Response Fields

array

Name Type Description
transaction object Object representing the account’s categorized transaction (available to Flinks). See below for the fields in the categorized object.

Example of a getting the categorized transaction for one account request

curl 'https://sandbox.flinks.io/v3/{customerId}/insight/account/{accountId}/transaction/oldest/{requestId}'



/{customerId}/insight/account/{accountId}/transaction/oldest/{requestId} Return the categorized transactions available for given accountId.

Request Parameters

Name Type Description
customerId string GUID representing your customer ID (provided by Flinks)
accountId string GUID representing an account ID. You get this value for each account after a successful call to GetAccountsSummary or GetAccountsDetail.
requestId string GUID representing an authorized request to the API. You get this value after a successful Authorize request.

Response Fields

Name Type Description
transaction object Object representing the account’s transaction (available to Flinks). See below for the fields in the Oldest object.

transaction object

Name Type Description
id string GUID representing the transaction.
accountId string GUID representing an account ID. You get this value for each account after a successful call to GetAccountsSummary or GetAccountsDetail.
date date Date of the transaction.
description string Transaction description as it is on bank website.
debit decimal The amount of the transaction. The value will be null if the transaction is a credit.
credit decimal The amount of the transaction. The value will be null if the transaction is a debit.
balance decimal Account balance after the transaction has been processed.
category object Object represent the category that the transaction belongs to

category object

Name Type Description
id string GUID representing the category.
name string The name of the category.
confidence decimal A decimal representing the confidence percentage for the categorization.

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:

Flinks Capital - Dummy Institution

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


Username: "Greatday"
Password: "Everyday"
Institution: "FlinksCapital"


Security Questions and Answers

What city were you born in? : Montreal
What is the best country on earth? : Canada
What shape do people like most? : Triangle


Disabled Account

Sometime an account happen to be disable at the institution level. For that case we will return DISABLED_LOGIN Flinks Code
To test, you will need to change the username for : test_disabled_account


Service Unavailable

Sometime the financial institution is doing maintenance and their service are not available. For that case we will return RETRY_LATER Flinks Code
To test, you will need to change the username for : test_service_unavailable


Operation dispatched

When your request exceeds 210 seconds of processing, we will return you a 202 Accepted and a partial result of what had been processed so far.
This means we dispatched the process into a queue for long running operations.
In this case, we will return a OPERATION_DISPATCHED Flinks Code
In order to retrieve the results, you will need to long pool the Async endpoint as explained in the GetAccountsDetail section.
To test, you will need to change the username for : test_dispatched


Operation pending

When your request is not completed yet, we will return you a 202 Accepted and a partial result of what had been processed so far.
This means we are still processing the operations.
In this case, we will return a OPERATION_PENDING Flinks Code
In order to retrieve the results, you will need to long pool the Async endpoint as explained in the GetAccountsDetail section.
To test, you will need to change the username for : test_pending


Banks special authorization flows

Some banks have unique special flows that you can encounter during the Authorize request. It is possible to test them with FlinksCapital to ensure that you can support them correctly.

Laurentienne
Laurentienne bank has an additional security step during the Authorize request. After answering the usual MFA question, the client must select his personal image from a list.
You can test this flow with the user test_laurentienne

RBC
Sometimes RBC will ask the client to reset his MFA questions and answers during the Authorize request, if the bank determined that a suspicious access attempt was made recently.
You can test this flow with the user test_rbcsecurity

Scotia
Sometimes Scotia will ask the client to reset his MFA questions and answers during the Authorize request, if the user incorrectly answered his MFA question 3 times in its latest attempt.
The client will first have to confirm his identity by answering to questions only him should know, and after this successful confirmation he must recreate 3 new questions (with answers).
You can test this flow with the user test_scotiasecurity

TD
Some TD clients have activated two factor authentication, requiring the user to select a phone number and an action (Text or Call), then entering a security code.
You can test this flow with the user test_td

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.