Instant Verification

There are 3 endpoints that you will be using:

  1. GET /v3/bank/institutions
  2. POST /v3/bank/iav
  3. POST /v3/bank

Find the bank

This will return a list of the institutions that we support for instant account verification. The response contains a login_form object, containing the login form fields the user will have to fill out. We suggest making this request at least once a week and no more often than once per day.

Our list of supported institutions does not change very often, and it is a better experience for your users if these results are cached on your end, instead of hitting our servers for the supported institutions for each account you onboard.

A sample response from this endpoint might look something like:

{ "institutions": [ { "id": "a34753da84194573807e72ae7dfc5dee", "login_form": [ { "description": null, "name": "username", "type": "TEXT" }, { "description": null, "name": "passcode", "type": "PASSWORD" } ], "name": "121 Financial Credit Union" } ] }

Where id is the id of the institution, name is the name of the institution and login_form is the data that the user needs to provide to login to their institution. Each item within the login_form list will contain description, name and type. The description is the name of the field that will be displayed to the user, the name is the name of the field that you will use in the response back to our api, and type can be TEXT, PASSWORD or OPTION. TEXT indicates that it is a text field, and PASSWORD indicates that it should be a password field (the input should be censored).

❗️

Institution ID

For any given institution, its id may be different depending on the environment. So don't use an institution id from sandbox for making an API call in production. Always use the ids returned by the GET /v3/bank/institutions call from the same environment.

Login to the bank

After the user fills out the login form, you will make a POST request to /v3/bank/iav containing the fields from login_form and an institution_id (this comes from the id field from the /v3/bank/institutions endpoint).

For example, if the login_form contains username and passcode, you may make a POST request containing something like:

{ "username": "user", "passcode": "p@ssw0rd", "institution_id": "a34753da84194573807e72ae7dfc5dee" }

Another example, if the login_form contains login and password, you may make a POST request containing something like:

{ "login": "user", "password": "p@ssw0rd", "institution_id": "a34753da84194573807e72ae7dfc5dee" }

🚧

Sandbox testing

On Sandbox, you can use the username checkbook_test and the password checkbook_good to login to a test account that doesn't have MFA verification.

Assuming the credentials you provide are valid, the IAV endpoint should either return a list of supported bank accounts at the institution (see Add the bank account ), or it will return MFA challenges.

There are 3 types of MFA challenges that may be returned (SELECTION, TEXT and IMAGE). For example, SELECTION challenge will have the user select the correct answer from a list of choices (think radio button or dropdown).

It is possible to have multiple MFA challenges as part of the instant account verification. So after successfully passing an MFA challenge, the IAV endpoint can either return a list of supported bank accounts or another MFA challenge.

In a common scenario, the bank may want to to verify the user's identify by sending a verification code. A first SELECTION challenge will be required to select how the verification code will be sent to the user (via SMS, EMAIL, etc.). Then a second TEXT challenge will prompt the user to enter the code received in order to complete the MFA process.

SELECTION challenge

🚧

Sandbox testing

On Sandbox, you can trigger a SELECTION challenge by calling https://api.sandbox.checkbook.io/v3/bank/iav with the following payload:

{ "institution_id": "a34753da84194573807e72ae7dfc5dee", "username": "checkbook_selection", "password": "checkbook_good" }

The SELECTION challenge will look something like:

{ "mfa": [ { "description": "What is 1+1?", "name": "checkbook_selection1", "selections": [ { "description": "1", "name": "ans_1" }, { "description": "2", "name": "ans_2" }, { "description": "3", "name": "ans_3" } ], "type": "SELECTION" } ] }

🚧

The mfa parameter needs to be an array of objects, and not a single object

SELECTION MFA objects will contain an extra field called selections which provides the user with an option that they will select. Also, the name value in the answer object must correspond to the name value of the MFA challenge (checkbook_selection1 in this example).

To answer the MFA challenge, you will create another POST request to /v3/bank/iav containing the user's response:

{ "mfa": [ { "type": "SELECTION", "name": "checkbook_selection1", "description": "What is 1+1?", "response": "ans_2" } ], "institution_id": "a34753da84194573807e72ae7dfc5dee" }

🚧

The mfa parameter needs to be an array of objects, and not a single object

TEXT challenge

🚧

Sandbox testing

On Sandbox, you can trigger a TEXT challenge by calling https://api.sandbox.checkbook.io/v3/bank/iav with the following payload:

{ "institution_id": "a34753da84194573807e72ae7dfc5dee", "username": "checkbook_question", "password": "checkbook_good" }

The TEXT challenge will look something like:

{ "mfa": [ { "description": "Is the sky blue?", "name": "checkbook_text1", "type": "TEXT" }, { "description": "Is the grass pink?", "name": "checkbook_text2", "type": "TEXT" } ] }

🚧

The mfa parameter needs to be an array of objects, and not a single object

To answer the MFA challenge, you will create another POST request to /v3/bank/iav containing the user's response:

{ "mfa": [ { "description": "Is the sky blue?", "name": "checkbook_text1", "response": "yes", "type": "TEXT" }, { "description": "Is the grass pink?", "name": "checkbook_text2", "response": "no", "type": "TEXT" } ], "institution_id": "a34753da84194573807e72ae7dfc5dee" }

🚧

The mfa parameter needs to be an array of objects, and not a single object

IMAGE challenge

🚧

Sandbox testing

On Sandbox, you can trigger an IMAGE challenge by calling https://api.sandbox.checkbook.io/v3/bank/iav with the following payload:

{ "institution_id": "a34753da84194573807e72ae7dfc5dee", "username": "checkbook_image", "password": "checkbook_good" }

The IMAGE challenge will look something like:

{ "mfa": [ { "description": "Please enter the word in the image", "image": "data:image/jpg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDABYPERMRDhYTEhMZFxYaITckIR4eIUQwMyg3UEZUU09GTUxYY39sWF54X0xNbpZweIOHjpCOVmqcp5uKpn+Ljon/2wBDARcZGSEdIUEkJEGJW01biYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYn/wAARCAA5ASwDASIAAhEBAxEB/8QAGwABAAMBAQEBAAAAAAAAAAAAAAMEBQYCAQf/xAAuEAACAwACAAUCBQQDAQAAAAAAAQIDBAURBhIhMUETIhQyQlFxFWGB0SNScpH/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A64AAAAABXv3Zc81C6+EJP4b9SdNSSaaafygPoBU08jmzT+nOfmsftCK7YFsFLJymbVa6YuULV+ia6Y2ctixT8l9yUv2XqBdBBl2Z9dfnz2Rmv7MqZ+V8+6WTRU6bP0d/qQGkAAAAAAAAAQ6defLFSvtjWn7dsCYEdN1d8FOqanF/KJAAAAAAAAAAAAAAAAAAAAAAAAGu00Bhcj4lpzafw2amWi1PpqP7/sR0+Ka1cqtuWzNJ/LM7jvw/EeItENz6cn/xzft6lzxLDib4w0XaG5x9Eq5JtgPFmbNPAtlcIuxtfevlGbl5nk9OaNORKqNUfun0afKOi3wonR3GCivKp+5n8fzGHHwn0YVOeiSakkgNrw9ylu/Da7mnZV6d/uUeI0vzXWwzS0aZTalP4Ri8Fs15dbdOeVkLX04pHU1cZpzWyvwWqtW/dKqxdrsCnbj5G7k4bbIV0+VdJJ+rKXA4q9vKapb15rYv8sjXlx3I7dVduy6Fddb7UK/kl5Tg47LFfntefRH9Ufn+QMe7Dt4jmI3Y6nLNJ+sYv06LfiSX0tfH7XFxhGX3NfBHqw+IZ0/R/EQsj/2T6Zbqx6Xw9mfln9T9nH1aAmfiLBC1V2Tce/aXwyTRyc1X9fHXHTSl3LyS9Ucdh4pX651/WinB/bGxdKSOn4yPH5b1BweXQ104t+kv4/cDVw7Kd2dXUy7Xs18plg53lMGvB9TXxNnljP7rK/j+UZePxXyEZNW0xuUffpdNAdsfJNRi5SfSXuzmdXP/AI7E5cdY69EfV1yXq1/Y+cTdzWvG7fPVdW+04T9G/wDIGjb4l4yu76bubffTaXojzzn4fVw9umuMbuo/bJevRhcZHJl1X0bMjff5lJdyh/tFuLq4pTsy3w1YLPz0+b7o/wAAVcnNvHgz5uPgrLpfmjL37NzjLuZstT2UwjU/290YTwYKLIb6nZZlsfp5fSVbNT+ras0VZV3szr3Ti4zX+wOiBnYuZza5KHU6pv8ATOPRogAAAAAAAAAAAAAAAAAAAAAFPfxmTkElpqUmvaXsylT4Y4uqzz/SlPr2Updo2QBn6eGxaZxlbBtR9FFP0/8AhPVgyUrqvPXFf+SyAPEKq611CEY/wj2AAAAAAAQ25c9v56YP+/RR5Dg826EYuU4OH5XF+xqADKwYNuSX0p6ldn666kvU5Xfw3IUbLrc9MvpuT66+Ud+APznjOM3vfXL8PYkpdt9dG3o/qfD7JvHR9Siz7vL130zq+ugBy+fHyHKcnVt00rNCHuvmRb1eFsOjQ7YynX5n24x9jdAFfLioy51RXBeRfD9SeMIxXSil/g+gDy64N9uEe/4PQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/9k=", "name": "checkbook_image1", "type": "IMAGE" } ] }

🚧

The mfa parameter needs to be an array of objects, and not a single object

To answer the MFA challenge, you will create another POST request to /v3/bank/iav containing the user's response:

{ "mfa": [ { "description": "Please enter the word in the image", "name": "checkbook_image1", "response": "checkbook", "type": "IMAGE" } ], "institution_id": "a34753da84194573807e72ae7dfc5dee" }

🚧

The mfa parameter needs to be an array of objects, and not a single object

Add the bank account

Once the user has successfully logged into their bank and filled in the required MFA information if necessary, you will receive a response from the /v3/bank/iav endpoint that looks something like:

{ "accounts": [ { "name": "Checking 1", "routing": "122105155", "account": "-1234" }, { "name": "Savings", "routing": "122105155", "account": "-0000" }, ] }

Where name is a display name for the account, routing is the routing number for the account, and account is the last 4 of the account number prepended to a '-' character. The values accepted for type are CHECKING (for personal checking accounts), SAVINGS (for personal savings accounts), and BUSINESS (for business accounts).

Once you have the user select which account they wish to add, you will make a POST request to /v3/bank containing the routing and account information returned by the /v3/bank/iav endpoint. For example (yes, you will include the '-' character as well):

{ "type": "CHECKING", "routing": "122105155", "account": "-1234" }