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

# Payment Verification with the API

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

In this guide, we cover the steps for connecting your end user's account to retrieve account and routing number, account owner information, and additional account details such as balance. This guide only uses API endpoints to connect members and fetch the data you need.

You'll want to use an API-only integration if:

* You don't want to use our [Connect Widget](/connect).
* You need a highly-customized solution that you want to build yourself.

The flow for payment verification is as follows:

1. Create a user
2. Create a member
3. Fetch and read the account and routing number to verify the account.
4. Fetch and read account owner data to verify the identity of the end user and the account owner.
5. Read the account details to verify account balance and account status for payments.
6. Fetch and read balance data for future payments.

## Before you Begin

Before you can you can use this guide, complete the following:

* Sign up for the [Client Dashboard](https://dashboard.mx.com/).
* Retrieve your `client_id` and `api_key` from the dashboard; 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.
* Get familiar with MX Bank, our test environment; MX Bank only allows specific test scenarios; and our guides follow these test experiences.
* Work with your MX representative to enable the following products:
  * [Instant Account Verification](/products/connectivity/instant-account-verification)
  * [Account Owner Identification](/products/connectivity/account-owner-identification/)
  * [Balance Checks](/products/connectivity/balance-checks/)

## Assumptions

In this guide we make a few assumptions about your use case to make it easier to follow:

* You are using the Platform API.
* It starts from the beginning and instructs you to create a user first. It assumes that no user exists on our platform for your end user yet.
* You'll use our Platform API to create a user on the MX platform.
* To make this guide easier to follow, we don't cover multifactor authentication or OAuth. We have in-depth guides on how to manage MFA or OAuth depending on the product you're using.

## 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 GET request to the [list institution credentials](/api-reference/platform-api/reference/list-institution-credentials) endpoint.

Include the institution `code` retrieved from the previous step in the request URL. This endpoint returns the `guid` for each credential returned, which is used to match the credentials the end user provides to the required credential type in the next step.

<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       |
| `metadta`                            | 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>

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

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

The `connection_status` must be one of the following to continue with verification. For this guide, we just created a member so the `connection_status` is still `CREATED` and we can move forward, but if you've already connected a member for a different reason, validate that the status is one of the following. Also, validate that `is_being_aggregated: false` because you can't initiate verification for a member if a connection already in process.

* `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. See [Webhooks](/resources/webhooks) for more information.
</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). For more information about this product, review our IAV guides.

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-3 seconds until a member is in a connected state and no longer being aggregated.

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

<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/status' \
    -H 'Accept: application/vnd.mx.api.v1+json' \
    -u 'client_id:api_key'
    ```
  </Tab>

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

### 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 directly to `connection_status: CONNECTED` 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 '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'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "member": {
    "aggregated_at": null,
    "challenges": [
      {
        "field_name": null,
        "guid": "CRD-bc26dc1d-9fe3-41f1-9d67-e84070cf3055",
        "label": "Please select an account:",
        "options": [
          {
            "label": "Checking",
            "value": "act-23445745"
          },
          {
            "label": "Savings",
            "value": "act-352386787"
          }
        ],
        "type": "OPTIONS"
      }
    ],
    "connection_status": "CHALLENGED",
    "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa",
    "is_authenticated": true,
    "is_being_aggregated": true,
    "successfully_aggregated_at": null
    }
    }
    ```
  </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-bc26dc1d-9fe3-41f1-9d67-e84070cf3055",
            "value": "act-23445745"
          }
        ]
      }
    }'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "member": {
    "aggregated_at": null,
    "background_aggregation_is_disabled": false,
    "connection_status": "RESUMED",
    "guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0",
    "id": null,
    "institution_code": "mxbank",
    "is_being_aggregated": true,
    "is_oauth": false,
    "metadata": null,
    "name": "MX Bank",
    "successfully_aggregated_at": null,
    "user_guid": "USR-151a102b-90b3-1bc3-48d1-c24cad5a2b13",
    "user_id": "10405939560"
    }
    }
    ```
  </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 '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'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "member": {
    "aggregated_at": "2020-05-07T22:01:00Z",
    "connection_status": "CONNECTED",
    "guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0",
    "is_authenticated": true,
    "is_being_aggregated": false,
    "successfully_aggregated_at": "2020-05-07T22:01:25Z"
    }
    }
    ```
  </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": "68899990000000",
      "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>

## 5. Read the Account Details

Before using the account numbers you've just gathered for things like ACH transfers, read the account details by making a GET request to the [read account](/api-reference/platform-api/reference/read-account) endpoint.
Read the account's details to confirm that:

* The `available_balance` shows sufficient funds.
* The account is still open: `is_closed: false`.

This helps [prevent ACH returns](/products/connectivity/overview/best-practices).

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i -X GET 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/accounts/ACT-82a93692-f756-534f-9b2e-ad10a0f38462' \
    -H 'Accept: application/vnd.mx.api.v1+json' \
    -u 'client_id:api_key'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "account": {
    "account_number": "****0001",
    "apr": null,
    "apy": null,
    "available_balance": 500000,
    "available_credit": null,
    "balance": 500000,
    "cash_balance": null,
    "cash_surrender_value": null,
    "created_at": "2020-09-21T19:43:44Z",
    "credit_limit": null,
    "currency_code": null,
    "day_payment_is_due": 12,
    "death_benefit": null,
    "guid": "ACT-82a93692-f756-534f-9b2e-ad10a0f38462",
    "holdings_value": null,
    "id": "act-23445745",
    "imported_at": "2023-02-24T09:01:25Z",
    "institution_code": "mxbank",
    "insured_name": null,
    "interest_rate": null,
    "is_closed": false,
    "is_hidden": false,
    "last_payment": null,
    "last_payment_at": null,
    "loan_amount": null,
    "matures_on": null,
    "member_guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa",
    "member_id": null,
    "member_is_managed_by_user": true,
    "metadata": null,
    "minimum_balance": null,
    "minimum_payment": null,
    "name": "Checking",
    "nickname": null,
    "original_balance": null,
    "pay_out_amount": null,
    "payment_due_at": "2021-05-12T16:01:00Z",
    "payoff_balance": null,
    "premium_amount": null,
    "routing_number": "005026788",
    "started_on": null,
    "subtype": null,
    "total_account_value": null,
    "type": "CHECKING",
    "updated_at": "2023-02-24T09:01:25Z",
    "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c",
    "user_id": "partner-2345"
    }
    }
    ```
  </Tab>
