Introduction

This guide explains how to deal with multi-factor authentication (MFA) while running an aggregation-type process. There’s a lot of material in here that’s quite similar to our guide on the happy aggregation path without MFA, except that it’s expanded and explained in more detail.

General steps

Aggregating account and transaction data is one of the most important features of the MX API. Seeing when, where, and how much people are spending is core not only to personal financial management, but also to hundreds of fintechs, banks, credit unions, and financial companies who seek to learn from and improve the financial lives of their customers.

It can also be a somewhat complicated process, especially when dealing with issues like multi-factor authentication (MFA). This guide will walk you through the process step-by-step so that you can see the potential pitfalls and avoid them.

In general, it involves:

  1. Making a request to the aggregate member endpoint;
  2. Repeatedly check the member for changes in the state of the aggregation using the read member connection status endpoint and looking at fields such as connection_status, is_being_aggregated, is_authenticated, has_processed_accounts, etc.;
  • Using the Connect widget provided by MX greatly simplifies and automates steps 2 and 3;
  1. If necessary, answering MFA challenges using the resume aggregation endpoint;
  2. Reading aggregated data using the list accounts and list transactions endpoints.

Before we get to the real step-by-step, though, there’s some things you should know that will make your development much easier.

There are multiple aggregation-type processes in the MX API

One important thing to point out up front is that there are multiple processes in the API that follow the same general steps and workflows. This guide will help you with all of them, but we’ll focus on standard aggregation in the examples here.

Aggregation-type processes include:

  • Standard aggregation
  • Account verification
  • Identification
  • Fetching an extended transaction history
  • Fetching account statements
  • Fetching account balances
  • Fetching account rewards information

Important fields and states: connection_status, is_being_aggregated, and more

There are multiple fields on each member that give you all the information you need to determine what state it is in and how to resolve that state into a successful aggregation — as well as when resolution is not possible. These all need to be weighed together in order to make an aggregation successful.

The connection_status field indicates the current state of an aggregation in a general way. For instance, a value of CREATED indicates that the member has just been created. A value of CHALLENGED means the aggregation has run into MFA. FAILED means that the aggregation was unsuccessful. Below, you’ll see exact definitions and next steps for each of the 21 connection statuses.

Another important field is the boolean is_being_aggregated. This indicates whether an aggregation process is currently taking place on the MX platform.

These fields should be used in conjunction with several other member fields to determine future actions. These include aggregated_at, successfully_aggregated_at, and is_authenticated.

For example, when the connection_status is CONNECTED and the is_being_aggregated field is false, this means the latest aggregation attempt has finished and data for accounts and transactions can be read. You can use the field successfully_aggregated_at to determine when the last successful aggregation occurred.

The connection statuses CREATED, UPDATED, DELAYED, and RESUMED represent transient states for different points in the aggregation process and generally do not require a specific action or end-user input. They may, however, require you to keep making read requests on the member until an actionable status or an end state shows up.

The connection statuses PREVENTED, DENIED, IMPEDED, IMPAIRED, REJECTED, EXPIRED, LOCKED, IMPORTED, DISABLED, DISCONTINUED, and CLOSED, represent end states that will require a new aggregation, and possibly end-user input for future success.

But we’ll get into more detail about all these various statuses in future guides. For right now, we’ll focus on the happy path.

Member fields to pay attention to

Field Name Data Type Description
aggregated_at String The date and time the member the last aggregation was initiated, represented in ISO 8601 format with timestamp (e.g., 2015-04-13T12:01:23-06:00).
connection_status String This field indicates the state of a member’s aggregation, provided as a string. See member connection statuses for more information on possible values.
is_being_aggregated Boolean This field will be true if the member is being aggregated at the time of the request. Otherwise, this field will be false.
successfully_aggregated_at String The date and time the account was last successfully aggregated, represented in ISO 8601 format with timestamp (e.g., 2015-04-13T12:01:23-06:00).

Connection status definitions

