> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Fetch Account and Routing Numbers

<Note>
  **LEGACY GUIDE**

  This guide is for Platform API v2011101. For guidance on the newest version, see [Connectivity Integration Guides](/products/connectivity/overview/connectivity-integration-guides/).
</Note>

The following guide starts at the beginning and shows you how to navigate the Platform API to get an end user's account and routing number for verification.

Before following the steps in this guide, you'll need to:

* Sign up for access to the Platform API and [get your development API keys](https://dashboard.mx.com).
* Retrieve your `client_id` and `api_key` as you'll need them to pass requests.
* Whitelist your IP addresses.
* Ensure all requests are using HTTPS with TLSv1.2 encryption or higher or else they will fail.

Keep the following in mind:

* IAV applies only to demand deposit accounts. Functionally, this means that only `CHECKING` and `SAVINGS` accounts are likely to return account/routing numbers.
* IAV does not provide a complete money movement or payments solution. Rather, it provides the necessary account numbers to facilitate payments through payment processors and the ACH system.
* Account and routing numbers can be used for ACH transfers for as long as the account is still open; in most cases, you don't need to use IAV for an account more than once.

## Workflow

You'll use this workflow with the Platform API.

1. Create a `user`.
2. Create a `member` using the correct institution code and credentials required by that institution. When a member is created, an Account Aggregation is automatically started; this can be stopped with the `skip_aggregation` parameter.
3. Call the `verify` endpoint.
4. Poll the member's connection status.
5. Answer multifactor authentication, if necessary.
6. Answer the special account-selection challenge.
7. Poll the verification status until an end state is reached. A verification is successful when the `connection_status` is `CONNECTED` and the `is_aggregating` field changes from `true` to `false`.
8. List the member's account numbers.

## 1. Create a User

A user represents your end user in the MX Platform. Make a request to the [Create User](/api-reference/platform-api/reference/create-user) endpoint (`POST /users`).

We recommend that you include a unique [`id`](/api-reference/platform-api/overview/formats-requirements#identifiers-and-metadata) of your choice with the request. You may also include `metadata`, such as the date the `user` was created or the end user's name. Don't include any sensitive information here, such as credentials.

<Info>
  **INFO**

  None of these parameters are required, but the `user` object can't be empty. We recommend that you always set the `id` parameter when creating a user.
</Info>

In the response, the API gives each new `user` an MX-defined `guid` (or `user_guid` when appearing outside the `user` object). Between your `id` and the `guid`, you can map between your system and ours. You'll need the user `guid` for nearly every request on the MX API, at least when using basic authorization.

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i -X POST 'https://int-api.mx.com/users' \
    -u 'client_id:api_key' \
    -H 'Accept: application/vnd.mx.api.v1+json' \
    -H 'Content-Type: application/json' \
    -d '{
      "user": {
        "id": "partner-2345",
        "is_disabled": false,
        "email": "example@example.com",
        "metadata": "Some metadata"
      }
    }'

    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "user": {
    "email": "totally.fake.email@notreal.com",
    "guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c",
    "id": "partner-2345",
    "is_disabled": false,
    "metadata": "Yada yada yada"
    }
    }

    ```
  </Tab>
</Tabs>

## 2. Create a Member

Next, create a `member`. A member represents the relationship between a `user` and an `institution`, and creating one is how you connect one to the other. Multiple members may be attached to a single `user` (for example, one `member` for their bank, another for their mortgage provider, another for their credit card provider, etc.).

To create a member:

1. Search for an institution
2. Get the institution-required credentials
3. Make a request to the create member endpoint

### a. Search for an Institution

First, you need to know what financial `institution` the `member` should be connected to and what type of credentials the `institution` expects to get.

Search for an institution by making a GET request using query parameters on the [list institutions](/api-reference/platform-api/reference/list-institutions) endpoint.

The example that follows searches for MX Bank, which is MX's institution for testing and development. The response returns a paginated list of institutions that match the string you send in the `name` query parameter. Make a note of the `code` you find in the example response; you'll need this for the next step.

### b. Get the Institution-Required Credentials

Each institution requires different types of credentials. Some require an email and a password, some require a username and a password, and some may require other types of credentials.

Make a request to the [List Institution Credentials endpoint](/api-reference/platform-api/reference/list-institution-credentials) (`GET /institutions/{institution_code}/credentials`). Include the institution code retrieved from the previous step in the request path.

This endpoint returns the `GUID` for each required credential, which is used to match the credentials the end user provides to the required credential type when creating a member.

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -X GET https://int-api.mx.com/institutions/mxbank/credentials \
      -H 'Accept: application/vnd.mx.api.v1+json' \
      -u 'client_id:api_key'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "credentials": [
        {
          "display_order": 1,
          "field_name": "LOGIN",
          "field_type": "LOGIN",
          "guid": "CRD-9f61fb4c-912c-bd1e-b175-ccc7f0275cc1",
          "label": "Username"
        },
        {
          "display_order": 2,
          "field_name": "PASSWORD",
          "field_type": "PASSWORD",
          "guid": "CRD-e3d7ea81-aac7-05e9-fbdd-4b493c6e474d",
          "label": "Password"
        }
      ]
    }
    ```
  </Tab>