</Tabs>

## 6. Verify Account Owner Information

In addition to account and routing numbers, you may also want to verify the end-user's account information such as their first and last name, phone number, and potentially more using the Account Owner Identification product. For more information about this product, review our Account Owner Identification guide.

### a. Check the Member's status again

As with the IAV product, you can't initiate a new request to gather information if one is still in progress.

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 account owner identification 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 fetch the account owner data.
* The `successfully_aggregated_at` field gives the exact time the account owner identification finished.

### b. Make a Request to the Identity Endpoint

Make a POST request to the [identify member](/api-reference/platform-api/reference/identify-member) endpoint. This request starts the account owner identification process.

The response returns the status of the process that gathers the account owner information.

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i -X POST 'https://int-api.mx.com/users/USR-fa7537f3-48aa-a683-a02a-b18940482f54/members/MBR-7c6f361b-e582-15b6-60c0-358f12466b4b/identify' \
    -H 'Accept: application/vnd.mx.api.v1+json' \
    -H 'Content-Type: application/json' \
    -u 'client_id:api_key'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "member": {
    "aggregated_at": "2016-10-13T18:07:57.000Z",
    "background_aggregation_is_disabled": false,
    "connection_status": "CONNECTED",
    "guid": "MBR-7c6f361b-e582-15b6-60c0-358f12466b4b",
    "id": "unique_id",
    "institution_code": "chase",
    "is_being_aggregated": false,
    "is_managed_by_user": false,
    "is_oauth": false,
    "metadata": "\"credentials_last_refreshed_at\": \"2015-10-15\"",
    "name": "Chase Bank",
    "oauth_window_uri": "https://mxbank.mx.com/oauth/authorize?client_id=b8OikQ4Ep3NuSUrQ13DdvFuwpNx-qqoAsJDVAQCyLkQ&redirect_uri=https%3A%2F%2Fint-app.moneydesktop.com%2Foauth%2Fredirect_from&response_type=code&scope=openid&state=d745bd4ee6f0f9c184757f574bcc2df2",
    "successfully_aggregated_at": "2016-10-13T17:57:38.000Z",
    "user_guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54",
    "user_id": "user123"
    }
    }
    ```
  </Tab>
</Tabs>

### c. Read Account Owner Details

After you've connected, list account owner information using the [list account owners by member](/api-reference/platform-api/reference/list-account-owners-by-member) endpoint to review identity-related data. Information returned depends on what is available from the institution the end user connected to. You'll need the `user_guid` and `member_guid` to pass the request.

```shell theme={null}
curl -i -X GET 'https://int-api.mx.com/users/USR-fa7537f3-48aa-a683-a02a-b18940482f54/members/MBR-7c6f361b-e582-15b6-60c0-358f12466b4b/account_owners?page=1&records_per_page=10' \
  -H 'Accept: application/vnd.mx.api.v1+json' \
  -u 'client_id:api_key'
