Skip to main content

MDX On Demand v5

MDX On Demand v5 is a proprietary specification for the RESTful exchange of data between financial institutions and MX.

Data providers implement the MDX On Demand API for the purpose of allowing MX to synchronize account and transaction data with the MX Platform.

MDX On Demand supports XML encoding of the request and response bodies. JSON encoding is not supported at this time.

An MDX On Demand session will start with a request to the sessions endpoint to authenticate the user. Additional endpoints are used to request account and transaction information once the user is authenticated.

Base URL

All endpoints in the MDX On Demand API have the following base URL:

https://{partner_base_url}/{institution_id}

The partner_base_url varies with each implementation and is provided to MX by you, the partner. The base URL may contain a port if needed.

The institution_id identifies the financial institution for which the request is made. The institution_id is provided to MX by you. In many integrations — especially those for an online banking provider — the client is a financial institution. In these cases it is recommended to use the same value for the client_id and the institution_id to avoid confusion; however, different values can be used if needed.

HTTPS

All API requests must be made over HTTPS. Calls made to your implementation of the API over plain HTTP should fail. 256-bit SSL or greater is preferred.

Versioning

The MDX version will change as the specification is updated. On Demand requests will specify the version expected in the response. Data providers may wish to support multiple MDX versions as they upgrade from one version to another.

Requests that don't specify a version should return the latest representation of resources. Unsupported endpoints should simply return HTTP 404 NOT FOUND.

Accept Header

All requests will have an Accept header that specifies the encoding and the version being requested.

Accept: application/vnd.moneydesktop.mdx.v5+xml

Content-Type Header

POST and PUT requests will include a Content-Type header to specify the encoding and the version of the request body. Your responses should include the same header.

Content-Type: application/vnd.moneydesktop.mdx.v5+xml

Job Type Header

An MDX-Job-Type header is provided with each request. The header identifies whether the request is being initiated by a user login or a background aggregation request to update the user's data. The provided value will be either foreground or background.

MDX-Job-Type: foreground

MDX-Job-Type: background

Sessions

When synchronizing accounts and transactions with MDX On Demand, a session key must first be obtained. MX will open a session with a request to the sessions endpoint.

When the session is established, the partner will return a session key to MX. MX will provide this session key in an MDX-Session-Key header in all subsequent requests during that session, as shown in the example.

If a request is made with an invalid session key, you should return a 401 (Unauthorized) error.

Example Session Request


_10
$ curl -H "MDX-Session-Key: [SESSION_KEY]" https://dataprovider_base_url/:institution_id/accounts

Authentication

Every MDX On Demand request will include MDX-HMAC and Content-MD5 headers. If the HMAC signature or MD5 content do not match, you should return a 412 (precondition failed) error.

The HMAC key will be provided during your integration with MX and will be a 32- to 64-byte string. The length depends on the algorithm used. The key will be provided in base64 format since the key may contain non-printable characters. Supported algorithms are SHA1, SHA224, SHA256, SHA384, and SHA512.

MD5 Authentication

The Content-MD5 header is calculated by MD5 authenticating the body of each request. For GET requests without a body, you will use an empty string when computing the Content-MD5 value.

HMAC Signature

The MDX-HMAC header is composed using a string that is signed via HMAC. It is a canonical composition of the request's headers, the HTTP verb, and the REST resource.

The MDX-Session-Key value will be an empty string in requests to the sessions endpoint.

The REST Resource of the Request value will be the final portion of the URL. It will be one of these values:

  • /sessions
  • /accounts
  • /transactions
  • /user
  • /member
  • /account_owner
  • /account_number

Signature Pattern


_10
HTTP VERB + "\n" + Content-MD5 Header + "\n" + Content-Type Header + "\n" + UNIX Epoch Date Time + "\n" + Accept Header + "\n" + MDX-Session-Key + "\n" + REST Resource of Request

HMAC Example

Given the information above, let's take a look at what a POST request to /sessions would look like.


_10
POST /sessions "<?xml version=\"1.0\"?>\n<mdx version=\"5.0\">\n <session>\n <userkey><![CDATA[the-userkey]]></userkey>\n </session>\n</mdx>\n"
_10
Content-Type: application/vnd.moneydesktop.mdx.v5+xml
_10
Date: 1382975431
_10
Accept: application/vnd.moneydesktop.mdx.v5+xml
_10
MDX-Session-Key:

MD5 Hash

The MD5 hash would be computed using the body of the example above.


_10
require 'digest/md5'
_10
digest = Digest::MD5.hexdigest("<?xml version=\"1.0\"?>\n<mdx version=\"5.0\">\n <session>\n <userkey><![CDATA[the-userkey]]></userkey>\n </session>\n</mdx>\n")
_10
puts digest
_10
=> "e9a179f879165fd64bdeaa57032d342f"

HMAC Signature

Now that we have our MD5 hash, we can take a look at our headers to compose our HMAC signature.


_10
POST /sessions "<?xml version=\"1.0\"?>\n<mdx version=\"5.0\">\n <session>\n <userkey><![CDATA[the-userkey]]></userkey>\n </session>\n</mdx>\n"
_10
Content-MD5: e9a179f879165fd64bdeaa57032d342f
_10
Content-Type: application/vnd.moneydesktop.mdx.v5+xml
_10
Date: 1382975431
_10
Accept: application/vnd.moneydesktop.mdx.v5+xml
_10
MDX-Session-Key:

Canonical String

The canonical string to be signed can now be composed.