Integer value Status Definition Next steps End-user message
null null The member exists but does not have credentials. A member that does not aggregate (e.g., a manual member) will always have this status. None. None.
0 CREATED The member is new and has not yet been aggregated. Aggregate the member once the end user logs in; poll for a status update. Connecting to {…} …
1 PREVENTED MX is preventing aggregation until the member’s credentials have been updated. Display end-user message; after end user has updated their credentials, aggregate again. The last 3 attempts to connect have failed. Please re-enter your credentials to continue importing data.
2 DENIED The credentials provided for the member were invalid. Display end-user message; after end user has updated their credentials, aggregate again. The credentials entered do not match your credentials at this institution. Please re-enter your credentials to continue importing data.
3 CHALLENGED The member has been challenged by multi-factor authentication. Display end-user message; follow MFA pathway; after the user answers MFA, poll for a status update. To authenticate your connection to {…}, please answer the following challenge(s).
4 REJECTED An MFA challenge was answered incorrectly. Display end-user message; another challenge may follow or aggregation may need to be restarted. The answer or answers provided were incorrect. Please try again.
5 LOCKED The financial institution is preventing authentication. The end user must contact the financial institution. Display end-user message. Your account is locked. Please log in to the appropriate website for {…} and follow the steps to resolve the issue.
6 CONNECTED The member was successfully authenticated and data is now aggregating. Display the account as having been connected. Connected to […] …
7 IMPEDED The end user’s attention is required at their online banking institution, e.g., there is a marketing message that must be viewed, terms and conditions that must be accepted, etc. Display end-user message. Your attention is needed at this institution’s website. Please log in to the appropriate website for {…} and follow the steps to resolve the issue.
8 RECONNECTED The member has been migrated to a new data source and aggregation is likely to trigger one-time password MFA. MX will not perform background aggregation in order to avoid unnecessarily disruptive texts, emails, etc. The member must be re-aggregated in the foreground with the end user present. Aggregate the member once the end user logs in; poll for a status update. Reconnecting to {…} …
9 DEGRADED Aggregation has failed at least three times within a short period of time. Display end-user message. We are upgrading this connection. Please try again later.
10 DISCONNECTED Aggregation has failed at least three times and has not succeeded for at least two weeks. Display end-user message. It looks like your data from {…} cannot be imported. We are working to resolve the issue.
11 DISCONTINUED The connection to this financial institution is no longer available. Display end-user message. Connections to this institution are no longer supported. You may create a manual account and use manual transactions to track data for this account.
12 CLOSED The end user, MX, the client, or a partner has marked the member as closed. Display end-user message. This connection has been closed. You may track this account manually. If reopened, you may connect the institution again.
13 DELAYED Aggregating the member has taken longer than expected and it has not yet been connected. Display end-user message; poll for a status update. Importing your data from {…} may take a while. Please check back later.
14 FAILED Aggregation failed without being connected. Display end-user message; try aggregating again later. There was a problem validating your credentials with {…}. Please try again later.
15 UPDATED The member has been updated — i.e., credentials have been updated — but it has not yet been connected. Aggregate the member once the end user logs in; poll for a status update. Connecting to {…} …
16 DISABLED Aggregation has been momentarily paused, but the member is still connected. Display end-user message. Importing data from this institution has been disabled. Please contact us if you believe it has been disabled in error.
17 IMPORTED MX does not have credentials and will not try to aggregate the member until the end user provides credentials. Display end-user message; re-aggregate after the end user updates credentials. You must re-authenticate before your data can be imported. Please enter your credentials for {…}.
18 RESUMED The answer to an MFA challenge was received, but it is not yet clear whether it was correct. Poll for a status update. Connecting to {…} …
19 EXPIRED The MFA answer was not provided within the time allotted by the financial institution. Display end-user message; re-aggregate the member if the end user initiates it. The answer or answers were not provided in time. Please try again.
20 IMPAIRED The member is missing some or all credentials needed in order to connect. Display end-user message; re-aggregate after the end user updates credentials. You must re-authenticate before your data can be imported. Please enter your credentials for {…}.

Background aggregation, automatic aggregation, and the skip_aggregation parameter