```

## 7. Fetch and Read Balance Data for Future or Delayed Payments

Account and routing numbers can be used for things like ACH transfers for as long as the account is still open, so there is no need to use IAV again for the account. However, information about the available balance in that account can become out of date within a few hours.

Before using these numbers again in the future (or if you wait a while to use them after the initial verification) run a balance check to get the latest `available_balance` before you initiate a payment or transfer. This prevents errors related to insufficient funds or closed accounts. For more information on Balance Checks, review our Balance Check product guide.

### a. Fetch Account Balance

Make a POST request to the [check balances](/api-reference/platform-api/reference/list-account-owners-by-member) endpoint.

Aggregating balance data takes some time, so check on the status of this process. Initially, you should see the `is_being_aggregated` field return with `true`.

<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/check_balance' \
    -H 'Accept: application/vnd.mx.api.v1+json' \
    -H 'Content-Type: application/json' \
    -u 'client_id:api_key'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "member": {
    "aggregated_at": "2023-02-24T21:33:23Z",
    "background_aggregation_is_disabled": false,
    "connection_status": "CONNECTED",
    "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": "Additional information",
    "name": "MX Bank",
    "successfully_aggregated_at": "2023-02-24T21:11:23Z",
    "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c",
    "user_id": "partner-2345"
    }
    }
    ```
  </Tab>
</Tabs>

### b. Check the Status of the Balance Process

The balance check is complete when the following state is reached. You may need to check the status multiple times using the [read member](/api-reference/platform-api/reference/read-member) endpoint.

* `connection_status: CONNECTED`
* `is_being_aggregated: false`
* `successfully_aggregated_at` updates to the current time.

<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-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0/status' \
    -H 'Accept: application/vnd.mx.api.v1+json' \
    -u 'client_id:api_key'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "member": {
    "aggregated_at": "2023-02-24T21:42:05Z",
    "connection_status": "CONNECTED",
    "guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0",
    "has_processed_account_numbers": false,
    "is_authenticated": true,
    "is_being_aggregated": false,
    "successfully_aggregated_at": "2023-02-24T21:42:07Z"
    }
    }
    ```
  </Tab>
</Tabs>

### c. Read the Account Details Again

Check to see that `available_balance` is sufficient for your purposes and that `is_closed` is `false`. Make a GET request to the [read account](/api-reference/platform-api/reference/read-account) endpoint.

<Tabs>
  <Tab title="Request">
    ```shell theme={null}
    curl -i -X GET 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/accounts/ACT-82a93692-f756-534f-9b2e-ad10a0f38462' \
    -H 'Accept: application/vnd.mx.api.v1+json' \
    -u 'client_id:api_key'
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "account": {
    "account_number": "****0001",
    "apr": null,
    "apy": null,
    "available_balance": 500000,
    "available_credit": null,
    "balance": 500000,
    "cash_balance": null,
    "cash_surrender_value": null,
    "created_at": "2020-09-21T19:43:44Z",
    "credit_limit": null,
    "currency_code": null,
    "day_payment_is_due": 12,
    "death_benefit": null,
    "guid": "ACT-82a93692-f756-534f-9b2e-ad10a0f38462",
    "holdings_value": null,
    "id": "act-23445745",
    "imported_at": "2023-02-24T09:01:25Z",
    "institution_code": "mxbank",
    "insured_name": null,
    "interest_rate": null,
    "is_closed": false,
    "is_hidden": false,
    "last_payment": null,
    "last_payment_at": null,
    "loan_amount": null,
    "matures_on": null,
    "member_guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa",
    "member_id": null,
    "member_is_managed_by_user": true,
    "metadata": null,
    "minimum_balance": null,
    "minimum_payment": null,
    "name": "Checking",
    "nickname": null,
    "original_balance": null,
    "pay_out_amount": null,
    "payment_due_at": "2021-05-12T16:01:00Z",
    "payoff_balance": null,
    "premium_amount": null,
    "routing_number": "005026788",
    "started_on": null,
    "subtype": null,
    "total_account_value": null,
    "type": "CHECKING",
    "updated_at": "2023-02-24T09:01:25Z",
    "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c",
    "user_id": "partner-2345"
    }
    }
    ```
  </Tab>
</Tabs>

<Info>
  **INFO**

  We suggest you add a Balance Webhook in the Client Dashboard. We provide webhooks that send HTTPS POST callback requests to the URL of your choice. This webhook notifies you when new balance data is successfully returned. Note this webhook does not trigger member-based actions. See [Webhooks](/resources/webhooks) for more information.
</Info>