</Tabs>

### c. Create the Member

After you have the `user_guid`, an `institution_code`, and a `guid` for each credential required by the institution, create a new `member`. For this step, you need the values provided by the end user for each necessary credential.

Make a POST request to the [create member](/api-reference/platform-api/reference/create-member) endpoint shown below. There are several parameters that you can pass in this request which are included in the table below.

| Parameter                            | Data Type | Description                                                                                                                                                                                                                          | Required? |
| ------------------------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- |
| `background_aggregation_is_disabled` | Boolean   | When set to `true`, background aggregation will be disabled for this `member`.                                                                                                                                                       | No        |
| `credentials`                        | Array     | The credentials endpoint for the requested `institution` will give you a list of all the `credentials` required to create a `member` for a given `institution`. Each required credential will need to be included within this array. | Yes       |
| `id`                                 | String    | The unique partner-defined identifier for the `member`.                                                                                                                                                                              | No        |
| `institution_code`                   | String    | The unique code for the `institution` to which the `member` will connect. Defined by MX.                                                                                                                                             | Yes       |
| `metadata`                           | String    | Additional information you can store on this `member`.                                                                                                                                                                               | No        |

The following example uses MX Bank and requires a username and a password. It sets the username to `mxuser` and the password to `password` which are the credentials for the test user for MX Bank. For real institutions, these values must be the end user's correct login information.

<Warning>
  **WARNING**

  Do not add multiple members that connect to the same `institution` using the same `credentials` on the same `user`. This will result in a `409 Conflict` error.
</Warning>

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i -X POST 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members' \
    -u 'client_id:api_key' \
    -H 'Accept: application/vnd.mx.api.v1+json' \
    -H 'Content-Type: application/json' \
    -d '{
          "member": {
            "credentials": [
              {
                "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
                "value": "mxuser"
              },
              {
                "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
                "value": "password"
              }
            ],
            "institution_code": "mxbank"
          }
        }'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "member": {
        "aggregated_at": null,
        "connection_status": "CREATED",
        "background_aggregation_is_disabled": false,
        "guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0",
        "id": null,
        "institution_code": "mxbank",
        "is_being_aggregated": true,
        "metadata": null,
        "name": "MX Bank",
        "successfully_aggregated_at": null,
        "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c"
      }
    }
    ```
  </Tab>
</Tabs>

If the request is successful, the response returns with the newly created `member` and indicates that the connection process has started. The `connection_status` should be `CREATED` and the `is_being_aggregated` field should be `true`.

The `connection_status` must be one of the following in order to continue with verification:

* `CREATED`
* `CONNECTED`
* `DEGRADED`
* `DISCONNECTED`
* `EXPIRED`
* `FAILED`
* `IMPEDED`
* `RECONNECTED`
* `UPDATED`

<Info>
  **INFO**

  We suggest you add a Connection Status Webhook in the Client Dashboard. We provide webhooks that send HTTPS POST callback requests to the URL of your choice. This webhook notifies you whenever a member's connection\_status field enters into an end-user-actionable state. For more information on webhooks, click [here](/resources/webhooks).
</Info>

## 3. Fetch Account and Routing Number

Now that you've created a member, you can request account and routing number to verify the end-user's financial account using Instant Account Verification (IAV).

To start the process, make a POST request to the [verify member](/api-reference/platform-api/reference/verify-member) endpoint.

The response indicates the status of the request. Next you'll check the connection status and answer any possible challenges.

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i -X POST 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0/verify' \
      -u 'client_id:api_key' \
      -H 'Accept: application/vnd.mx.api.v1+json' \
      -H 'Content-Type: application/json'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "member": {
        "aggregated_at": null,
        "background_aggregation_is_disabled": false,
        "connection_status": "CREATED",
        "guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0",
        "id": null,
        "institution_code": "mxbank",
        "is_being_aggregated": true,
        "is_managed_by_user": true,
        "is_oauth": false,
        "metadata": null,
        "name": "MX Bank",
        "successfully_aggregated_at": null,
        "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c",
        "user_id": null
      }
    }
    ```
  </Tab>