MX aggregates each member every 24 hours without you having to do anything. This process is called background aggregation. It ensures that end users’ data will always be up to date. This is beneficial because if a background aggregation is successful (i.e., the successfully_aggregated_at field indicates a time within the last 24 hours) you can choose to skip manual aggregation and jump right to reading account and transaction data, which can help you load things faster in your product.

If an end user is present, you can often choose to manually run an aggregation using the general steps in this guide. End users must be present during manual aggregations because they may run into MFA, credential update requests, terms and conditions agreements, or any number of other situations requiring end-user input. Just keep in mind that you cannot run a new aggregation within three hours of a successful aggregation, whether manual or background. So pay attention to those aggregated_at and successfully_aggregated_at fields while you’re developing your product with the MX API.

Both manual and background aggregation may be prevented by disabling a user. A user must be re-enabled before any aggregation can be attempted.

MX may also suspend background aggregation on a particular member in some circumstances, such as when several consecutive aggregation attempts fail. However, you can always attempt a manual aggregation on a suspended member.

Automatic aggregation is a bit different. Every time a new member is successfully created or an existing member is successfully updated, an aggregation process will start automatically, without having to manually call the aggregate member endpoint. You will, however, need to follow up on the rest of the aggregation process, like looking for changes in the connection status, answering MFA, etc.

If your workflow requires that there not be any automatic aggregation, you can easily prevent it by including the skip_aggregation body parameter and setting it to true in either a create member or update member request.


1. Check the member's connection status

Now that you’ve got all that important information above, we can take you through the actual aggregation process step by step, including the MFA process.

The first step is to check the member’s connection_status to see whether aggregation is either necessary or even possible. Each status indicates something different; some connection statuses mean that an aggregation will fail if attempted or that an aggregation is already in progress. Again, we’ll focus on an easy case where aggregation proceeds successfully for this example, but here’s some important information on what these statuses mean anyway.

In general, aggregation can be attempted for a member with the following connection statuses:

  • CREATED
  • CONNECTED
  • DEGRADED
  • DISCONNECTED
  • EXPIRED
  • FAILED
  • IMPEDED
  • RECONNECTED
  • UPDATED

In general, you must update credentials before aggregating a member with the following connection statuses:

  • PREVENTED
  • DENIED
  • IMPAIRED
  • IMPORTED

The following connection statuses represent a transitory state in an ongoing aggregation process:

  • CHALLENGED
  • DELAYED
  • REJECTED
  • RESUMED

You should not attempt aggregation on a member with the following connection statuses:

  • CLOSED
  • DISABLED
  • DISCONTINUED

Endpoint:

GET /users/{user_guid}/members/{member_guid}/status

Example request

1
2
3
curl -L -X GET 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa/status' \
-H 'Accept: application/vnd.mx.api.v1+json' \
-H 'Authorization: Basic {token}'

Example response

1
2
3
4
5
6
7
8
9
10
{
  "member": {
    "aggregated_at": "2020-09-21T19:38:01Z",
    "connection_status": "CONNECTED",
    "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa",
    "is_authenticated": true,
    "is_being_aggregated": false,
    "successfully_aggregated_at": "2020-09-21T19:44:17Z"
  }
}

Notice the various fields you see. This shows a member that was successfully authenticated and aggregated on September 21, 2020, but is not currently being aggregated. You see a connection_status of CONNECTED, which was the final state of the member at the end of the last aggregation. All this means we can proceed to the next step and actually request a new aggregation.


2. Call the aggregate member endpoint

Go ahead and make a request to the aggregate member endpoint.

Endpoint:

POST /users/{user_guid}/members/{member_guid}/aggregate

Example request

1
2
3
4
curl -L -X POST 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa/aggregate' \
-H 'Authorization: Basic {token}' \
-H 'Accept: application/vnd.mx.api.v1+json' \
-H 'Content-Type: application/json'

Example response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "member": {
    "aggregated_at": "2020-09-21T19:48:57Z",
    "connection_status": "CONNECTED",
    "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa",
    "id": null,
    "institution_code": "mxbank",
    "is_being_aggregated": true,
    "metadata": null,
    "name": "MX Bank",
    "successfully_aggregated_at": "2020-09-21T19:44:17Z",
    "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c"
  }
}

