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

# Getting Started With Atrium

In this guide, you'll find lots of information to help you get up and running with Atrium. It includes material on about how the API works, common terminology, common problem scenarios, a Postman collection and downloadable examples in multiple languages, steps on how to test certain Atrium features, broad workflows for common tasks, and more.

This is not designed to be comprehensive but to provide a broad overview of common tasks and issues. Refer to our [detailed API reference](/api-reference/atrium) for more specific information about Atrium resources, endpoints, and configuration options.

## Whitelisting

Before you can work within Atrium's production environment, your IP addresses must be whitelisted. If you haven't been whitelisted, you'll see `403 Forbidden` errors. You can whitelist IP addresses on your [account profile](https://dashboard.mx.com/api_keys).

Atrium's vestibule environment does not require any whitelisting.

## Resource Structure

Atrium is structured around five major resources, each with its own attributes and endpoints:

| Resource                                                               | Description                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`institution`](/api-reference/atrium/reference/institutions/overview) | An `institution` represents a financial institution (FI) like Chase or Wells Fargo. It's important to point out that many real-world FI will actually have several different `institution` objects within Atrium. This is because, for example, the mortgage division of Wells Fargo might use a separate system than its everyday banking division, which is different from its credit card division, etc. |
| [`user`](/api-reference/atrium/reference/members/overview)             | A `user` represents a person using Atrium via your application, be it a mobile app, web app, desktop app, etc.                                                                                                                                                                                                                                                                                              |
| [`member`](/api-reference/atrium/reference/members/overview)           | A `member` represents the relationship between a `user` and an `institution`. A `user` may have one `member` each for their bank, their mortgage broker, their credit card provider, etc. Aggregation takes place via members.                                                                                                                                                                              |
| [`account`](/api-reference/atrium/reference/accounts/overview)         | An `account` represents a financial account held by an FI, e.g., a user's checking or savings account. A member may have more than one account associated with it. For instance, a user may have both a checking and savings account associated with one Chase login and therefore would have two accounts associated with one `member`.                                                                    |
| [`transaction`](/api-reference/atrium/reference/transactions/overview) | A `transaction` represents any instance in which money moves into or out of an `account`, such as a purchase at a business, a payroll deposit, a transfer from one account to another, an ATM withdrawal, etc. Each `transaction` belongs to only one `account`.                                                                                                                                            |

## Creating Users

To create a new `user`, call the [*create user*](/api-reference/atrium/reference/users/create-user) endpoint. It's a good idea to send along a unique [`identifier`](/api-reference/atrium/#identifiers-and-metadata) with your request to create a new user. Atrium will also give each new `user` a unique GUID in the `guid` field within the `user` object. The Atrium user GUID also appears in the `user_guid` field when not inside the `user` object. The `identifier` and `guid` allow you to easily map between your system and Atrium.

