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

# Architecture & Security

> The MX Platform API is a powerful, fully-featured API designed to make aggregating and enhancing financial data easy and reliable.

It can seamlessly connect your app or website to tens of thousands of financial institutions.

The MX API is built around a standard REST architecture, uses predictable, resource-oriented URLs, and returns all data in JSON format. Requests are made with HTTP methods and HTTP response codes indicate the success or failure of those requests.

## API Architecture and Resource Structure

The MX Platform API has many different resources and features, but once you break it down, it is centered around five major resource types. Virtually all the others are connected in one way or another with the resources described here.

| Resource      | Description                                                                                                                                                                                                                                                                                                                                                                                                              |
| :------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `institution` | 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 the MX Platform API. 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`        | A `user` represents an end-user accessing the MX Platform API via your application, be it a mobile app, web app, desktop app, etc.                                                                                                                                                                                                                                                                                       |
| `member`      | A `member` represents the relationship between a user and an `institution`. A `user` may have multiple members, one each for their bank, their mortgage broker, their credit card provider, etc. Aggregation, verification, and many other processes are centered around a `member`, meaning this is probably the most important type of object you'll be working with.                                                  |
| `account`     | 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 would therefore have two accounts associated with that `member`.                                                                              |
| `transaction` | 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`.                                                                                                                                                           |

## Development and Production Environments

MX provides two environments: Production and development (also called integrations or INT). The development environment shares the same code base and provides the same features as the production environment so that clients can properly develop and test their integrations. However, the development environment does not perfectly replicate the performance of the production environment nor the number and quality of connections to real-world institutions that can be found in the production environment. The development environment provides only the limited number of connections necessary for development testing. Furthermore, certain features — like OAuth — can only be tested in the development environment using MX-provided institutions, and no real-world institutions are available.

MX uses separate base URLs for its development and production environments. All examples given in this reference use the development base URL.

**Development URL**

```
https://int-api.mx.com
```

**Production URL**

```
https://api.mx.com
```

## Authentication and Security

All requests to the MX Platform API must use HTTPS (TLS v1.2 or higher) and include an `Authorization` header using basic access authentication.

For the Platform API, the header format is: `Authorization: Basic <Base64(client_id:api_key)>`. Basic access authentication requires the Base64 encoding of the `client_id` and `api_key` separated by a colon, but many HTTP clients handle the encoding for you. Our cURL example requests use the `-u` option (for example, `-u client_id:api_key`).