Notice in the example response that the member still has a connection_status of CONNECTED and successfully_aggregated_at is still the date and time.

However, the aggregated_at field has updated to the time the request was made, and the is_being_aggregated boolean is now true. This shows that the aggregation process is active and ongoing. The connection_status hasn’t changed from what it was at the last aggregation because the current process has not run into any errors or obstacles. However, it may change at any time in the process, so we need to check the status again.


3. Read the connection status again

Let’s check the connection status again to see what’s happening in this current aggregation.

Endpoint:

GET /users/{user_guid}/members/{member_guid}/status

Example request

1
2
3
curl -L -X GET 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa/status' \
-H 'Accept: application/vnd.mx.api.v1+json' \
-H 'Authorization: Basic {token}'

Example response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "member": {
    "aggregated_at": "2020-09-21T19:48:57Z",
    "challenges": [
      {
        "field_name": null,
        "guid": "CRD-8f841084-66cb-4e3d-9253-96f97093100a",
        "label": "What city were you born in?",
        "type": 0
      }
    ],
    "connection_status": "CHALLENGED",
    "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa",
    "is_authenticated": false,
    "is_being_aggregated": true,
    "successfully_aggregated_at": "2020-09-21T19:44:17Z"
  }
}

Notice that the connection status is CHALLENGED and there is a new array returned in this response called challenges. This indicates that the aggregation has run into multi-factor authentication, and the status response includes the specific question or questions the end user will need to answer in order to proceed. Make a note of both the guid in the challenges array and the label, which is thins case What city were you born in?.


4. Answer the challenges with the resume aggregation endpoint

The resume aggregation endpoint allows you to answer the challenges presented during MFA and continue the aggregation process. In the body of the request, you’ll need to include the challenge guid provided in the previous response and the correct answer to the question given in the label field of the last response.

In this case, we’re using MX Bank. The proper answer to any challenge when using MX Bank is correct if you desire to proceed successfully. In an actual MFA situation, the end user will need to provide the correct answer to the question. If the security question is What city were you born in?, the answer may be Chicago, Talahassee, etc.

There are also more exotic forms of MFA such as choosing from multiple options (like choosing from a list of phone number to text a code to), or choosing the correct pre-determined photo. These will not be covered in this guide, but you should be aware that they exist and that they can be answered with the MX API.

A relatively common scenario is requiring one-time code texted to a phone number. In this case, you’ll be using the resume aggregation endpoint twice: once to choose the phone number, and then again to provide the correct code. In this case, you’ll also need to use the read member status endpoint multiple times and you’ll get two different challenge GUIDs, one for the phone number and one for the code.

Endpoint:

PUT /users/{user_guid}/members/{member_guid}/resume

Example request

1
2
3
4
5
6
7
8
9
10
11
12
13
14
curl -L -X PUT 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa/resume' \
-H 'Authorization: Basic {token}' \
-H 'Accept: application/vnd.mx.api.v1+json' \
-H 'Content-Type: application/json' \
-d '{
      "member": {
        "challenges": [
          {
            "guid": "CRD-8f841084-66cb-4e3d-9253-96f97093100a",
            "value": "correct"
          }
        ]
      }
    }'

Example response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "member": {
    "aggregated_at": "2020-09-21T19:48:57Z",
    "connection_status": "RESUMED",
    "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa",
    "id": null,
    "institution_code": "mxbank",
    "is_being_aggregated": true,
    "metadata": null,
    "name": "MX Bank",
    "successfully_aggregated_at": "2020-09-21T19:44:17Z",
    "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c"
  }
}

Notice that connection_status has changed to RESUMED and is_being_aggregated is still true. However, the is_authenticated field is still false. This indicates that the MFA answer provided was correct and the aggregation is proceeding, but the member’s login credentials have not yet been authenticated. We’ll need to keep checking the status to make sure there are no more challenges or errors.

Next Steps

Read account and transaction data

Now that you’ve gone through the work of creating a user, a member, and aggregating data, it’s time to actually get a look at the account and transaction data that has been gathered.