You may also include `metadata`, such as the date the `user` was created, if desired. You can [read more on identifiers and metadata](/api-reference/atrium/#identifiers-and-metadata) on our API reference page.

An example request for creating a `user` is shown below.

**Endpoint**: `POST /users`

<CodeGroup>
  ```shell Request theme={null}
  curl -i -X POST 'https://vestibule.mx.com/users' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'Content-Type: application/json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}' \
    -d '{
          "user": {
            "identifier": "unique_id",
            "metadata": "{\"first_name\": \"Steven\"}"
          }
        }'
  ```

  ```json Response theme={null}
  {
    "user": {
      "guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54",
      "identifier": "unique_id",
      "is_disabled": false,
      "metadata": "{\"first_name\": \"Steven\"}"
    }
  }
  ```
</CodeGroup>

## Creating Members

Once a `user` is created, we recommend creating a `member` with our [MX Connect widget](/other/atrium/connect). MX Connect allows end users to easily choose an institution to connect to, enter credentials, update credentials, and answer multi-factor authentication.

If your system or application is unable to support MX Connect, you can always call the endpoint directly in your code. To create a `member` via endpoints, you'll follow the workflow below:

<img src="https://mintcdn.com/mx-7a01b258/OOfo2VTBgMqAqqgz/images/atrium/atrium-create-workflow.png?fit=max&auto=format&n=OOfo2VTBgMqAqqgz&q=85&s=7766512317967f83a61fc490ea46ab85" alt="Atrium create workflow" width="1080" height="360" data-path="images/atrium/atrium-create-workflow.png" />

Once your `member` has been created, you'll want to call the [*read member status*](/api-reference/atrium/reference/members/read-member-connection-status) endpoint to determine whether answering MFA is required or to update credentials as needed.

The steps outlined below assume you're creating a new `member` on an existing `user`.

### 1. Search for an institution

**Endpoint**: `GET /institutions`

<CodeGroup>
  ```shell Request theme={null}
  curl -i 'https://vestibule.mx.com/institutions?name=mx' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}'
  ```

  ```json Response theme={null}
  {
    "institutions": [
      {
        "code": "mxbank",
        "medium_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/INS-1572a04c-912b-59bf-5841-332c7dfafaef_100x100.png",
        "name": "MX Bank",
        "small_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/INS-1572a04c-912b-59bf-5841-332c7dfafaef_50x50.png",
        "supports_account_identification": true,
        "supports_account_statement": false,
        "supports_account_verification": true,
        "supports_oauth": false,
        "supports_transaction_history": true,
        "url": "https://www.mx.com"
      }
    ],
    "pagination": {
      "current_page": 1,
      "per_page": 25,
      "total_entries": 1,
      "total_pages": 1
    }
  }
  ```
</CodeGroup>

### 2. Get institution required credentials

**Endpoint** `GET /institutions/{institution_code}`

<CodeGroup>
  ```shell Request theme={null}
  curl -i 'https://vestibule.mx.com/institutions/mxbank' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}'
  ```

  ```json Response theme={null}
  {
    "institution": {
      "code": "mxbank",
      "medium_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/INS-1572a04c-912b-59bf-5841-332c7dfafaef_100x100.png",
      "name": "MX Bank",
      "small_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/INS-1572a04c-912b-59bf-5841-332c7dfafaef_50x50.png",
      "supports_account_identification": true,
      "supports_account_statement": false,
      "supports_account_verification": true,
      "supports_oauth": false,
      "supports_transaction_history": true,
      "url": "https://www.mx.com"
    }
  }
  ```
</CodeGroup>

### 3. Create a member

**Endpoint**: `POST /users/{user_guid}/members`

<CodeGroup>
  ```shell Request theme={null}
  curl -i -X POST 'https://vestibule.mx.com/users/{user_guid}/members' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'Content-Type: application/json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}' \
    -d '{
          "member": {
            "institution_code": "mxbank",
            "credentials": [
              {
                "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
                "value": "ExampleUsername"
              },
              {
                "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
                "value": "Pa$$vv@Rd"
              }
            ],
            "skip_aggregation": true
          }
        }'
  ```

  ```json Response theme={null}
  {
    "member": {
      "aggregated_at": "2016-10-13T17:57:36+00:00",
      "connection_status": "CONNECTED",
      "guid": "MBR-7c6f361b-e582-15b6-60c0-358f12466b4b",
      "identifier": "unique_id",
      "institution_code": "mxbank",
      "is_being_aggregated": true,
      "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
      "name": "MX Bank",
      "status": "INITIATED",
      "successfully_aggregated_at": null,
      "user_guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54"
    }
  }
  ```
</CodeGroup>

### 4. Poll the member status

**Endpoint**: `GET /users/{user_guid}/members/{member_guid}/status`

<CodeGroup>
  ```shell Request theme={null}
  curl -i 'https://vestibule.mx.com/users/{user_guid}/members/{member_guid}/status' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}'
  ```

  ```json Response theme={null}
  {
    "member": {
      "aggregated_at": "2019-06-08T17:21:05Z",
      "connection_status": "CONNECTED",
      "guid": "MBR-a4652b66-3ee5-cb9f-295a-72eddef61db5",
      "has_processed_accounts": true,
      "has_processed_transactions": true,
      "is_authenticated": true,
      "is_being_aggregated": false,
      "status": "COMPLETED",
      "successfully_aggregated_at": "2019-06-07T21:16:03Z"
    }
  }
  ```
</CodeGroup>

## Aggregating Data and Dealing with MFA

Aggregating data about accounts and transactions belonging to a `member` is a multi-step process. This same general outline applies to all aggregation-type features, with the necessary endpoint substitutions, of course: account verification, identity verification, extended transaction histories, fetching statements, account balance aggregation, and standard aggregation.

In general, it involves:

1. Making a request to the aggregate member endpoint (or an analogous endpoint);
2. Polling 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;
3. If necessary, answering MFA challenges using the resume aggregation endpoint.
4. Reading aggregated data using the list accounts and \_list transactions endpoints (or analogous endpoints).

<img src="https://mintcdn.com/mx-7a01b258/OOfo2VTBgMqAqqgz/images/atrium/atrium_mfa_flow.png?fit=max&auto=format&n=OOfo2VTBgMqAqqgz&q=85&s=05c2a8932ca2dfa38515ca80a7464d86" alt="Flow for Multi-Factor Authentication" width="1800" height="460" data-path="images/atrium/atrium_mfa_flow.png" />

Atrium automatically aggregates each `member` every 24 hours. This process is called background aggregation. It ensures that end users' data will always be up to date. If an end user is present, you may also manually run a **foreground aggregation** using the general steps specified above. End users must be present during foreground aggregations because they may run into MFA, credential update requests, terms and conditions agreements, or any number of other situations requiring end-user input.

Both foreground and background aggregation may be manually prevented by [disabling a `user`](/api-reference/atrium/reference/users/create-user). A `user` must be re-enabled before any aggregation can be attempted.

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

### Running Multiple Aggregation-Type Events on a Member

Your particular application may use several of Atrium's aggregation-type processes, including standard aggregation and premium features like fetching statements, verifying identity, etc. All of these processes are run on a specific `member`, but they cannot be run simultaneously — each process must reach an end state before a new process can be started.

Furthermore, when running multiple processes in succession, standard aggregation should **always be performed first** in the series. This is because any aggregation-type process will prevent a new standard aggregation for the next three hours; however, running a standard aggregation has no effect on the timing of premium features.

If a `member` already has a process running and you attempt to run an aggregation-type process on it, you may get one of two status codes:

1. If an event of the same type is already running, you'll get a `202 Accepted` status;

* For example, you called verify member when a verification is already running;
* You can tell that a process is already running because the `is_being_aggregated` field will be `true`.

2. If an event of a **different** type is running, you'll get a `409 Conflict` status;

* For example, you called identify member when a standard aggregation is already running.

### MFA And Connection Statuses

Some institutions require multiple steps for authentication; this process is called multi-factor authentication (MFA). Basically, it is a back and forth dialogue between the end user, the partner's application, and the `institution`. After the initial credentials are provided, the `institution` can either grant access or present an MFA challenge.

<Info>
  **INFO**

  MFA is controlled by the institution's security settings and not by MX. MFA can be encountered at each step in the aggregation process.
</Info>

When an MFA challenge is presented, the member's `connection_status` will be `CHALLENGED`. You must get the correct answer to the challenge from the end user and send it to MX so aggregation can continue. More than one MFA cycle may occur. Financial institutions will typically have multiple MFA questions and may ask a new question in future aggregations. Partners must continue to answer the institution's challenges until the `institution` grants access to the end user's account.

A single aggregation may also enter multiple `CHALLENGED` states. A typical scenario for this is when a list of options is presented along with a question such as, "Where should we send an authentication token?"

MFA can occur at any time on any aggregation, so even if authentication has been successful in the past, the institution may require an end user to authenticate again. Furthermore, aggregation may trigger MFA even if end users can successfully log into their online banking portal without MFA using the same credentials.

### Member Connection Statuses

The `connection_status` field appears on all `member` resources and [indicates the current state of aggregation](/api-reference/atrium/reference/members/read-member-connection-status) for that particular `member`. Partners can poll a particular `member` using the [read member connection status](/api-reference/atrium/reference/members/read-member-connection-status) endpoint to follow changes in the `connection_status` throughout an aggregation.

The `connection_status` should be used in conjunction with several other `member` fields to determine future actions, including `aggregated_at`, `is_being_aggregated`, and `successfully_aggregated_at`, `has_processed_accounts` and `has_processed_transactions`. Definitions for these fields appear at the end of this section. Definitions for all `member` fields are available [here](/api-reference/atrium/reference/members/overview).

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 should be pulled. Partners can use the field `successfully_aggregated_at` to determine when the last successful aggregation occurred.

When the status is `CHALLENGED`, an MFA challenge has been issued, requiring a [separate workflow](/other/atrium/getting-started#dealing-with-a-challenged-status) and user input.

The 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 continued polling until an end state is reached.

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

**Member fields to poll during aggregation**

| Field Name                   | Data Type | Description                                                                                                                                                                                                          |
| ---------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `aggregated_at`              | String    | The date and time the `member` the last aggregation was initiated.                                                                                                                                                   |
| `connection_status`          | String    | This field indicates the state of a member's aggregation, provided as a string. See [member connection statuses](/api-reference/atrium/reference/members/connection-status) 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.                                                                                                                                                      |

### Dealing with a `CHALLENGED` Status

When a `member` comes back with a status of `CHALLENGED`, the aggregation will require answers to MFA from the end user. The challenges that must be answered are returned in the [read member connection status](/api-reference/atrium/reference/members/connection-status) response, nested inside the `challenges` array, as shown to the right. Simply polling this endpoint for changes in the `connection_status` should return challenges as quickly as possible.

Once MFA answers have been gathered for the challenged `member`, a request to the [resume aggregation](/api-reference/atrium/reference/members/resume-aggregation-mfa) endpoint will send these answers and automatically resume the aggregation process. Aggregation will run until it either completes in an end state or enters into a state that requires action.

It is not uncommon for an aggregation to be `CHALLENGED` more than once.

**Example response for read member connection status when the `connection_status` is `CHALLENGED`**

```json JSON theme={null}
{
  "member": {
    "aggregated_at":"2016-10-13T18:24:37+00:00",
    "challenges": [
      {
        "field_name": null,
        "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
        "label": "What city were you born in?",
        "type": "TEXT"
      }
    ],
    "connection_status": "CHALLENGED",
    "guid": "MBR-7c6f361b-e582-15b6-60c0-358f12466b4b",
    "has_processed_accounts": false,
    "has_processed_transactions": false,
    "is_being_aggregated": true,
    "status": "CHALLENGED",
    "successfully_aggregated_at": "2016-10-13T18:08:04+00:00"
  }
}
```

### Dealing with Multiple `CHALLENGED` States in One Aggregation

A single aggregation may enter multiple `CHALLENGED` states. A typical scenario for this is when a list of options is presented along with a question such as, "Where should we send an authentication token?" As above, polling the read member connection status endpoint after resuming an aggregation should return these further challenges.

Here is a typical example: MFA is triggered and asks where to send an access token. The end user should be prompted for the answer and that answer provided to MX through the resume aggregation endpoint. The `connection_status` will move to a `RESUMED` state, but then will go back into a `CHALLENGED` state. This time, the end user should be prompted to enter the access token. If the second MFA challenge is answered successfully, the aggregation will typically proceed to an end state such as `CONNECTED`.

### Dealing with a `DENIED` or `PREVENTED` Status

If a `member` has a `PREVENTED` or a `DENIED` status, it means the authentication credentials are invalid; the end user must provide new credentials, and the `member` must be updated. A request to the [list member credentials](/api-reference/atrium/reference/members/list-member-credentials) endpoint (as distinct from the separate *list institution credentials* endpoint) will return a list of the authentication credentials required for that `member`; corresponding input should be gathered from the end user, and that input should be passed to the [update member](/api-reference/atrium/reference/members/update-member) endpoint.

<img src="https://mintcdn.com/mx-7a01b258/OOfo2VTBgMqAqqgz/images/atrium/agg_flow_prevented.png?fit=max&auto=format&n=OOfo2VTBgMqAqqgz&q=85&s=4f09cb6c91ed85002a4db2b3ae43f170" alt="Flow for preventing aggregation" width="1800" height="667" data-path="images/atrium/agg_flow_prevented.png" />

### Step-by-Step Guide for Standard Aggregation with MFA

The steps below show the ideal path for a standard aggregation on an existing member, including MFA. It's the happy path, so to speak. There are other flows and situations, to be sure, but this gives you the basic outline of a common situation that requires resolution.

#### 1. Check the member's connection status

The first step is to check the member's `connection_status` to determine whether aggregation is either necessary or 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. [See the sections above](/other/atrium/getting-started#aggregating-data-and-dealing-with-mfa) for more information, or consult the documentation on [connection statuses](/api-reference/atrium/reference/members/connection-status) for full details on exactly what each status means.

The following lists represent general guidelines.

<Info>
  **INFO**

  The `connection_status` field is not the same as `status`. The `status` field should no longer be relied on for aggregation purposes.
</Info>

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](/api-reference/atrium/reference/members/update-member) 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`

<CodeGroup>
  ```shell Request theme={null}
  curl -i 'https://vestibule.mx.com/users/{user_guid}/members/{member_guid}/status' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}'
  ```

  ```json Response theme={null}
  {
    "member": {
      "aggregated_at": "2019-06-08T17:21:05Z",
      "connection_status": "CONNECTED",
      "guid": "MBR-a4652b66-3ee5-cb9f-295a-72eddef61db5",
      "has_processed_accounts": true,
      "has_processed_transactions": true,
      "is_authenticated": true,
      "is_being_aggregated": false,
      "status": "COMPLETED",
      "successfully_aggregated_at": "2019-06-07T21:16:03Z"
    }
  }
  ```
</CodeGroup>

#### 2. Aggregate the member

Making a POST request to the aggregate member endpoint initiates an aggregation.

**Endpoint**: `POST /users/{user_guid}/members/{member_guid}/aggregate`

<CodeGroup>
  ```shell Request theme={null}
  curl -i -X POST 'https://vestibule.mx.com/users/{user_guid}/members/{member_guid}/aggregate' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'Content-Type: application/json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}'
  ```

  ```json Response theme={null}
  {
    "member": {
      "aggregated_at": "2016-10-13T18:07:57+00:00",
      "connection_status": "CONNECTED",
      "guid": "MBR-7c6f361b-e582-15b6-60c0-358f12466b4b",
      "identifier": "unique_id",
      "institution_code": "mxbank",
      "is_being_aggregated": true,
      "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
      "name": "MX Bank",
      "status": "INITIATED",
      "successfully_aggregated_at": "2016-10-13T17:57:38+00:00",
      "user_guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54"
    }
  }
  ```
</CodeGroup>

#### 3. Check the connection status again

In this example, we see that the status has returned as `CHALLENGED`, meaning the aggregation has run into MFA. When `CHALLENGED`, the response to your status request will include a `challenges` object containing the MFA that the end user must answer.

**Endpoint**: `GET /users/{user_guid}/members/{member_guid}/status`

<CodeGroup>
  ```shell Request theme={null}
  curl -i 'https://vestibule.mx.com/users/{user_guid}/members/{member_guid}/status' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}'
  ```

  ```json Response theme={null}
  {
    "member": {
      "aggregated_at": "2019-06-08T17:21:05Z",
      "connection_status": "CONNECTED",
      "guid": "MBR-a4652b66-3ee5-cb9f-295a-72eddef61db5",
      "has_processed_accounts": true,
      "has_processed_transactions": true,
      "is_authenticated": true,
      "is_being_aggregated": false,
      "status": "COMPLETED",
      "successfully_aggregated_at": "2019-06-07T21:16:03Z"
    }
  }
  ```
</CodeGroup>

#### 4. Answer MFA with the resume aggregation endpoint

**Endpoint**: `PUT /users/{user_guid}/members/{member_guid}/resume`

<CodeGroup>
  ```shell Request theme={null}
  curl -i -X PUT 'https://vestibule.mx.com/users/{user_guid}/members/{member_guid}/resume' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'Content-Type: application/json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}' \
    -d '{
          "member":{
            "challenges":[
              {
                 "guid": "institution-credential-guid",
                 "value": "user-entered-value"
              },
              {
                "guid": "institution-credential-guid",
                 "value": "user-entered-value"
              }
            ]
          }
        }'
  ```

  ```json Response theme={null}
  {
    "member": {
      "aggregated_at": "2016-09-30T14:31:45-06:00",
      "connection_status": "RESUMED",
      "guid": "MBR-7c6f361b-e582-15b6-60c0-358f12466b4b",
      "identifier":"unique_id",
      "institution_code": "mxbank",
      "is_being_aggregated": true,
      "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
      "name": "MX Bank",
      "status": "RECEIVED",
      "successfully_aggregated_at": null,
      "user_guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54"
    }
  }
  ```
</CodeGroup>

#### 5. Check the connection status again

Check the `connection_status` again, and keep checking until the aggregation reaches an end state, e.g., the `is_being_aggregated` field is `false`.

**Endpoint**: `GET /users/{user_guid}/members/{member_guid}/status`

<CodeGroup>
  ```shell Request theme={null}
  curl -i 'https://vestibule.mx.com/users/{user_guid}/members/{member_guid}/status' \
    -H 'Accept: application/vnd.mx.atrium.v1+json' \
    -H 'MX-API-Key: {mx_api_key}' \
    -H 'MX-Client-ID: {mx_client_id}'
  ```

  ```json Response theme={null}
  {
    "member": {
      "aggregated_at": "2019-06-08T17:21:05Z",
      "connection_status": "CONNECTED",
      "guid": "MBR-a4652b66-3ee5-cb9f-295a-72eddef61db5",
      "has_processed_accounts": true,
      "has_processed_transactions": true,
      "is_authenticated": true,
      "is_being_aggregated": false,
      "status": "COMPLETED",
      "successfully_aggregated_at": "2019-06-07T21:16:03Z"
    }
  }
  ```
</CodeGroup>

### Steps for Multiple-Question MFA

Multiple-question MFA is very similar to single-question MFA explained above.

1. Aggregate the member (or create a new `member`)
2. Check the member connection status.
3. Answer the `challenge` using the resume aggregation endpoint
4. Check the connection status again.
5. Answer the next `challenge`.
6. Keep checking the connection status and answering challenges until an end state is reached.

## Pulling Data

When an aggregation is initiated, the `member` field `aggregated_at` will update. If it completes successfully, the `successfully_aggregated_at` field will be updated. These will help you determine when to pull the latest data after a foreground aggregation.

Transaction data can be accessed though three different endpoints: `/users/{user_guid}/transactions`, `/users/{user_guid}/members/{member_guid}/transactions`, and `/users/{user_guid}/accounts/{account_guid}/transactions`. The first will list all the transactions that belong to the `user` object. The second will return all transactions that belong to a `member` object. The third will return all transactions that belong to an 'account' object.

We recommend first [listing available accounts](/api-reference/atrium/reference/accounts/list-accounts), then [listing transactions for a specific account](/api-reference/atrium/reference/accounts/list-account-transactions).

## Wrapper Libraries

To see example workflows, please download one of our Atrium wrapper libraries in the language of your choice.

* [Elixir](https://github.com/mxenabled/atrium-elixir)
* [Go](https://github.com/mxenabled/atrium-go)
* [Java](https://github.com/mxenabled/atrium-java)
* [Node](https://github.com/mxenabled/mx-atrium-node)
* [Python](https://github.com/mxenabled/atrium-python)
* [Ruby](https://github.com/mxenabled/atrium-ruby)