_10
"POST\ne9a179f879165fd64bdeaa57032d342f\napplication/vnd.moneydesktop.mdx.v5+xml\n1382975431\napplication/vnd.moneydesktop.mdx.v5+xml\n\n/sessions"

Generated Signature

If your HMAC key (salt) was QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo3ODkwMTI=, the resulting signed signature would be generated as shown below.

The resulting signature is e47928dcd29e494116961ad12884c8fd7aae07f2. This signature will be provided in the MDX-HMAC header of our request.


_10
require 'base64'
_10
require 'openssl'
_10
_10
salt = 'QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo3ODkwMTI='
_10
digest = ::OpenSSL::Digest.new('sha1')
_10
hmac_signature = "POST\ne9a179f879165fd64bdeaa57032d342f\napplication/vnd.moneydesktop.mdx.v5+xml\n1382975431\napplication/vnd.moneydesktop.mdx.v5+xml\n\n/sessions"
_10
hmac = ::OpenSSL::HMAC.hexdigest(digest, ::Base64.decode64(salt), hmac_signature)
_10
puts hmac
_10
_10
# => "e47928dcd29e494116961ad12884c8fd7aae07f2"

Session Request

We are now ready to compose our POST request to the /sessions endpoint.


_10
POST /sessions "<?xml version=\"1.0\"?>\n<mdx version=\"5.0\">\n <session>\n <userkey><![CDATA[the-userkey]]></userkey>\n </session>\n</mdx>\n"
_10
Content-MD5: e9a179f879165fd64bdeaa57032d342f
_10
Content-Type: application/vnd.moneydesktop.mdx.v5+xml
_10
Date: 1382975431
_10
Accept: application/vnd.moneydesktop.mdx.v5+xml
_10
MDX-Session-Key:
_10
MDX-HMAC: e47928dcd29e494116961ad12884c8fd7aae07f2

HMAC Notes

The HMAC signature is generated in the MX system with lower-case letters in the hexadecimal representation. Some code libraries return the signature with upper-case letters. A ToLower or downcase applied to the signature may be required on your end before comparing it to the one provided in the request header. A case-insensitve comparison may also be used.

The base64 HMAC key in this example decodes to a 32-byte string. This is the ideal size for the SHA1 algorithm, although most libraries such as OpenSSL will accept other key lengths. SHA1 outputs a 40-character HMAC result. The length of the HMAC key and of the resulting signatures will vary if other algorithms are used.

IP Filtering

MDX On Demand requests will initiate from one of MX's data centers. For failover and load balancing purposes, these requests can initiate from any data center. If you intend to use IP whitelisting, the IP address ranges of all of MX's data centers must be included.

You should return a 403 (Forbidden) error for an MDX On Demand request that fails IP validation.

CIDRRange
64.77.254.32/2730 addresses from 64.77.254.33 to 64.77.254.62
68.142.151.128/2662 addresses from 68.142.151.129 to 68.142.151.190
146.75.94.131/321 address 146.75.94.131
97.75.178.32/2730 addresses from 97.75.178.33 to 97.75.178.62
192.41.25.128/2662 addresses from 192.41.25.129 to 192.41.25.190
192.41.58.128/2662 addresses from 192.41.58.129 to 192.41.58.190

Additional Authentication

In addition to request signing and IP filtering, you may choose to implement any or all of the following: HTTP basic authentication, mutual authentication, and/or CA certification authentication. Any additional authentication must be set up with MX during your initial integration.

Errors

The MDX On Demand API uses conventional HTTP response codes to indicate success or failure of an API request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that resulted from the provided information (for example, a required parameter was missing), and codes in the 5xx range indicate an error with your servers.

HTTP Status Code Summary

  • 200 OK: Everything worked as expected.
  • 400 Bad Request: Malformed request body or missing a required parameter.
  • 401 Unauthorized: No valid session key or credentials provided.
  • 403 Forbidden: The IP address isn't whitelisted.
  • 404 Not Found: The requested item doesn't exist.
  • 406 Not Acceptable: The request didn't specify a valid version.
  • 412 Precondition Failed: The HMAC was invalid or missing.
  • 422 Unprocessable Entity: The credentials couldn't be decrypted.
  • 429 Too Many Requests: The partner's MDX service is at capacity.
  • 500 Internal Server Error: Something went wrong on the data provider's end.
  • 502 Bad Gateway: Something went wrong on the data provider's end.
  • 503 Service Unavailable: The service is down for maintenance.
  • 504 Gateway Timeout: The request couldn't be completed in the time allotted.

Additional Error Codes

You should use the error codes and messages documented here when applicable. These error codes and messages are intended to supplement the HTTP status code and offer additional detail. A message should always be returned. The code is optional. You can return your own code or leave the field blank, but the <code> and <message> elements should always be present in the error response body.

The format for sending an error is shown in the example.

CodeMessageDescription
4010Invalid CredentialsThe user key or login and password were invalid.
4011LockedThe login was valid, but the account was locked.
4012Invalid Session KeyThe provided session key was invalid.
4013MFA FailedThe MFA login information provided was incorrect.

_10
<mdx version="5.0">
_10
<error>
_10
<code>4010</code>
_10
<message>Error message.</message>
_10
</error>
_10
</mdx>

Response Format

The MDX On Demand specification is XML-based. Responses are required to be UTF-8 encoded and XML tags must be lowercase. Reserved XML characters must be properly escaped. The XML response must not contain Unicode Byte Order Mark characters (for example, 0xfeff).

Compression

Gzip compression is supported when Content-Encoding is set to gzip.

Data Sanitization

You are required to avoid sending identifiable account information such as complete account and/or credit card numbers for account IDs and names.