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

# Atrium

# Introduction to Atrium

The MX Atrium API supports over 48,000 data connections to thousands of financial institutions. It provides secure access to your users' accounts and transactions with industry-leading cleansing, categorization, and classification.

Atrium is designed according to resource-oriented REST architecture and responds with JSON bodies and HTTP response codes.

Use Atrium's development environment, vestibule.mx.com, to quickly get up and running. The development environment limits are 100 users and access to the top 15 institutions.

## Getting Started

To get started right away with some of the most common tasks and frequently used features of Atrium, you can check out our [detailed developer guide](/other/atrium/).

Our developer guide also explains our [test endpoints](/other/atrium/testing-your-setup#test-endpoints) and [test credentials](/other/atrium/testing-your-setup#test-endpoints) to  help you get off the ground as soon as possible.

We've also provided wrapper libraries in several languages. Visit the appropriate GitHub page below.

[C#](https://github.com/mxenabled/atrium-csharp)

[Go](https://github.com/mxenabled/atrium-go)

[Java](https://github.com/mxenabled/atrium-java)

[Node](https://github.com/mxenabled/mx-atrium-node)

[PHP](https://github.com/mxenabled/atrium-php)

[Python](https://github.com/mxenabled/atrium-python)

[Ruby](https://github.com/mxenabled/atrium-ruby)

## Aggregation and Data Availability

Aggregation is how Atrium is able to gather financial data from multiple sources and then deliver it to you. It is the core feature of the Atrium API.

MX automatically aggregates certain members in the background every 24 hours. Specifically, we aggregate all members whose [`connection_status`](/api-reference/atrium/reference/members/connection-status) is either `CONNECTED`, `CREATED`, or `UPDATED` — unless the `member` has been disabled.

You may aggregate a `member` via the [aggregate member](/api-reference/atrium/reference/members/aggregate-member) endpoint to get the most up-to-date information on accounts and transactions. When you aggregate a `member` with this endpoint, MX will not initiate a background aggregation within the next 20-hour period.

### Aggregation Limits

The default minimum time between aggregation events is 10,800 seconds (3 hours), though this limit can vary by institution. Aggregating within this limit will not return an error, however; the response will simply contain the current state of the `member`, including the latest `connection_status`. Certain codepaths may also bypass this limit — for instance, [updating a member's credentials](/api-reference/atrium/reference/members/update-member).

The [MX Bank test institution](/api-reference/atrium/#testing) has no aggregation limits.

### Data Availability

Be aware that aggregation is not guaranteed to return all relevant information or even every data point on a given resource. For instance, aggregation may return the `balance` of an account, but return a `null` value for the `apr` and `day_payment_is_due` fields. This is to be expected in all resources and all aggregations.

## API Architecture and Resource Structure

Atrium is designed around the REST architecture and uses predictable, resource-oriented URLs. Requests are made with HTTP methods and HTTP response codes indicate the success or failure of those requests.

Atrium has five broad groups of resources, each with their own attributes and endpoints:

| Resource      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user`        | A `user` represents a person using Atrium via your application, be it a mobile app, web app, desktop app, etc.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `institution` | An `institution` represents a financial institution like Chase or Wells Fargo. It's important to point out that many real-world financial institutions 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.                                                                                                                                      |
| `member`      | A `member` represents the relationship between a `user` and an `institution`, and creating one is how you connect a `user` to 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`     | An `account` represents a financial account held by a financial institution, e.g., a user's checking or savings account. Because a user's relationship with an institution may involve more than one account, a `member` may have more than one `account` associated with it. For instance, a user may have both a checking and savings account with Chase. In that case,  the `user` would have a `member` that represents their connection with the Chase `institution`. That `member` would have two accounts, a checking `account` and a savings `account`. |
| `transaction` | A `transaction` represents any instance in which money moves into or out of an `account`. This could be 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`.                                                                                                                                                                                                                                                                                          |

## Authentication and Security

Atrium API requests must be HTTPS with encryption TLSv1.2 or higher or else they will fail.

All requests are authenticated with tokens in request headers: `MX-API-Key` and `MX-Client-ID`. The production and development environments require separate tokens. Development tokens are granted automatically during the signup process; These can be found on your [profile page](https://dashboard.mx.com/security).

Because these tokens grant access to all of your data, you must **keep them secret and keep them safe. Do not share them in public areas, use them in client-side code, or otherwise use them in a way that may compromise their security.** In some instances, requests that require authentication will return `404 Not Found`, instead of `401 Unauthorized`. This is to prevent leaking private information.

## Base URL

**Production Environment**

```
https://atrium.mx.com/
```

**Development Environment**

```
https://vestibule.mx.com/
```

## Caching

Certain Atrium resources are subject to change at any time; for instance, institutions and institution credentials. For this reason, MX discourages partners from caching lists of resources. If caching is necessary, MX recommends refreshing a cached list at least daily.

## Character Encoding

Requests to Atrium must use characters encoded with the UTF-8 standard.

## Data Encoding

MX Technologies is committed to providing high-quality data to accommodate a wide range of scenarios. Due to the
financial nature of our data, sometimes special characters such as `'`, `<`, `>`, `"`, and `=` will be found in string
fields. For example, an account might be identified as `Mortgage Loan <= 15 Years`.  We strongly recommend that clients
sanitize and/or encode the output of our API, such as HTML encoding prior to rendering in a web view.

## Data Format

JSON structured data is returned in all responses, including some errors.

## Dates and Times

Dates and times are always given in ISO 8601 format.

Fields which end in `_on` are given without a timestamp: `2018-07-18`

Fields which end in `_at` are given with a timestamp: `2015-04-13T12:01:23-06:00`.

## Errors

Atrium uses conventional HTTP response codes to indicate the success or failure of a request, with supplementary error messaging as needed within response bodies.

```json Example theme={null}
{
  "error": {
    "message": "Unrecognized institution.",
  }
}
```

| Status Code                              | Explanation                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **2xx Success**                          |                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `200 OK`                                 | Everything worked as expected with content returned.                                                                                                                                                                                                                                                                                                                                                                                 |
| `202 Accepted`                           | <ol><li>Everything worked and MX's system is processing the request.</li><li>When attempting a job on a `member`, a job of the *same type* is already running; e.g., calling *aggregate member* while a standard agg is still running, or calling *verify member* while a previous verification is still running.</li><li>A standard aggregation has been attempted within the default minimum time between standard aggs.</li></ol> |
| `204 No Content`                         | Everything worked as expected without content returned.                                                                                                                                                                                                                                                                                                                                                                              |
| **4xx Requester error**                  |                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `400 Bad Request`                        | <ol><li>A required parameter was missing.</li><li>A premium aggregation-type job was requested, but the `institution` associated with the `member` does not support it.</li></ol>                                                                                                                                                                                                                                                    |
| `401 Unauthorized`                       | Invalid `MX-API-Key` or `MX-Client-ID` provided.                                                                                                                                                                                                                                                                                                                                                                                     |
| `403 Forbidden`                          | The request was made from a non-whitelisted address or the feature is not available to the client.                                                                                                                                                                                                                                                                                                                                   |
| `404 Not Found`                          | Invalid item/id/URL requested.                                                                                                                                                                                                                                                                                                                                                                                                       |
| `405 Method Not Allowed`                 | A constraint on the requested endpoint wasn't met.                                                                                                                                                                                                                                                                                                                                                                                   |
| `406 Not Acceptable`                     | The request didn't specify a valid API version.                                                                                                                                                                                                                                                                                                                                                                                      |
| `409 Conflict`                           | 1. An object with the given attributes already exists.<br /><br />2. When attempting an aggregation on a `member`, the `member` already has an an aggregation of a different type running; e.g., calling the *verify* endpoint while a standard aggregation is already running, or calling *fetch statements* while an *identification* aggregation is already running.                                                              |
| `422 Unprocessable Entity`               | The data provided cannot be processed.                                                                                                                                                                                                                                                                                                                                                                                               |
| **5xx Responder error — which are rare** |                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `500, 502, 504 Server errors`            | Something went wrong with MX's servers.                                                                                                                                                                                                                                                                                                                                                                                              |
| `503 Service Unavailable`                | The MX Platform is being updated.                                                                                                                                                                                                                                                                                                                                                                                                    |

## Identifiers and Metadata

Atrium gives you two special — but optional — fields which you can define for any [resource](/other/atrium/getting-started) created with the API: `identifier` and `metadata`. These fields make it easier to customize and integrate Atrium with your systems.

For instance, you may need to make certain that some resources are created only once. In these situations, you can give an unique `identifier` to resources created with Atrium. Atrium will return a `409 Conflict` error if a resource is created with an `identifier` that already exists.

You might also use the `metadata` field to store custom data about a resource. For example, you could store a user's username for your system, their sign-up date, the date and time of their last logon in your system, or all of these.

| Field        | Description                                                                                                                                                                                                                                                                                                                                |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `identifier` | A unique, enforced identifier for a `user` or `member`, defined by you. An `identifier` may contain letters, numbers, dashes, and underscores — but they should not be longer than 200 characters. MX recommends using GUIDs. Atrium will return a `409 Conflict` error if a resource is created with an `identifier` that already exists. |
| `metadata`   | This field that can be used to store additional information about a particular `user` or `member`. Any UTF-8 string can be stored, but MX recommends using structured key-value data such as JSON.                                                                                                                                         |

**Example `metadata` Request**

```shell 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": {
          "metadata": "{\"username\":\"steven\"}"
        }
      }'
```

**Example `identifier` Request**

```shell theme={null}
$ curl -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": "5935d8ef-20c0-4bc1-997c-b2cccf4d601d"
        }
      }'
```

**Example of an `identifier` Conflict Response**

```
Status: 409 Conflict
```

```json theme={null}
{
  "error": {
    "message": "A user already exists with identifier: '5935d8ef-20c0-4bc1-997c-b2cccf4d601d'."
  }
}
```

## IP Address Whitelisting

All IP addresses which will make calls to Atrium's production environment must be whitelisted first. A `403 Forbidden` error will be returned for non-whitelisted addresses. The vestibule environment does not require any whitelisting.

You can whitelist IP addresses on your [account profile](https://dashboard.mx.com/security).

## Limits

### User and member limits

The development environment limits developers to 100 [users](/api-reference/atrium/reference/members) and access to the top 15 [institutions](/api-reference/atrium/reference/institutions).

No `user` may have more than 25 members in either the development or production environments.

### Aggregation throttling

Standard aggregation jobs are throttled, and a new standard agg can only be started after the throttle period has elapsed. The default throttle period is three hours (10,800 seconds), though this limit can vary from one institution to another.

However, premium agg-type jobs won't start the throttle period (extended history, identification, verification, statements, balance check). In other words, running a standard agg will always start the throttle period and prevent a new standard agg. Running any other type of job will not start the throttle period.

Premium aggregation-type jobs are never throttled. That is, you can run an account verification right after a standard agg (or balance request, or verification etc.). However, because standard aggs *are* throttled, you should generally use the `include_transactions` parameter on premium jobs if standard data is also required; this will prevent delays.

Throttled jobs will not return an error; the response will return with `202 Accepted` and will contain the current state of the `member`, including the latest [`connection_status`](/api-reference/atrium/reference/members/connection-status).

Jobs for members that have experienced credential-related errors won't be throttled (`connection_status`: `REJECTED`, `PREVENTED`, `UPDATED`).

Balance jobs are limited to 5 requests every 2 hours.

There is no throttling of any kind when using the [MX Bank test institution](/api-reference/atrium/#testing).

## Numbers and Number Formats

Number limits are described by their precision and scale. Precision refers to the total number of digits. Scale refers to the number of digits to the right of the decimal. For example, 538.46's precision,scale is 5,2.

Percentages are in decimal format without the percentage sign. For example, 2.99% is written `2.99`.

## Pagination

All endpoints which return lists are paginated. These endpoints also support two query parameters which specify the number of records per page and the page to be returned.

Each response will include a `pagination` object specifying information on the total number of entries and the current page.

**Example Pagination object**

```json theme={null}
"pagination": {
  "current_page": 1,
  "per_page": 25,
  "total_entries": 2,
  "total_pages": 1
}
```

### Query parameters

| Parameter          | Definition                                                                                                                 |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------- |
| `page`             | This specifies the page to be returned. Defaults to `1`.                                                                   |
| `records_per_page` | This specifies the number of records to be returned on each page. Defaults to `25`. The valid range is from `10` to `100`. |

### Pagination fields

| Field           | Definition                                      |
| :-------------- | :---------------------------------------------- |
| `current_page`  | The page delivered by the current response.     |
| `per_page`      | The number of records delivered with each page. |
| `total_entries` | The total number of records available.          |
| `total_pages`   | The total number of pages available.            |

## Testing

The [developer guide](/other/atrium) explains how to test your setup using our [test endpoints](/other/atrium/testing-your-setup#test-endpoints) and [test credentials](/other/atrium/testing-your-setup#test-credentials-for-mx-bank).

## Versioning

We always try to make API changes backwards-compatible. However, when we make breaking changes to Atrium, we'll increment the version number. The current version is v1. Versions are specified in a request's `Accept` header. All requests will access the current version unless a different version is specified with the request, so it's best to always specify the API version. The current Accept header is `application/vnd.mx.atrium.v1+json`.

## Deleting Objects

When you delete an object on MX, associated child objects are also removed automatically:

* Deleting a **member** removes all linked accounts, transactions, and holdings.
* Deleting a **user** removes all connected members (and their accounts, transactions, and holdings).

<Warning>
  Deleting a user is permanent. Deleted users can never be restored.
</Warning>

MX uses a two-phase deletion process. Deleted objects first enter a **soft-deleted** state, then are permanently purged approximately two weeks later. Soft-deleted items cannot be restored through the API, though MX may manually restore soft-deleted members in limited circumstances before permanent purging occurs.

If a new member is created for the same user and institution with identical credentials, any soft-deleted member will be immediately purged and a fresh record created.

For OAuth members specifically:

* Members in a `PENDING` state are **immediately purged** upon deletion by MX and cannot be recovered.
* Members in other states are soft-deleted and potentially recoverable through MX support before permanent purging.

Once fully purged, all data is permanently lost and cannot be retrieved.