</Tabs>

### a. Check the Connection Status

After verification has been initiated, poll the member by making a GET request to the [read member](/api-reference/platform-api/reference/read-member) endpoint. We suggest you invoke this call every 2 to 3 seconds until a member is in a connected state and no longer being aggregated.

```shell theme={null}
curl -i 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0/status' \
-H 'Accept: application/vnd.mx.api.v1+json' \
-u 'client_id:api_key'
```

Poll until the `connection_status` is `CONNECTED` and `is_being_aggregated` is `false`. This indicates that the member has been authenticated and verification has begun.

```json theme={null}
{
  "member": {
    "aggregated_at": null,
    "connection_status": "CREATED",
    "guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0",
    "is_authenticated": false,
    "is_being_aggregated": true,
    "successfully_aggregated_at": null
  }
}
```

### b. Answer the Account-Selection Challenge

The end user must select which account to verify. If you have to select an account, the status switches to `CHALLENGED`, and the response includes the challenges you need to answer.

If you don't get the challenge and the member goes to `connection_status: IMPEDED` and `is_being_aggregated: false`, it means that there are no eligible accounts to verify and there's nothing more to do.

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i -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' \
      -u 'client_id:api_key'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "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"
      }
    }
    ```
  </Tab>
</Tabs>

#### 1. Use the Resume Endpoint

To answer the account-selection challenge, present the challenge from the previous step to end users, gather their response, and return it to MX using the resume endpoint. You may or may not run into MFA issued by the institution. If you do, you may get challenged multiple times.

Use the [resume aggregation](/api-reference/platform-api/reference/resume-aggregation) endpoint to answer the challenge. Include the appropriate credential GUID with the value chosen by the end user.

The response should come back with `connection_status: RESUMED`.

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i -X PUT 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa/resume' \
    -u 'client_id:api_key' \
    -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"
              }
            ]
          }
        }'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "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"
      }
    }
    ```
  </Tab>
</Tabs>

#### 2. Check the Status Again

Check `connection_status`, `is_being_aggregated`, and `successfully_aggregated_at`.

* The `is_being_aggregated` field indicates whether verification is complete; it'll be `true` while IAV is running and `false` when complete.
* When you see `connection_status: CONNECTED` and `is_being_aggregated: false` at the same time, verification is done and you can pull account and routing data.
* The `successfully_aggregated_at` field gives the exact time verification was finished.

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i -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' \
      -u 'client_id:api_key'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "member": {
        "aggregated_at": "2022-02-02T13:15:14Z",
        "connection_status": "CONNECTED",
        "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa",
        "has_processed_accounts": true,
        "has_processed_transactions": true,
        "is_authenticated": true,
        "is_being_aggregated": false,
        "successfully_aggregated_at": "2022-02-02T20:24:48Z"
      }
    }
    ```
  </Tab>
</Tabs>

## 4. Read the Account Numbers

When verification is complete, retrieve account and routing numbers. There are two endpoints for this: [list account numbers by member](/api-reference/platform-api/reference/list-account-numbers-by-member) and [list account numbers by account](/api-reference/platform-api/reference/list-account-numbers-by-account). The first is shown here.

* If MX has both an account number and a routing number for at least one of the member's accounts, that information is returned. No information is returned for accounts that are missing a value for one or both of these fields.
* The account number returned from this endpoint may be a Tokenized Account Number (TAN). See the [section on TANs](/products/connectivity/instant-account-verification#tokenized-account-numbers) for information on dealing with these properly.

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0/account_numbers' \
      -H 'Accept: application/vnd.mx.api.v1+json' \
      -u 'client_id:api_key'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "account_numbers": [
        {
          "account_guid": "ACT-82a93692-f756-534f-9b2e-ad10a0f38462",
          "account_number": "10001",
          "institution_number": null,
          "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0",
          "routing_number": "091000019",
          "passed_validation": true,
          "transit_number": null,
          "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c"
        }
      ],
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 1,
        "total_pages": 1
      }
    }
    ```
  </Tab>
</Tabs>