Retrieve your `client_id` and `api_key` from the [Client Dashboard](https://dashboard.mx.com/).

<Warning>
  Keep your `client_id` and `api_key` secret. Don't embed them in client-side code or share them in public repositories or forums. These credentials may grant access to your data.
</Warning>

To prevent leaking private information, requests that require authentication may return `404 Not Found`, instead of `401 Unauthorized`.

**Authorization Header Example**

Given the base64 encoding of the following credentials: `CLIENT-1234:API-KEY-4567 -> Q0xJRU5ULTEyMzQ6QVBJLUtFWS00NTY3`.

Format the basic access authorization header as follows: `Authorization: Basic Q0xJRU5ULTEyMzQ6QVBJLUtFWS00NTY3`.

## IP Whitelisting

All requests must come from a whitelisted IP address, which is configured via the client dashboard. Any request from a non-whitelisted IP address will return a `403 Forbidden` error. IP addresses outside of the United States are normally not permissible, so any requests for non-US IPs will require additional scrutiny and will be manually investigated and approved. Should we have any questions or need further details, MX will contact you via email.

## MX IP Address Ranges

MX maintains multiple data centers for failover and load balancing purposes. Each data center has a range of IP addresses and any IP address in these ranges can be active.

The DNS entries for the MX Platform API URLs can resolve to any IP address in our ranges and can change at any time. If you choose to whitelist the IP addresses that the API URLs are allowed to resolve to you must whitelist all of the IP address ranges.

| CIDR              | Range                                                 |
| ----------------- | ----------------------------------------------------- |
| 64.77.254.32/27   | 30 addresses from 64.77.254.33 to 64.77.254.62        |
| 66.43.0.0/22      | 1,022 addresses from 66.43.0.1 to 66.43.3.254         |
| 68.142.151.128/26 | 62 addresses from 68.142.151.129 to 68.142.151.190    |
| 97.75.178.32/27   | 30 addresses from 97.75.178.33 to 97.75.178.62        |
| 146.75.94.131/32  | 1 address 146.75.94.131                               |
| 170.178.148.0/22  | 1,022 addresses from 170.178.148.0 to 170.178.151.255 |
| 192.41.25.128/26  | 62 addresses from 192.41.25.129 to 192.41.25.190      |
| 192.41.58.128/26  | 62 addresses from 192.41.58.129 to 192.41.58.190      |

## DDoS Protection

MX provides an on-demand DDoS protection service using Akamai's DDoS scrubbing center. In the event of a DDoS attack, traffic is only redirected to Akamai.

We will only redirect inbound requests (requests coming into MX), while outbound requests (requests sent to clients/partners) will still come from the existing IP ranges. Outbound requests include but are not limited to mobile upstream events, webhooks and aggregation requests.

Although we only redirect inbound requests, if you have firewall rules that prevent outbound connections to whitelisted IP addresses, you must add those to avoid service disruption during a DDoS mitigation event.

Visit Akamai's documentation to learn more about the IP addresses that may be used in the event of a DDOS attack: [https://techdocs.akamai.com/origin-ip-acl/docs/update-your-origin-server](https://techdocs.akamai.com/origin-ip-acl/docs/update-your-origin-server). We suggest you subscribe to this page to stay up to date on any changes.

## Limits on the API

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

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.

### Rate Limiting

When too many requests are made at a time, a "`429: Too Many Requests`" error may be returned:

Too many requests have been made in a given amount of time. Wait before retrying. The Platform API enforces per-client rate limits (2000 GET / 750 POST+PUT / 150 DELETE requests per second). Reduce your request frequency or implement exponential backoff.

### 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 `apy` fields. This is to be expected in all resources and all aggregations.

### User and Member Limits

The development environment limits developers to 100 users and access to only some of the top financial institutions.

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

## Caching

Certain API resources are subject to change at any time; for instance, institutions. For this reason, we discourage you from caching lists of resources. If caching is necessary, we recommend refreshing a cached list at least daily.

## OAuth

MX encourages partners to use OAuth for authenticating with financial institutions. However, some institutions support OAuth, while others don't. And some institutions only support OAuth and no other forms of authentication.

Furthermore, using OAuth requires you to register with institutions that support OAuth to ensure security and trustworthiness. This registration can only be done after MX has granted you production access; MX will handle this registration on your behalf. You can request production access and OAuth registration on the dashboard.

If you have production access but haven't registered with the institutions that support OAuth, these institutions will not return in any institution-related endpoints.

Two test institutions for testing OAuth flows are available in the integration environment. For more guidance on testing OAuth, see [Testing the Platform API](/resources/test-platform).

## Encrypted Responses

The Platform API supports encrypted responses using JWE (JSON Web Encryption) format. To receive a JWE-encrypted response, include these encryption-specific headers in your API request:

| Header         | Required | Description                                                                                                                                |
| :------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------- |
| `Content-Type` | Yes      | Must be `application/encrypted.<cipher>+json` where `<cipher>` is a supported cipher: `a256gcm` (recommended) or `a128gcm`                 |
| `X-Public-Key` | Yes      | Your ECDH public key in Base64-encoded DER format. Supported curves: `secp384r1` (recommended) or `secp256r1` (also known as `prime256v1`) |

No special account configuration is required—if the headers are present and valid, the API encrypts the response. Decrypt the JWE using your private key to access the original API response.

If there are any problems with the encryption cipher or public key sent in the request headers, the API will respond with an HTTP 412 status and an unencrypted error message.

| Scenario                     | Error Message                       |
| :--------------------------- | :---------------------------------- |
| Invalid public key format    | `Invalid public key`                |
| Unsupported public key curve | `Unsupported curve: <curve_name>`   |
| Invalid cipher               | `Unsupported cipher: <cipher_name>` |
| Unknown error                | `Error processing parameters`       |

### Example

<CodeGroup>
  ```bash Request theme={null}
  # Generate your ECDH key pair with one of the supported elliptic curves
  openssl ecparam -name secp384r1 -genkey -noout -out private_key.pem
  openssl ec -in private_key.pem -pubout -outform DER -out public_key.der

  # Base64 encode your public key
  ECDH_PUBLIC_KEY=$(base64 -i public_key.der)

  # Make the API request
  curl -X GET "https://int-api.mx.com/users" \
    -H "Accept: application/vnd.mx.api.v1+json" \
    -H "Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}" \
    -H "Content-Type: application/encrypted.a256gcm+json" \
    -H "X-Public-Key: ${ECDH_PUBLIC_KEY}"
  ```

  ```text 200 Response theme={null}
  eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIuLi4iLCJ5IjoiLi4uIn19.X1mPFDqKVN8wvhKmPj4ZY0oN...
  ```

  ```json 412 Response theme={null}
  { "error": { "message": "Invalid public key" } }
  ```
</CodeGroup>
