NAV
Getting Started With Atrium
cURL C# Go Java Node PHP Python Ruby
  • What's in this guide
  • Whitelisting
  • Resource structure
  • Creating users
  • Creating members
  • Aggregating data and dealing with MFA
  • Pulling data
  • Tools to get you running
  • Testing your setup
  • Test endpoints
  • Support
  • Product mailing list
  • What's in this guide

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

    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 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 A user represents a person using Atrium 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 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 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 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

    Example request

    $ 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\"}"
            }
          }'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class CreateUserExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var body = new UserCreateRequestBody(); // UserCreateRequestBody | User object to be created with optional parameters (identifier, is_disabled, metadata)
    
                try
                {
                    // Create user
                    UserResponseBody response = client.users.CreateUser(body);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling UsersApi.CreateUser: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      body := atrium.UserCreateRequestBody{} // UserCreateRequestBody | User object to be created with optional parameters (identifier, is_disabled, metadata)
    
      response, _, err := client.Users.CreateUser(ctx, body)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class UsersApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            UserCreateRequestBody body = new UserCreateRequestBody(); // UserCreateRequestBody | User object to be created with optional parameters (identifier, is_disabled, metadata)
    
            try {
                UserResponseBody response = client.users.createUser(body);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling UsersApi#createUser");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var body = new atrium.UserCreateRequestBody(); // UserCreateRequestBody | User object to be created with optional parameters (identifier, is_disabled, metadata)
    
    var response = client.users.createUser(body);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $body = new \atrium\model\UserCreateRequestBody(); // \atrium\model\UserCreateRequestBody | User object to be created with optional parameters (identifier, is_disabled, metadata)
    
    try {
        $result = $client->users->createUser($body);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling UsersApi->createUser: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    body = atrium.UserCreateRequestBody() # UserCreateRequestBody | User object to be created with optional parameters (identifier, is_disabled, metadata)
    
    try:
        # Create user
        response = client.users.create_user(body)
        pprint(response)
    except ApiException as e:
        print("Exception when calling UsersApi->create_user: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    body = Atrium::UserCreateRequestBody.new # UserCreateRequestBody | User object to be created with optional parameters (identifier, is_disabled, metadata)
    
    begin
      #Create user
      response = client.users.create_user(body)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling UsersApi->create_user: #{e}"
    end
    

    Example response

    Status: 200 OK
    
    {
      "user": {
        "guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54",
        "identifier": "unique_id",
        "is_disabled": false,
        "metadata": "{\"first_name\": \"Steven\"}"
      }
    }
    
    class UserResponseBody {
      User:
        class User {
          Guid: USR-d74cb14f-fd0a-449f-991b-e0362a63d9c6
          Identifier: My-Unique-ID
          IsDisabled: false
          Metadata: {"first_name": "Steven", "last_name": "Universe"}
        }
    }
    
    {
      User:
        {
          Guid: USR-d74cb14f-fd0a-449f-991b-e0362a63d9c6
          Identifier: My-Unique-ID
          IsDisabled: false
          Metadata: {"first_name": "Steven", "last_name": "Universe"}
        }
    }
    
    class UserResponseBody {
      user:
        class User {
          guid: USR-d74cb14f-fd0a-449f-991b-e0362a63d9c6
          identifier: My-Unique-ID
          isDisabled: false
          metadata: {"first_name": "Steven", "last_name": "Universe"}
        }
    }
    
    UserResponseBody {
      user:
        User {
          guid: USR-d74cb14f-fd0a-449f-991b-e0362a63d9c6
          identifier: My-Unique-ID
          isDisabled: false
          metadata: {"first_name": "Steven", "last_name": "Universe"}
        }
    }
    
    atrium/model/UserResponseBody Object (
      [user] =>
        atrium/model/User Object (
          [guid] => USR-d74cb14f-fd0a-449f-991b-e0362a63d9c6
          [identifier] => My-Unique-ID
          [is_disabled] => false
          [metadata] => {"first_name": "Steven", "last_name": "Universe"}
        )
    )
    
    {
      'user':
        {
          'guid': USR-d74cb14f-fd0a-449f-991b-e0362a63d9c6
          'identifier': My-Unique-ID
          'is_disabled': false
          'metadata': {"first_name": "Steven", "last_name": "Universe"}
        }
    }
    
    #<MX::UserResponseBody
      @user=
        #<MX::User
          @guid= USR-d74cb14f-fd0a-449f-991b-e0362a63d9c6
          @identifier= My-Unique-ID
          @is_disabled= false
          @metadata= {"first_name": "Steven", "last_name": "Universe"}
        >
    >
    

    To create a new user, call the create user endpoint. It's a good idea to send along a unique identifier 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 on our API reference page.

    An example request for creating a user is shown to the right.

    Creating members

    Once a user is created, we recommend creating a member with our MX Connect widget. 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:

    Once your member has been created, you'll want to call the read member 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

    GET /institutions/{institution_code}
    

    Example request

    $ curl -i -X GET '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}'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class ReadInstitutionExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var institutionCode = "example_institution_code";  // string | The institution_code of the institution.
    
                try
                {
                    // Read institution
                    InstitutionResponseBody response = client.institutions.ReadInstitution(institutionCode);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling InstitutionsApi.ReadInstitution: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      institutionCode := "example_institution_code" // string | The institution_code of the institution.
    
      response, _, err := client.Institutions.ReadInstitution(ctx, institutionCode)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class InstitutionsApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            String institutionCode = "example_institution_code"; // String | The institution_code of the institution.
    
            try {
                InstitutionResponseBody response = client.institutions.readInstitution(institutionCode);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling InstitutionsApi#readInstitution");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var institutionCode = "example_institution_code"; // string | The institution_code of the institution.
    
    var response = client.institutions.readInstitution(institutionCode);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $institution_code = "example_institution_code"; // string | The institution_code of the institution.
    
    try {
        $result = $client->institutions->readInstitution($institution_code);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling InstitutionsApi->readInstitution: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    institution_code = "example_institution_code" # str | The institution_code of the institution.
    
    try:
        # Read institution
        response = client.institutions.read_institution(institution_code)
        pprint(response)
    except ApiException as e:
        print("Exception when calling InstitutionsApi->read_institution: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    institution_code = "example_institution_code" # String | The institution_code of the institution.
    
    begin
      #Read institution
      response = client.institutions.read_institution(institution_code)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling InstitutionsApi->read_institution: #{e}"
    end
    

    Example response

    Status: 200 OK
    
    {
      "institution": {
        "code": "mxbank",
        "medium_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png",
        "name": "MX Bank",
        "small_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png",
        "supports_account_identification": true,
        "supports_account_verification": true,
        "url": "https://www.mx.com"
      }
    }
    
    class InstitutionResponseBody {
      Institution:
        class Institution {
          Code: Mxbank
          MediumLogoUrl: https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png
          Name: mx Bank
          SmallLogoUrl: https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png
          SupportsAccountIdentification: true
          SupportsAccountVerification: true
          Url: https://www.mx.com
        }
    }
    
    {
      Institution:
        {
          Code: mx
          MediumLogoUrl: https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png
          Name: mx Bank
          SmallLogoUrl: https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png
          SupportsAccountIdentification: true
          SupportsAccountVerification: true
          Url: https://www.mx.com
        }
    }
    
    class InstitutionResponseBody {
      institution:
        class Institution {
          code: mxbank
          mediumLogoUrl: https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png
          name: mx Bank
          smallLogoUrl: https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png
          supportsAccountIdentification: true
          supportsAccountVerification: true
          url: https://www.mx.com
        }
    }
    
    InstitutionResponseBody {
      institution:
        Institution {
          code: mxbank
          mediumLogoUrl: https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png
          name: mx Bank
          smallLogoUrl: https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png
          supportsAccountIdentification: true
          supportsAccountVerification: true
          url: https://www.mx.com
        }
    }
    
    atrium/model/InstitutionResponseBody Object (
      [institution] =>
        atrium/model/Institution Object (
          [code] => mxbank
          [medium_logo_url] => https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png
          [name] => mx Bank
          [small_logo_url] => https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png
          [supports_account_identification] => true
          [supports_account_verification] => true
          [url] => https://www.mx.com
        )
    )
    
    {
      'institution':
        {
          'code': mxbank
          'medium_logo_url': https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png
          'name': mx Bank
          'small_logo_url': https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png
          'supports_account_identification': true
          'supports_account_verification': true
          'url': https://www.mx.com
        }
    }
    
    #<MX::InstitutionResponseBody
      @institution=
        #<MX::Institution
          @code= mxbank
          @medium_logo_url= https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png
          @name= mx Bank
          @small_logo_url= https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png
          @supports_account_identification= true
          @supports_account_verification= true
          @url= https://www.mx.com
        >
    >
    

    2. Get institution required credentials

    GET /institutions/{institution_code}/credentials
    

    Example request

    $ curl -i -X GET 'https://vestibule.mx.com/institutions/mxbank/credentials' \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {mx_api_key}' \
      -H 'MX-Client-ID: {mx_client_id}'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class ReadInstitutionCredentialsExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var institutionCode = "example_institution_code";  // string | The institution_code of the institution.
    
                try
                {
                    // Read institution credentials
                    CredentialsResponseBody response = client.institutions.ReadInstitutionCredentials(institutionCode);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling InstitutionsApi.ReadInstitutionCredentials: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      institutionCode := "example_institution_code" // string | The institution_code of the institution.
    
      response, _, err := client.Institutions.ReadInstitutionCredentials(ctx, institutionCode)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class InstitutionsApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            String institutionCode = "example_institution_code"; // String | The institution_code of the institution.
    
            try {
                CredentialsResponseBody response = client.institutions.readInstitutionCredentials(institutionCode);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling InstitutionsApi#readInstitutionCredentials");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var institutionCode = "example_institution_code"; // string | The institution_code of the institution.
    
    var response = client.institutions.readInstitutionCredentials(institutionCode);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $institution_code = "example_institution_code"; // string | The institution_code of the institution.
    
    try {
        $result = $client->institutions->readInstitutionCredentials($institution_code);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling InstitutionsApi->readInstitutionCredentials: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    institution_code = "example_institution_code" # str | The institution_code of the institution.
    
    try:
        # Read institution credentials
        response = client.institutions.read_institution_credentials(institution_code)
        pprint(response)
    except ApiException as e:
        print("Exception when calling InstitutionsApi->read_institution_credentials: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    institution_code = "example_institution_code" # String | The institution_code of the institution.
    
    begin
      #Read institution credentials
      response = client.institutions.read_institution_credentials(institution_code)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling InstitutionsApi->read_institution_credentials: #{e}"
    end
    

    Example response

    Status: 200 OK
    
    {
        "credentials": [
            {
                "field_name": "login_email",
                "guid": "CRD-12ce94ad-032b-5441-8cb3-d7ebe3a35676",
                "label": "Email Address",
                "display_order": 0,
                "type": "LOGIN"
            },
            {
                "field_name": "login_password",
                "guid": "CRD-305767e4-f464-765b-8f83-881b5bd307ec",
                "label": "PayPal password",
                "display_order": 1,
                "type": "PASSWORD"
            }
        ]
    }
    
    class CredentialsResponseBody {
      Credentials: [
        class CredentialResponse {
          FieldName: LOGIN
          Guid: CRD-1ec152cd-e628-e81a-e852-d1e7104624da
          Label: Username
          Options: [
            class CredentialOption {
              Label: option_label
              Value: option_value
            }      
          ]
          Type: LOGIN
        }  
      ]
    }
    
    {
      Credentials: [
        {
          FieldName: LOGIN
          Guid: CRD-1ec152cd-e628-e81a-e852-d1e7104624da
          Label: Username
          Options: [
            {
              Label: option_label
              Value: option_value
            }      
          ]
          Type: LOGIN
        }  
      ]
    }
    
    class CredentialsResponseBody {
      credentials: [
        class CredentialResponse {
          fieldName: LOGIN
          guid: CRD-1ec152cd-e628-e81a-e852-d1e7104624da
          label: Username
          options: [
            class CredentialOption {
              label: option_label
              value: option_value
            }      
          ]
          type: LOGIN
        }  
      ]
    }
    
    CredentialsResponseBody {
      credentials: [
        CredentialResponse {
          fieldName: LOGIN
          guid: CRD-1ec152cd-e628-e81a-e852-d1e7104624da
          label: Username
          options: [
            CredentialOption {
              label: option_label
              value: option_value
            }      
          ]
          type: LOGIN
        }  
      ]
    }
    
    atrium/model/CredentialsResponseBody Object (
      [credentials] => Array (
        atrium/model/CredentialResponse Object (
          [field_name] => LOGIN
          [guid] => CRD-1ec152cd-e628-e81a-e852-d1e7104624da
          [label] => Username
          [options] => Array (
            atrium/model/CredentialOption Object (
              [label] => option_label
              [value] => option_value
            )      
          )
          [type] => LOGIN
        )  
      )
    )
    
    {
      'credentials': [
        {
          'field_name': LOGIN
          'guid': CRD-1ec152cd-e628-e81a-e852-d1e7104624da
          'label': Username
          'options': [
            {
              'label': option_label
              'value': option_value
            }      
          ]
          'type': LOGIN
        }  
      ]
    }
    
    #<MX::CredentialsResponseBody
      @credentials= [
        #<MX::CredentialResponse
          @field_name= LOGIN
          @guid= CRD-1ec152cd-e628-e81a-e852-d1e7104624da
          @label= Username
          @options= [
            #<MX::CredentialOption
              @label= option_label
              @value= option_value
            >      
          ]
          @type= LOGIN
        >  
      ]
    >
    

    3. Create a member

    POST /users/{user_guid}/members
    

    Example request

    $ 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": "chase",
              "credentials": [
                {
                  "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
                  "value": "ExampleUsername"
                },
                {
                  "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
                  "value": "Pa$$vv@Rd"
                }
              ],
              "skip_aggregation": true
            }
          }'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class CreateMemberExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var userGuid = "USR-123";  // string | The unique identifier for a `user`.
                var body = new MemberCreateRequestBody(); // MemberCreateRequestBody | Member object to be created with optional parameters (identifier and metadata) and required parameters (credentials and institution_code)
    
                try
                {
                    // Create member
                    MemberResponseBody response = client.members.CreateMember(userGuid, body);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling MembersApi.CreateMember: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      userGUID := "USR-123" // string | The unique identifier for a `user`.
      body := atrium.MemberCreateRequestBody{} // MemberCreateRequestBody | Member object to be created with optional parameters (identifier and metadata) and required parameters (credentials and institution_code)
    
      response, _, err := client.Members.CreateMember(ctx, userGUIDbody)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class MembersApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            String userGuid = "USR-123"; // String | The unique identifier for a `user`.
            MemberCreateRequestBody body = new MemberCreateRequestBody(); // MemberCreateRequestBody | Member object to be created with optional parameters (identifier and metadata) and required parameters (credentials and institution_code)
    
            try {
                MemberResponseBody response = client.members.createMember(userGuid, body);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling MembersApi#createMember");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var userGuid = "USR-123"; // string | The unique identifier for a `user`.
    var body = new atrium.MemberCreateRequestBody(); // MemberCreateRequestBody | Member object to be created with optional parameters (identifier and metadata) and required parameters (credentials and institution_code)
    
    var response = client.members.createMember(userGuid, body);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $user_guid = "USR-123"; // string | The unique identifier for a `user`.
    $body = new \atrium\model\MemberCreateRequestBody(); // \atrium\model\MemberCreateRequestBody | Member object to be created with optional parameters (identifier and metadata) and required parameters (credentials and institution_code)
    
    try {
        $result = $client->members->createMember($user_guid, $body);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling MembersApi->createMember: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    user_guid = "USR-123" # str | The unique identifier for a `user`.
    body = atrium.MemberCreateRequestBody() # MemberCreateRequestBody | Member object to be created with optional parameters (identifier and metadata) and required parameters (credentials and institution_code)
    
    try:
        # Create member
        response = client.members.create_member(user_guid, body)
        pprint(response)
    except ApiException as e:
        print("Exception when calling MembersApi->create_member: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    user_guid = "USR-123" # String | The unique identifier for a `user`.
    body = Atrium::MemberCreateRequestBody.new # MemberCreateRequestBody | Member object to be created with optional parameters (identifier and metadata) and required parameters (credentials and institution_code)
    
    begin
      #Create member
      response = client.members.create_member(user_guidbody)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling MembersApi->create_member: #{e}"
    end
    

    Example response

    Status: 202 Accepted
    
    {
      "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": "chase",
        "is_being_aggregated": true,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "INITIATED",
        "successfully_aggregated_at": null,
        "user_guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54"
      }
    }
    
    class MemberResponseBody {
      Member:
        class Member {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          Identifier: unique_id
          InstitutionCode: chase
          IsBeingAggregated: false
          Metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          Name: Chase Bank
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          UserGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    {
      Member:
        {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          Identifier: unique_id
          InstitutionCode: chase
          IsBeingAggregated: false
          Metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          Name: Chase Bank
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          UserGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    class MemberResponseBody {
      member:
        class Member {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          identifier: unique_id
          institutionCode: chase
          isBeingAggregated: false
          metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          name: Chase Bank
          status: COMPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          userGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    MemberResponseBody {
      member:
        Member {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          identifier: unique_id
          institutionCode: chase
          isBeingAggregated: false
          metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          name: Chase Bank
          status: COMPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          userGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    atrium/model/MemberResponseBody Object (
      [member] =>
        atrium/model/Member Object (
          [aggregated_at] => 2016-10-13T18:07:57+00:00
          [connection_status] => CONNECTED
          [guid] => MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          [identifier] => unique_id
          [institution_code] => chase
          [is_being_aggregated] => false
          [metadata] => {"credentials_last_refreshed_at": "2015-10-15"}
          [name] => Chase Bank
          [status] => COMPLETED
          [successfully_aggregated_at] => 2016-10-13T17:57:38+00:00
          [user_guid] => USR-fa7537f3-48aa-a683-a02a-b18940482f54
        )
    )
    
    {
      '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': chase
          'is_being_aggregated': false
          'metadata': {"credentials_last_refreshed_at": "2015-10-15"}
          'name': Chase Bank
          'status': COMPLETED
          'successfully_aggregated_at': 2016-10-13T17:57:38+00:00
          'user_guid': USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    #<MX::MemberResponseBody
      @member=
        #<MX::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= chase
          @is_being_aggregated= false
          @metadata= {"credentials_last_refreshed_at": "2015-10-15"}
          @name= Chase Bank
          @status= COMPLETED
          @successfully_aggregated_at= 2016-10-13T17:57:38+00:00
          @user_guid= USR-fa7537f3-48aa-a683-a02a-b18940482f54
        >
    >
    

    4. Poll the member status

    GET /users/{user_guid}/members/{member_guid}/status
    

    Example request

    $ curl -i -X GET '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}'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class ReadMemberStatusExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var memberGuid = "MBR-123";  // string | The unique identifier for a `member`.
                var userGuid = "USR-123";  // string | The unique identifier for a `user`.
    
                try
                {
                    // Read member connection status
                    MemberConnectionStatusResponseBody response = client.members.ReadMemberStatus(memberGuid, userGuid);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling MembersApi.ReadMemberStatus: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      memberGUID := "MBR-123" // string | The unique identifier for a `member`.
      userGUID := "USR-123" // string | The unique identifier for a `user`.
    
      response, _, err := client.Members.ReadMemberStatus(ctx, memberGUID, userGUID)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class MembersApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            String memberGuid = "MBR-123"; // String | The unique identifier for a `member`.
            String userGuid = "USR-123"; // String | The unique identifier for a `user`.
    
            try {
                MemberConnectionStatusResponseBody response = client.members.readMemberStatus(memberGuid, userGuid);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling MembersApi#readMemberStatus");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var memberGuid = "MBR-123"; // string | The unique identifier for a `member`.
    var userGuid = "USR-123"; // string | The unique identifier for a `user`.
    
    var response = client.members.readMemberStatus(memberGuid, userGuid);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $member_guid = "MBR-123"; // string | The unique identifier for a `member`.
    $user_guid = "USR-123"; // string | The unique identifier for a `user`.
    
    try {
        $result = $client->members->readMemberStatus($member_guid, $user_guid);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling MembersApi->readMemberStatus: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # str | The unique identifier for a `member`.
    user_guid = "USR-123" # str | The unique identifier for a `user`.
    
    try:
        # Read member connection status
        response = client.members.read_member_status(member_guid, user_guid)
        pprint(response)
    except ApiException as e:
        print("Exception when calling MembersApi->read_member_status: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # String | The unique identifier for a `member`.
    user_guid = "USR-123" # String | The unique identifier for a `user`.
    
    begin
      #Read member connection status
      response = client.members.read_member_status(member_guid, user_guid)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling MembersApi->read_member_status: #{e}"
    end
    

    Example response

    Status: 200 OK
    
    {
      "member": {
        "aggregated_at": "2016-10-13T18:07:57+00:00",
        "connection_status": "CONNECTED",
        "guid": "MBR-7c6f361b-e582-15b6-60c0-358f12466b4b",
        "has_processed_accounts": true,
        "has_processed_transactions": false,
        "identifier": "unique_id",
        "institution_code": "chase",
        "is_being_aggregated": false,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "COMPLETED",
        "successfully_aggregated_at": "2016-10-13T17:57:38+00:00",
        "user_guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54"
      }
    }
    
    class MemberConnectionStatusResponseBody {
      Member:
        class MemberConnectionStatus {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          Challenges: [
            class Challenge {
              FieldName: Who is this guy?
              Guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              ImageData: Who is this guy?
              Label: Who is this guy?
              Options: [
                class ChallengeOption {
                  ImageData: data:image/png;base64,iVBORw0KGgoAAAANSUh ... more image data ...
                  Label: IMAGE_1
                  Value: image_data
                }          
              ]
              Type: IMAGE_DATA
            }      
          ]
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: true
          HasProcessedTransactions: false
          IsBeingAggregated: false
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    {
      Member:
        {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          Challenges: [
            {
              FieldName: Who is this guy?
              Guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              ImageData: Who is this guy?
              Label: Who is this guy?
              Options: [
                {
                  ImageData: data:image/png;base64,iVBORw0KGgoAAAANSUh ... more image data ...
                  Label: IMAGE_1
                  Value: image_data
                }          
              ]
              Type: IMAGE_DATA
            }      
          ]
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: true
          HasProcessedTransactions: false
          IsBeingAggregated: false
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    class MemberConnectionStatusResponseBody {
      member:
        class MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          challenges: [
            class Challenge {
              fieldName: Who is this guy?
              guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              imageData: Who is this guy?
              label: Who is this guy?
              options: [
                class ChallengeOption {
                  imageData: data:image/png;base64,iVBORw0KGgoAAAANSUh ... more image data ...
                  label: IMAGE_1
                  value: image_data
                }          
              ]
              type: IMAGE_DATA
            }      
          ]
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: true
          hasProcessedTransactions: false
          isBeingAggregated: false
          status: COMPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    MemberConnectionStatusResponseBody {
      member:
        MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          challenges: [
            Challenge {
              fieldName: Who is this guy?
              guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              imageData: Who is this guy?
              label: Who is this guy?
              options: [
                ChallengeOption {
                  imageData: data:image/png;base64,iVBORw0KGgoAAAANSUh ... more image data ...
                  label: IMAGE_1
                  value: image_data
                }          
              ]
              type: IMAGE_DATA
            }      
          ]
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: true
          hasProcessedTransactions: false
          isBeingAggregated: false
          status: COMPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    atrium/model/MemberConnectionStatusResponseBody Object (
      [member] =>
        atrium/model/MemberConnectionStatus Object (
          [aggregated_at] => 2016-10-13T18:07:57+00:00
          [challenges] => Array (
            atrium/model/Challenge Object (
              [field_name] => Who is this guy?
              [guid] => CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              [image_data] => Who is this guy?
              [label] => Who is this guy?
              [options] => Array (
                atrium/model/ChallengeOption Object (
                  [image_data] => data:image/png;base64,iVBORw0KGgoAAAANSUh ... more image data ...
                  [label] => IMAGE_1
                  [value] => image_data
                )          
              )
              [type] => IMAGE_DATA
            )      
          )
          [connection_status] => CONNECTED
          [guid] => MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          [has_processed_accounts] => true
          [has_processed_transactions] => false
          [is_being_aggregated] => false
          [status] => COMPLETED
          [successfully_aggregated_at] => 2016-10-13T17:57:38+00:00
        )
    )
    
    {
      'member':
        {
          'aggregated_at': 2016-10-13T18:07:57+00:00
          'challenges': [
            {
              'field_name': Who is this guy?
              'guid': CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              'image_data': Who is this guy?
              'label': Who is this guy?
              'options': [
                {
                  'image_data': data:image/png;base64,iVBORw0KGgoAAAANSUh ... more image data ...
                  'label': IMAGE_1
                  'value': image_data
                }          
              ]
              'type': IMAGE_DATA
            }      
          ]
          'connection_status': CONNECTED
          'guid': MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          'has_processed_accounts': true
          'has_processed_transactions': false
          'is_being_aggregated': false
          'status': COMPLETED
          'successfully_aggregated_at': 2016-10-13T17:57:38+00:00
        }
    }
    
    #<MX::MemberConnectionStatusResponseBody
      @member=
        #<MX::MemberConnectionStatus
          @aggregated_at= 2016-10-13T18:07:57+00:00
          @challenges= [
            #<MX::Challenge
              @field_name= Who is this guy?
              @guid= CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              @image_data= Who is this guy?
              @label= Who is this guy?
              @options= [
                #<MX::ChallengeOption
                  @image_data= data:image/png;base64,iVBORw0KGgoAAAANSUh ... more image data ...
                  @label= IMAGE_1
                  @value= image_data
                >          
              ]
              @type= IMAGE_DATA
            >      
          ]
          @connection_status= CONNECTED
          @guid= MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          @has_processed_accounts= true
          @has_processed_transactions= false
          @is_being_aggregated= false
          @status= COMPLETED
          @successfully_aggregated_at= 2016-10-13T17:57:38+00:00
        >
    >
    

    Example response for status CHALLENGED

    Status: 200 OK
    
    {
      "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"
      }
    }
    
    class MemberConnectionStatusResponseBody {
      Member:
        class MemberConnectionStatus {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          Challenges: [
            class Challenge {
              FieldName: What city were you born in?
              Guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              Label: What city were you born in?
              Type: TEXT
            }      
          ]
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: true
          HasProcessedTransactions: false
          IsBeingAggregated: false
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    {
      Member:
        {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          Challenges: [
            {
              FieldName: What city were you born in?
              Guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              Label: What city were you born in?
              Type: TEXT
            }      
          ]
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: true
          HasProcessedTransactions: false
          IsBeingAggregated: false
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    class MemberConnectionStatusResponseBody {
      member:
        class MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          challenges: [
            class Challenge {
              fieldName: What city were you born in?
              guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              label: What city were you born in?
              type: TEXT
            }      
          ]
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: true
          hasProcessedTransactions: false
          isBeingAggregated: false
          status: COMPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    MemberConnectionStatusResponseBody {
      member:
        MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          challenges: [
            Challenge {
              fieldName: What city were you born in?
              guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              label: What city were you born in?
              type: TEXT
            }      
          ]
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: true
          hasProcessedTransactions: false
          isBeingAggregated: false
          status: COMPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    atrium/model/MemberConnectionStatusResponseBody Object (
      [member] =>
        atrium/model/MemberConnectionStatus Object (
          [aggregated_at] => 2016-10-13T18:07:57+00:00
          [challenges] => Array (
            atrium/model/Challenge Object (
              [field_name] => What city were you born in?
              [guid] => CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              [label] => What city were you born in?
              [type] => TEXT
            )      
          )
          [connection_status] => CONNECTED
          [guid] => MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          [has_processed_accounts] => true
          [has_processed_transactions] => false
          [is_being_aggregated] => false
          [status] => COMPLETED
          [successfully_aggregated_at] => 2016-10-13T17:57:38+00:00
        )
    )
    
    {
      'member':
        {
          'aggregated_at': 2016-10-13T18:07:57+00:00
          'challenges': [
            {
              'field_name': What city were you born in?
              'guid': CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              'label': What city were you born in?
              'type': TEXT
            }      
          ]
          'connection_status': CONNECTED
          'guid': MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          'has_processed_accounts': true
          'has_processed_transactions': false
          'is_being_aggregated': false
          'status': COMPLETED
          'successfully_aggregated_at': 2016-10-13T17:57:38+00:00
        }
    }
    
    #<MX::MemberConnectionStatusResponseBody
      @member=
        #<MX::MemberConnectionStatus
          @aggregated_at= 2016-10-13T18:07:57+00:00
          @challenges= [
            #<MX::Challenge
              @field_name= What city were you born in?
              @guid= CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              @label= What city were you born in?
              @type= TEXT
            >      
          ]
          @connection_status= CONNECTED
          @guid= MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          @has_processed_accounts= true
          @has_processed_transactions= false
          @is_being_aggregated= false
          @status= COMPLETED
          @successfully_aggregated_at= 2016-10-13T17:57:38+00:00
        >
    >
    

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

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

    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 for that particular member. Partners can poll a particular member using the 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.

    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 and end-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, represented in ISO 8601 format with timestamp (e.g., 2015-04-13T12:01:23-06:00).
    connection_status String This field indicates the state of a member's aggregation, provided as a string. See member connection statuses 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, represented in ISO 8601 format with timestamp (e.g., 2015-04-13T12:01:23-06:00).

    Dealing with a CHALLENGED status

    Example response for read member connection status when the connection_ststus is CHALLENGED:

    {
      "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"
      }
    }
    

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

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

    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

    Example request

    $ curl -i -X GET '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}'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class ReadMemberStatusExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var memberGuid = "MBR-123";  // string | The unique identifier for a `member`.
                var userGuid = "USR-123";  // string | The unique identifier for a `user`.
    
                try
                {
                    // Read member connection status
                    MemberConnectionStatusResponseBody response = client.members.ReadMemberStatus(memberGuid, userGuid);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling MembersApi.ReadMemberStatus: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      memberGUID := "MBR-123" // string | The unique identifier for a `member`.
      userGUID := "USR-123" // string | The unique identifier for a `user`.
    
      response, _, err := client.Members.ReadMemberStatus(ctx, memberGUID, userGUID)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class MembersApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            String memberGuid = "MBR-123"; // String | The unique identifier for a `member`.
            String userGuid = "USR-123"; // String | The unique identifier for a `user`.
    
            try {
                MemberConnectionStatusResponseBody response = client.members.readMemberStatus(memberGuid, userGuid);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling MembersApi#readMemberStatus");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var memberGuid = "MBR-123"; // string | The unique identifier for a `member`.
    var userGuid = "USR-123"; // string | The unique identifier for a `user`.
    
    var response = client.members.readMemberStatus(memberGuid, userGuid);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $member_guid = "MBR-123"; // string | The unique identifier for a `member`.
    $user_guid = "USR-123"; // string | The unique identifier for a `user`.
    
    try {
        $result = $client->members->readMemberStatus($member_guid, $user_guid);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling MembersApi->readMemberStatus: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # str | The unique identifier for a `member`.
    user_guid = "USR-123" # str | The unique identifier for a `user`.
    
    try:
        # Read member connection status
        response = client.members.read_member_status(member_guid, user_guid)
        pprint(response)
    except ApiException as e:
        print("Exception when calling MembersApi->read_member_status: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # String | The unique identifier for a `member`.
    user_guid = "USR-123" # String | The unique identifier for a `user`.
    
    begin
      #Read member connection status
      response = client.members.read_member_status(member_guid, user_guid)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling MembersApi->read_member_status: #{e}"
    end
    

    Example response

    Status: 200 OK
    
    {
      "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"
      }
    }
    
    class MemberConnectionStatusResponseBody {
      Member:
        class MemberConnectionStatus {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: true
          HasProcessedTransactions: false
          IsAuthenticated: true
          IsBeingAggregated: false
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    {
      Member:
        {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: true
          HasProcessedTransactions: false
          IsAuthenticated: true
          IsBeingAggregated: false
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    class MemberConnectionStatusResponseBody {
      member:
        class MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: true
          hasProcessedTransactions: false
          isAuthenticated: true
          isBeingAggregated: false
          status: COMPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    MemberConnectionStatusResponseBody {
      member:
        MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: true
          hasProcessedTransactions: false
          isAuthenticated: true
          isBeingAggregated: false
          status: COMPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    atrium/model/MemberConnectionStatusResponseBody Object (
      [member] =>
        atrium/model/MemberConnectionStatus Object (
          [aggregated_at] => 2016-10-13T18:07:57+00:00
          [connection_status] => CONNECTED
          [guid] => MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          [has_processed_accounts] => true
          [has_processed_transactions] => false
          [is_authenticated] => true
          [is_being_aggregated] => false
          [status] => COMPLETED
          [successfully_aggregated_at] => 2016-10-13T17:57:38+00:00
        )
    )
    
    {
      'member':
        {
          'aggregated_at': 2016-10-13T18:07:57+00:00
          'connection_status': CONNECTED
          'guid': MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          'has_processed_accounts': true
          'has_processed_transactions': false
          'is_authenticated': true
          'is_being_aggregated': false
          'status': COMPLETED
          'successfully_aggregated_at': 2016-10-13T17:57:38+00:00
        }
    }
    
    #<MX::MemberConnectionStatusResponseBody
      @member=
        #<MX::MemberConnectionStatus
          @aggregated_at= 2016-10-13T18:07:57+00:00
          @connection_status= CONNECTED
          @guid= MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          @has_processed_accounts= true
          @has_processed_transactions= false
          @is_authenticated= true
          @is_being_aggregated= false
          @status= COMPLETED
          @successfully_aggregated_at= 2016-10-13T17:57:38+00:00
        >
    >
    

    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 for more information, or consult the documentation on connection statuses for full details on exactly what each status means.

    The following lists represent general guidelines.

    In general, aggregation can be attempted for a member with the following connection statuses:

    In general, you must update credentials before aggregating a member with the following connection statuses:

    The following connection statuses represent a transitory state in an ongoing aggregation process:

    You should not attempt aggregation on a member with the following connection statuses:

    2. Aggregate the member

    Example request

    $ curl -i -X POST 'https://vestibule.mx.com/users/{user_guid}/members/{member_guid}/aggregate' \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {mx_api_key}' \
      -H 'MX-Client-ID: {mx_client_id}'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class AggregateMemberExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var memberGuid = "MBR-123";  // string | The unique identifier for a `member`.
                var userGuid = "USR-123";  // string | The unique identifier for a `user`.
    
                try
                {
                    // Aggregate member
                    MemberResponseBody response = client.members.AggregateMember(memberGuid, userGuid);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling MembersApi.AggregateMember: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      memberGUID := "MBR-123" // string | The unique identifier for a `member`.
      userGUID := "USR-123" // string | The unique identifier for a `user`.
    
      response, _, err := client.Members.AggregateMember(ctx, memberGUID, userGUID)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class MembersApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            String memberGuid = "MBR-123"; // String | The unique identifier for a `member`.
            String userGuid = "USR-123"; // String | The unique identifier for a `user`.
    
            try {
                MemberResponseBody response = client.members.aggregateMember(memberGuid, userGuid);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling MembersApi#aggregateMember");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var memberGuid = "MBR-123"; // string | The unique identifier for a `member`.
    var userGuid = "USR-123"; // string | The unique identifier for a `user`.
    
    var response = client.members.aggregateMember(memberGuid, userGuid);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $member_guid = "MBR-123"; // string | The unique identifier for a `member`.
    $user_guid = "USR-123"; // string | The unique identifier for a `user`.
    
    try {
        $result = $client->members->aggregateMember($member_guid, $user_guid);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling MembersApi->aggregateMember: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # str | The unique identifier for a `member`.
    user_guid = "USR-123" # str | The unique identifier for a `user`.
    
    try:
        # Aggregate member
        response = client.members.aggregate_member(member_guid, user_guid)
        pprint(response)
    except ApiException as e:
        print("Exception when calling MembersApi->aggregate_member: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # String | The unique identifier for a `member`.
    user_guid = "USR-123" # String | The unique identifier for a `user`.
    
    begin
      #Aggregate member
      response = client.members.aggregate_member(member_guid, user_guid)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling MembersApi->aggregate_member: #{e}"
    end
    

    Example response

    Status: 202 Accepted
    
    {
      "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"
      }
    }
    
    class MemberResponseBody {
      Member:
        class Member {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          Identifier: unique_id
          InstitutionCode: mxbank
          IsBeingAggregated: true
          Metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          Name: MX Bank
          Status: INITIATED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          UserGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    {
      Member:
        {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          Identifier: unique_id
          InstitutionCode: mxbank
          IsBeingAggregated: true
          Metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          Name: MX Bank
          Status: INITIATED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          UserGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    class MemberResponseBody {
      member:
        class Member {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          identifier: unique_id
          institutionCode: mxbank
          isBeingAggregated: false
          metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          name: MX Bank
          status: INITIATED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          userGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    MemberResponseBody {
      member:
        Member {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          identifier: unique_id
          institutionCode: mxbank
          isBeingAggregated: true
          metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          name: MX Bank
          status: INITIATED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          userGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    atrium/model/MemberResponseBody Object (
      [member] =>
        atrium/model/Member Object (
          [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
        )
    )
    
    {
      '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
        }
    }
    
    #<MX::MemberResponseBody
      @member=
        #<MX::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
        >
    >
    

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

    3. Check the connection status again

    Example request

    GET /users/{user_guid}/members/{member_guid}/status
    

    Example request

    $ curl -i -X GET '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}'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class ReadMemberStatusExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var memberGuid = "MBR-123";  // string | The unique identifier for a `member`.
                var userGuid = "USR-123";  // string | The unique identifier for a `user`.
    
                try
                {
                    // Read member connection status
                    MemberConnectionStatusResponseBody response = client.members.ReadMemberStatus(memberGuid, userGuid);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling MembersApi.ReadMemberStatus: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      memberGUID := "MBR-123" // string | The unique identifier for a `member`.
      userGUID := "USR-123" // string | The unique identifier for a `user`.
    
      response, _, err := client.Members.ReadMemberStatus(ctx, memberGUID, userGUID)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class MembersApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            String memberGuid = "MBR-123"; // String | The unique identifier for a `member`.
            String userGuid = "USR-123"; // String | The unique identifier for a `user`.
    
            try {
                MemberConnectionStatusResponseBody response = client.members.readMemberStatus(memberGuid, userGuid);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling MembersApi#readMemberStatus");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var memberGuid = "MBR-123"; // string | The unique identifier for a `member`.
    var userGuid = "USR-123"; // string | The unique identifier for a `user`.
    
    var response = client.members.readMemberStatus(memberGuid, userGuid);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $member_guid = "MBR-123"; // string | The unique identifier for a `member`.
    $user_guid = "USR-123"; // string | The unique identifier for a `user`.
    
    try {
        $result = $client->members->readMemberStatus($member_guid, $user_guid);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling MembersApi->readMemberStatus: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # str | The unique identifier for a `member`.
    user_guid = "USR-123" # str | The unique identifier for a `user`.
    
    try:
        # Read member connection status
        response = client.members.read_member_status(member_guid, user_guid)
        pprint(response)
    except ApiException as e:
        print("Exception when calling MembersApi->read_member_status: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # String | The unique identifier for a `member`.
    user_guid = "USR-123" # String | The unique identifier for a `user`.
    
    begin
      #Read member connection status
      response = client.members.read_member_status(member_guid, user_guid)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling MembersApi->read_member_status: #{e}"
    end
    

    Example response

    Status: 200 OK
    
    {
      "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"
      }
    }
    
    class MemberConnectionStatusResponseBody {
      Member:
        class MemberConnectionStatus {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          Challenges: [
            class Challenge {
              FieldName: What city were you born in?
              Guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              Label: What city were you born in?
              Type: TEXT
            }      
          ]
          ConnectionStatus: CHALLENGED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: false
          HasProcessedTransactions: false
          IsBeingAggregated: true
          Status: CHALLENGED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    {
      Member:
        {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          Challenges: [
            {
              FieldName: What city were you born in?
              Guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              Label: What city were you born in?
              Type: TEXT
            }      
          ]
          ConnectionStatus: CHALLENGED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: false
          HasProcessedTransactions: false
          IsBeingAggregated: true
          Status: CHALLENGED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    class MemberConnectionStatusResponseBody {
      member:
        class MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          challenges: [
            class Challenge {
              fieldName: What city were you born in?
              guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              label: What city were you born in?
              type: TEXT
            }      
          ]
          connectionStatus: CHALLENGED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: false
          hasProcessedTransactions: false
          isBeingAggregated: true
          status: CHALLENGED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    MemberConnectionStatusResponseBody {
      member:
        MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          challenges: [
            Challenge {
              fieldName: What city were you born in?
              guid: CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              label: What city were you born in?
              type: TEXT
            }      
          ]
          connectionStatus: CHALLENGED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: false
          hasProcessedTransactions: false
          isBeingAggregated: true
          status: CHALLENGED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    atrium/model/MemberConnectionStatusResponseBody Object (
      [member] =>
        atrium/model/MemberConnectionStatus Object (
          [aggregated_at] => 2016-10-13T18:07:57+00:00
          [challenges] => Array (
            atrium/model/Challenge Object (
              [field_name] => What city were you born in?
              [guid] => CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              [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] => false
          [status] => CHALLENGED
          [successfully_aggregated_at] => 2016-10-13T17:57:38+00:00
        )
    )
    
    {
      'member':
        {
          'aggregated_at': 2016-10-13T18:07:57+00:00
          'challenges': [
            {
              'field_name': What city were you born in?
              'guid': CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              '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-13T17:57:38+00:00
        }
    }
    
    #<MX::MemberConnectionStatusResponseBody
      @member=
        #<MX::MemberConnectionStatus
          @aggregated_at= 2016-10-13T18:07:57+00:00
          @challenges= [
            #<MX::Challenge
              @field_name= What city were you born in?
              @guid= CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5
              @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-13T17:57:38+00:00
        >
    >
    

    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.

    4. Answer MFA with the resume aggregation endpoint

    Example request

    curl -i -X PUT 'https://vestibule.mx.com/users/{user_guid}/members/MBR-69691bf0-fc09-d876-284e-a8ea0165c04f/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": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
                  "value": "Atlanta"
                }
              ]
            }
          }'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class ResumeMemberExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var memberGuid = "MBR-123";  // string | The unique identifier for a `member`.
                var userGuid = "USR-123";  // string | The unique identifier for a `user`.
                var body = new MemberResumeRequestBody(
                  member new MemberResumeRequest(
                    challenges: new List<ChallengeRequest>(){
                      new ChallengeRequest(
                        guid: "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
                        value: "Atlanta"
                      ),
                    }
                  )
                ); // MemberResumeRequestBody | Member object with MFA challenge answers
    
                try
                {
                    // Resume aggregation from MFA
                    MemberResponseBody response = client.members.ResumeMember(memberGuid, userGuid, body);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling MembersApi.ResumeMember: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      memberGUID := "MBR-123" // string | The unique identifier for a `member`.
      userGUID := "USR-123" // string | The unique identifier for a `user`.
      body := atrium.MemberResumeRequestBody{
        Member: &atrium.MemberResumeRequest{
          Challenges: ChallengeRequest{
            &atrium.ChallengeRequest{
              GUID: "CRD-1ec152cd-e628-e81a-e852-d1e7104624da"
              Value: "Atlanta"
            }
          }
        }
      } // MemberResumeRequestBody | Member object with MFA challenge answers
    
      response, _, err := client.Members.ResumeMember(ctx, memberGUID, userGUID, body)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class MembersApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            String memberGuid = "MBR-123"; // String | The unique identifier for a `member`.
            String userGuid = "USR-123"; // String | The unique identifier for a `user`.
            MemberResumeRequestBody body = new MemberResumeRequestBody(); // MemberResumeRequestBody | Member object with MFA challenge answers
    
            try {
                MemberResponseBody response = client.members.resumeMember(memberGuid, userGuid, body);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling MembersApi#resumeMember");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var memberGuid = "MBR-123"; // string | The unique identifier for a `member`.
    var userGuid = "USR-123"; // string | The unique identifier for a `user`.
    var body = new atrium.MemberResumeRequestBody(); // MemberResumeRequestBody | Member object with MFA challenge answers
    
    var response = client.members.resumeMember(memberGuid, userGuid, body);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $member_guid = "MBR-123"; // string | The unique identifier for a `member`.
    $user_guid = "USR-123"; // string | The unique identifier for a `user`.
    $body = new \atrium\model\MemberResumeRequestBody(
      array(
        "member" => new \atrium\model\MemberResumeRequest
          array(
            "challenges"=>array(
              "guid"=>"CRD-f61b2add-df2e-3ac0-b7ee-a7d5cbfad3f7",
              "value"=>"Atlanta"
            )
          )
      )
    ); // \atrium\model\MemberResumeRequestBody | Member object with MFA challenge answers
    
    try {
        $result = $client->members->resumeMember($member_guid, $user_guid, $body);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling MembersApi->resumeMember: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # str | The unique identifier for a `member`.
    user_guid = "USR-123" # str | The unique identifier for a `user`.
    body = atrium.MemberResumeRequestBody(
      member = atrium.MemberResumeRequest(
        challenges = [
          atrium.ChallengesRequest(
            guid = "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
            value = "Atlanta"
            )
          ]
        )
      ) # MemberResumeRequestBody | Member object with MFA challenge answers
    
    try:
        # Resume aggregation from MFA
        response = client.members.resume_member(member_guid, user_guid, body)
        pprint(response)
    except ApiException as e:
        print("Exception when calling MembersApi->resume_member: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # String | The unique identifier for a `member`.
    user_guid = "USR-123" # String | The unique identifier for a `user`.
    body = Atrium::MemberResumeRequestBody.new(
      :member => MemberResumeRequest.new(
        :challenges => [
          ChallengesRequest.new(
          guid => "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
          value => "Atlanta"
            )
          ]
        )
      ) # MemberResumeRequestBody | Member object with MFA challenge answers
    
    begin
      #Resume aggregation from MFA
      response = client.members.resume_member(member_guid, user_guidbody)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling MembersApi->resume_member: #{e}"
    end
    

    Response

    Status: 202 Accepted
    
    {
      "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": "REQUESTED",
        "successfully_aggregated_at": null,
        "user_guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54"
      }
    }
    
    class MemberResponseBody {
      Member:
        class Member {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: RESUMED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          Identifier: unique_id
          InstitutionCode: mxbank
          IsBeingAggregated: true
          Metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          Name: MX Bank
          Status: REQUESTED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          UserGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    {
      Member:
        {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: RESUMED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          Identifier: unique_id
          InstitutionCode: mxbank
          IsBeingAggregated: true
          Metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          Name: MX Bank
          Status: REQUESTED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          UserGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    class MemberResponseBody {
      member:
        class Member {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: RESUMED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          identifier: unique_id
          institutionCode: mxbank
          isBeingAggregated: true
          metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          name: MX Bank
          status: REQUESTED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          userGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    MemberResponseBody {
      member:
        Member {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: RESUMED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          identifier: unique_id
          institutionCode: mxbank
          isBeingAggregated: true
          metadata: {"credentials_last_refreshed_at": "2015-10-15"}
          name: MX Bank
          status: REQUESTED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
          userGuid: USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    atrium/model/MemberResponseBody Object (
      [member] =>
        atrium/model/Member Object (
          [aggregated_at] => 2016-10-13T18:07:57+00: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] => REQUESTED
          [successfully_aggregated_at] => 2016-10-13T17:57:38+00:00
          [user_guid] => USR-fa7537f3-48aa-a683-a02a-b18940482f54
        )
    )
    
    {
      'member':
        {
          'aggregated_at': 2016-10-13T18:07:57+00: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': REQUESTED
          'successfully_aggregated_at': 2016-10-13T17:57:38+00:00
          'user_guid': USR-fa7537f3-48aa-a683-a02a-b18940482f54
        }
    }
    
    #<MX::MemberResponseBody
      @member=
        #<MX::Member
          @aggregated_at= 2016-10-13T18:07:57+00: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= REQUESTED
          @successfully_aggregated_at= 2016-10-13T17:57:38+00:00
          @user_guid= USR-fa7537f3-48aa-a683-a02a-b18940482f54
        >
    >
    

    5. Check the connection status again

    Example request

    GET /users/{user_guid}/members/{member_guid}/status
    

    Example request

    $ curl -i -X GET '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}'
    
    using System;
    using Atrium.Api;
    using Atrium.Model;
    
    namespace Example
    {
        public class ReadMemberStatusExample
        {
            public void main()
            {
                var client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
                var memberGuid = "MBR-123";  // string | The unique identifier for a `member`.
                var userGuid = "USR-123";  // string | The unique identifier for a `user`.
    
                try
                {
                    // Read member connection status
                    MemberConnectionStatusResponseBody response = client.members.ReadMemberStatus(memberGuid, userGuid);
                    Console.WriteLine(response);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception when calling MembersApi.ReadMemberStatus: " + e.Message );
                }
            }
        }
    }
    
    package main
    
    import (
      "context"
      "fmt"
      "github.com/mxenabled/atrium-go"
    )
    
    func main() {
      client := atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
      ctx := context.Background()
    
      memberGUID := "MBR-123" // string | The unique identifier for a `member`.
      userGUID := "USR-123" // string | The unique identifier for a `user`.
    
      response, _, err := client.Members.ReadMemberStatus(ctx, memberGUID, userGUID)
      if err != nil {
        fmt.Printf("Error: %v\n", err)
      } else {
        fmt.Printf("Response: %s\n", response)
      }
    }
    
    import com.mx.atrium.*;
    import com.mx.model.*;
    
    public class MembersApiExample {
        public static void main(String[] args) {
            AtriumClient client = new AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
            String memberGuid = "MBR-123"; // String | The unique identifier for a `member`.
            String userGuid = "USR-123"; // String | The unique identifier for a `user`.
    
            try {
                MemberConnectionStatusResponseBody response = client.members.readMemberStatus(memberGuid, userGuid);
                System.out.println(response);
            } catch (ApiException e) {
                System.err.println("Exception when calling MembersApi#readMemberStatus");
                e.printStackTrace();
            }
        }
    }
    
    var atrium = require('./atrium.js');
    
    var client = new atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID");
    
    var memberGuid = "MBR-123"; // string | The unique identifier for a `member`.
    var userGuid = "USR-123"; // string | The unique identifier for a `user`.
    
    var response = client.members.readMemberStatus(memberGuid, userGuid);
    
    response.then(function(value) {
      console.log(value);
    });
    
    <?php
    require_once(__DIR__ . '/vendor/autoload.php');
    
    $client = new atrium\Api\AtriumClient(
        "YOUR_API_KEY",
        "YOUR_CLIENT_ID",
        new GuzzleHttp\Client()
    );
    
    $member_guid = "MBR-123"; // string | The unique identifier for a `member`.
    $user_guid = "USR-123"; // string | The unique identifier for a `user`.
    
    try {
        $result = $client->members->readMemberStatus($member_guid, $user_guid);
        print_r($result);
    } catch (Exception $e) {
        echo 'Exception when calling MembersApi->readMemberStatus: ', $e->getMessage(), PHP_EOL;
    }
    ?>
    
    from __future__ import print_function
    import time
    import atrium
    from atrium.rest import ApiException
    from pprint import pprint
    
    # create an instance of the AtriumClient
    client = atrium.AtriumClient("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # str | The unique identifier for a `member`.
    user_guid = "USR-123" # str | The unique identifier for a `user`.
    
    try:
        # Read member connection status
        response = client.members.read_member_status(member_guid, user_guid)
        pprint(response)
    except ApiException as e:
        print("Exception when calling MembersApi->read_member_status: %s\n" % e)
    
    # load the gem
    require 'atrium-ruby'
    
    client = Atrium::AtriumClient.new("YOUR_API_KEY", "YOUR_CLIENT_ID")
    
    member_guid = "MBR-123" # String | The unique identifier for a `member`.
    user_guid = "USR-123" # String | The unique identifier for a `user`.
    
    begin
      #Read member connection status
      response = client.members.read_member_status(member_guid, user_guid)
      p response
    rescue Atrium::ApiError => e
      puts "Exception when calling MembersApi->read_member_status: #{e}"
    end
    

    Example response

    Status: 200 OK
    
    {
      "member": {
        "aggregated_at":"2016-10-13T18:24:37+00:00",
        "connection_status": "CONNECTED",
        "guid": "MBR-7c6f361b-e582-15b6-60c0-358f12466b4b",
        "has_processed_accounts": true,
        "has_processed_transactions": true,
        "is_being_aggregated": false,
        "status": "COMPLETED",
        "successfully_aggregated_at": "2016-10-13T18:08:04+00:00"
      }
    }
    
    class MemberConnectionStatusResponseBody {
      Member:
        class MemberConnectionStatus {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: true
          HasProcessedTransactions: true
          IsBeingAggregated: false
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    {
      Member:
        {
          AggregatedAt: 2016-10-13T18:07:57+00:00
          ConnectionStatus: CONNECTED
          Guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          HasProcessedAccounts: true
          HasProcessedTransactions: true
          IsBeingAggregated: false
          Status: COMPLETED
          SuccessfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    class MemberConnectionStatusResponseBody {
      member:
        class MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: true
          hasProcessedTransactions: true
          isBeingAggregated: false
          status: COMEPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    MemberConnectionStatusResponseBody {
      member:
        MemberConnectionStatus {
          aggregatedAt: 2016-10-13T18:07:57+00:00
          connectionStatus: CONNECTED
          guid: MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          hasProcessedAccounts: true
          hasProcessedTransactions: true
          isBeingAggregated: false
          status: COMPLETED
          successfullyAggregatedAt: 2016-10-13T17:57:38+00:00
        }
    }
    
    atrium/model/MemberConnectionStatusResponseBody Object (
      [member] =>
        atrium/model/MemberConnectionStatus Object (
          [aggregated_at] => 2016-10-13T18:07:57+00:00
          [connection_status] => CONNECTED
          [guid] => MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          [has_processed_accounts] => true
          [has_processed_transactions] => true
          [is_being_aggregated] => false
          [status] => COMPLETED
          [successfully_aggregated_at] => 2016-10-13T17:57:38+00:00
        )
    )
    
    {
      'member':
        {
          'aggregated_at': 2016-10-13T18:07:57+00:00
          'connection_status': CONNECTED
          'guid': MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          'has_processed_accounts': true
          'has_processed_transactions': true
          'is_being_aggregated': false
          'status': COMPLETED
          'successfully_aggregated_at': 2016-10-13T17:57:38+00:00
        }
    }
    
    #<MX::MemberConnectionStatusResponseBody
      @member=
        #<MX::MemberConnectionStatus
          @aggregated_at= 2016-10-13T18:07:57+00:00
          @connection_status= CONNECTED
          @guid= MBR-7c6f361b-e582-15b6-60c0-358f12466b4b
          @has_processed_accounts= true
          @has_processed_transactions= true
          @is_being_aggregated= false
          @status= COMPLETED
          @successfully_aggregated_at= 2016-10-13T17:57:38+00:00
        >
    >
    

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

    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, then listing transactions for a specific account.

    Tools to get you running

    The Postman collection below will allow you to start experimenting with Atrium immediately. The GitHub collections below demonstrate recommended workflows.

    Postman

    To easily get up and running, we recommend using Postman to experiment with Atrium. To do so you should:

    1. Download Postman.
    2. Install the Atrium Postman collection as explained here.
    3. Add the following fields and your own values to a new Postman environment as explained here.
      • MX-API-Key
      • MX-Client-ID
      • Accept
      • Content-Type
      • baseURL
      • User
      • Member
      • Account

    Wrapper libraries on GitHub

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

    Testing your setup

    MX provides a test institution in our development environment called MX Bank (institution code: mxbank) to test different aggregation responses. Creating a test member with this institution allows you to use custom credentials to mimic various aggregation workflows.

    For example, you can use MX bank to test a complicated flow such as aggregation with MFA:

    1. Aggregate the test member (or create a new test member)
    2. Poll the member's connection status.
      • With MX Bank, this will return with a challenges object.
    3. Answer the challenge using the resume aggregation endpoint
      • On MX Bank, responding with "value": "challenge" will answer the first question correctly and trigger a follow-up challenge.
    4. Poll the status again.
      • This will return another challenges object.
    5. Answer the second challenge.
      • On MX Bank, answering with "value": "correct" will result in a successful aggregation.
    6. Poll the status until an end state is reached.

    MX also provides dozens of test endpoints to mimic the behavior of other Atrium features and workflows.

    Test credentials for MX Bank

    The test credentials for different situations are as follows:

    Username Password Description
    test_atrium password This mimics successful aggregation with no MFA.
    test_atrium challenge This mimics a text-based MFA challenge. Answer with the word correct to successfully progress through MFA.
    test_atrium options This mimics the "option list" type of MFA challenge. Select "correct" to successfully progress through MFA.
    test_atrium image This mimics the image type of MFA challenge. Answer with the word "correct" to successfully progress through MFA.
    test_atrium BAD_REQUEST This mimics not having a username and password on the member. The member status will go to HALTED.
    test_atrium UNAUTHORIZED This mimics the member having invalid credentials. The member status will go to DENIED.
    test_atrium INVALID This mimics the member having invalid login and/or password fields. The member status will go to DENIED.
    test_atrium LOCKED This mimics a user being locked out of their banking institution. The member status will go to DENIED.
    test_atrium SERVER_ERROR This mimics the financial institution having a server error. The member status will go to HALTED.
    test_atrium UNAVAILABLE This mimics the financial institution having a "service unavailable" error. The member status will go to HALTED.

    Testing with MXBank and OAuth

    You will only be able to test OAuth flows in the integration environment with MX Bank (OAuth) (institution code: mx_bank_oauth).

    When you select MX Bank (OAuth) from search, or load the Connect with it via current_institution_code. You should see the following screen before going to the OAuth provider:

    Then you should end up on this page:

    From here you can simply click "Authorize" to simulate authorizing and success paths, and "Deny" to simulate an error path.

    Test endpoints

    MX provides test endpoints to aid developers in working the flows and other issues with their Atrium integrations. Test endpoints return static data.

    Certain endpoints can take a connection_status string as a URL parameter in place of the typical GUID. This will return a member in the state corresponding to the given connection_status.

    Connection status definitions

    Connection status id (integer) Connection status (string) Definition Next steps End-user message
    null null The member exists but does not have credentials. None. None.
    0 CREATED The member is new and has not yet been aggregated. Aggregate the member once the end user logs in; poll for a status update. Connecting to {...} ...
    1 PREVENTED MX is preventing aggregation until the member’s credentials have been updated. Display end-user message; after end user has updated their credentials, aggregate again. The last 3 attempts to connect have failed. Please re-enter your credentials to continue importing data.
    2 DENIED The credentials provided for the member were invalid. Display end-user message; after end user has updated their credentials, aggregate again. The credentials entered do not match your credentials at this institution. Please re-enter your credentials to continue importing data.
    3 CHALLENGED The member has been challenged by multi-factor authentication. Display end-user message; follow MFA pathway; after the user answers MFA, poll for a status update. To authenticate your connection to {...}, please answer the following challenge(s).
    4 REJECTED An MFA challenge was answered incorrectly. Display end-user message; another challenge may follow or aggregation may need to be restarted. The answer or answers provided were incorrect. Please try again.
    5 LOCKED The financial institution is preventing authentication. The end user must contact the financial institution. Display end-user message. Your account is locked. Please log in to the appropriate website for {...} and follow the steps to resolve the issue.
    6 CONNECTED The member was successfully authenticated and data is now aggregating. Display the account as having been connected. Connected to [...] ...
    7 IMPEDED The end user’s attention is required at their online banking institution, e.g., there is a marketing message that must be viewed, terms and conditions that must be accepted, etc. Display end-user message. Your attention is needed at this institution's website. Please log in to the appropriate website for {...} and follow the steps to resolve the issue.
    8 RECONNECTED The member has been migrated to a new data source and aggregation is likely to trigger one-time password MFA. MX will not perform background aggregation in order to avoid unnecessarily disruptive texts, emails, etc. The member must be re-aggregated in the foreground with the end user present. Aggregate the member once the end user logs in; poll for a status update. Reconnecting to {...} ...
    9 DEGRADED Aggregation has failed at least three times within a short period of time. Display end-user message. We are upgrading this connection. Please try again later.
    10 DISCONNECTED Aggregation has failed at least three times and has not succeeded for at least two weeks. Display end-user message. It looks like your data from {...} cannot be imported. We are working to resolve the issue.
    11 DISCONTINUED The connection to this financial institution is no longer available. Display end-user message. Connections to this institution are no longer supported. You may create a manual account and use manual transactions to track data for this account.
    12 CLOSED The end user, MX, the client, or a partner has marked the member as closed. Display end-user message. This connection has been closed. You may track this account manually. If reopened, you may connect the institution again.
    13 DELAYED Aggregating the member has taken longer than expected and it has not yet been connected. Display end-user message; poll for a status update. Importing your data from {...} may take a while. Please check back later.
    14 FAILED Aggregation failed without being connected. Display end-user message; try aggregating again later. There was a problem validating your credentials with {...}. Please try again later.
    15 UPDATED The member has been updated — i.e., credentials have been updated — but it has not yet been connected. Aggregate the member once the end user logs in; poll for a status update. Connecting to {...} ...
    16 DISABLED Aggregation has been momentarily paused, but the member is still connected. Display end-user message. Importing data from this institution has been disabled. Please contact us if you believe it has been disabled in error.
    17 IMPORTED MX does not have credentials and will not try to aggregate the member until the end user provides credentials. Display end-user message; re-aggregate after the end user updates credentials. You must re-authenticate before your data can be imported. Please enter your credentials for {...}.
    18 RESUMED The answer to an MFA challenge was received, but it is not yet clear whether it was correct. Poll for a status update. Connecting to {...} ...
    19 EXPIRED The MFA answer was not provided within the time allotted by the financial institution. Display end-user message; re-aggregate the member if the end user initiates it. The answer or answers were not provided in time. Please try again.
    20 IMPAIRED The member is missing some or all credentials needed in order to connect. Display end-user message; re-aggregate after the end user updates credentials. You must re-authenticate before your data can be imported. Please enter your credentials for {...}.
    21 PENDING The member is using OAuth to authenticate credentials and still needs to go through the financial institution's OAuth process. A PENDING status will appear only on members less than one hour old with is_oauth: true. Members that stay PENDING longer than one hour will be deleted by MX. Redirect the end user to the oauth_window_uri provided in the create member response, or request one through the generate OAuth window URI endpoint. None.

    Accounts

    List accounts for a member

    Endpoint: GET /users/test_atrium/members/test_atrium_member/accounts

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/accounts \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "accounts": [
        {
          "account_number": null,
          "apr": null,
          "apy": null,
          "available_balance": 2263.28,
          "available_credit": null,
          "balance": 2263.28,
          "cash_balance": null,
          "cash_surrender_value": null,
          "created_at": "2017-03-02T17:50:03Z",
          "credit_limit": null,
          "currency_code": null,
          "day_payment_is_due": null,
          "death_benefit": null,
          "guid": "ACT-7129bwf4-b583-cee5-31e5-36d5e3db238c",
          "holdings_value": null,
          "institution_code": "chase",
          "interest_rate": null,
          "is_closed": false,
          "last_payment": null,
          "last_payment_at": null,
          "loan_amount": null,
          "matures_on": null,
          "member_guid": "test_atrium_member",
          "minimum_balance": null,
          "minimum_payment": null,
          "name": "Checking 10261",
          "original_balance": null,
          "payment_due_at": null,
          "payoff_balance": null,
          "started_on": null,
          "subtype": "PERSONAL",
          "total_account_value": null,
          "type": "CHECKING",
          "updated_at": "2019-01-08T17:24:13Z",
          "user_guid": "test_atrium"
        },
        {
          "account_number": "4390657065347709",
          "apr": null,
          "apy": null,
          "available_balance": null,
          "available_credit": 10342.81,
          "balance": 10342.81,
          ...
        },
        ...
      ],
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 6,
        "total_pages": 1
      }
    }
    

    Main docs.

    List accounts for a user

    Endpoint: /users/test_atrium/accounts`

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/accounts \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "accounts": [
        {
          "account_number": null,
          "apr": null,
          "apy": null,
          "available_balance": 2263.28,
          "available_credit": null,
          "balance": 2263.28,
          "cash_balance": null,
          "cash_surrender_value": null,
          "created_at": "2017-03-02T17:50:03Z",
          "credit_limit": null,
          "currency_code": null,
          "day_payment_is_due": null,
          "death_benefit": null,
          "guid": "ACT-7129bwf4-b583-cee5-31e5-36d5e3db238c",
          "holdings_value": null,
          "institution_code": "chase",
          "interest_rate": null,
          "is_closed": false,
          "last_payment": null,
          "last_payment_at": null,
          "loan_amount": null,
          "matures_on": null,
          "member_guid": "test_atrium_member",
          "minimum_balance": null,
          "minimum_payment": null,
          "name": "Checking 10261",
          "original_balance": null,
          "payment_due_at": null,
          "payoff_balance": null,
          "started_on": null,
          "subtype": "PERSONAL",
          "total_account_value": null,
          "type": "CHECKING",
          "updated_at": "2019-01-08T17:24:13Z",
          "user_guid": "test_atrium"
        },
        {
          "account_number": "4390657065347709",
          "apr": null,
          "apy": null,
          "available_balance": null,
          "available_credit": 10342.81,
          "balance": 10342.81,
          "cash_balance": null,
          "cash_surrender_value": 2000,
          "created_at": "2018-02-05T14:12:13Z",
          "credit_limit": null,
          ...
        },
        ...
      ],
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 6,
        "total_pages": 1
      }
    }
    

    Main docs.

    Read an account

    Endpoint: GET /users/test_atrium/accounts/test_atrium_account

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/accounts/test_atrium_account \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "account": {
        "account_number": null,
        "apr": null,
        "apy": null,
        "available_balance": 2263.28,
        "available_credit": null,
        "balance": 2263.28,
        "cash_balance": null,
        "cash_surrender_value": null,
        "created_at": "2017-03-02T17:50:03Z",
        "credit_limit": null,
        "currency_code": null,
        "day_payment_is_due": null,
        "death_benefit": null,
        "guid": "ACT-7129bwf4-b583-cee5-31e5-36d5e3db238c",
        "holdings_value": null,
        "institution_code": "chase",
        "interest_rate": null,
        "is_closed": false,
        "last_payment": null,
        "last_payment_at": null,
        "loan_amount": null,
        "matures_on": null,
        "member_guid": "test_atrium_member",
        "minimum_balance": null,
        "minimum_payment": null,
        "name": "Checking 10261",
        "original_balance": null,
        "payment_due_at": null,
        "payoff_balance": null,
        "started_on": null,
        "subtype": "PERSONAL",
        "total_account_value": null,
        "type": "CHECKING",
        "updated_at": "2019-01-08T17:24:13Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    MX Connect

    Create an MX Connect URL

    Endpoint: POST /users/test_atrium/connect_widget_url

    Example request:

    curl -i -X POST 'https://vestibule.mx.com/users/test_atrium/connect_widget_url' \
      -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}'
    

    Example response:

    {
      "user": {
        "connect_widget_url": "https://int-widgets.moneydesktop.com/md/connect/342tbkx5ybdvdh67dc3yd2g1w7Z7kkAj4cmhjcpttcvAx5k0h92zA/eyJ1aV9tZXNzYWdlX3ZlcnNpb24iOjEsInVpX21lc3NhZ2Vfd2Vidmlld191cmxfc2NoZW1lIjoiYXRyaXVtIiwiY3VycmVudF9pbnN0aXR1dGlvbl9jb2RlIjoibXhiYW5rIiwiY3VycmVudF9tZW1iZXJfZ3VpZCI6InRlc3RfYXRyaXVtX21lbWJlciIsImlzX21vYmlsZV93ZWJ2aWV3Ijp0cnVlLCJ1cGRhdGVfY3JlZGVudGlhbHMiOiIifQ%3D%3D",
        "guid": "test_atrium"
      }
    }
    

    Main docs.

    Holdings

    List holdings for a user

    Endpoint: GET /users/test_atrium/holdings

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/holdings \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "holdings": [
        {
          "account_guid": "ACT-d65683e8-9eab-26bb-bcfd-ced159c9abe2",
          "cost_basis": 676,
          "created_at": "2015-04-13T18:01:23Z",
          "currency_code": "USD",
          "cusip": "18383M878",
          "daily_change": 2.5,
          "description": "Guggenheim Defensive Equity ETF",
          "external_guid": null,
          "guid": "HOL-d65683e8-9eab-26bb-bcfd-ced159c9abe2",
          "holding_type": "MONEY_MARKET",
          "market_value": 899.5,
          "member_guid": "test_atrium_member",
          "metadata": null,
          "purchase_price": 26.3,
          "shares": 6,
          "symbol": "DEF",
          "updated_at": "2015-04-13T18:01:23Z",
          "user_guid": "test_atrium"
        },
        {
          "account_guid": "ACT-17u7f41q-cwie-0f6e-5271-01f12w70enk2",
          "cost_basis": 354,
          "created_at": "2016-02-19T13:05:17Z",
          "currency_code": "USD",
          "cusip": "922906201",
          "daily_change": 2.1,
          "description": "Vanguard Prime Money Market Fund",
          "external_guid": null,
          "guid": "HOL-342e7f0f-15ad-4f71-92d8-6424c3400e8c",
          "holding_type": "MONEY_MARKET",
          "market_value": 243.5,
          "member_guid": "test_atrium_member",
          "metadata": null,
          "purchase_price": 89.4,
          "shares": 29,
          "symbol": "VMMXX",
          "updated_at": "2016-02-19T13:05:17Z",
          "user_guid": "test_atrium"
        }
      ],
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 2,
        "total_pages": 1
      }
    }
    

    Main docs.

    List holdings for a member

    Endpoint: GET /users/test_atrium/members/test_atrium_members/holdings

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/holdings \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "holdings": [
        {
          "account_guid": "ACT-d65683e8-9eab-26bb-bcfd-ced159c9abe2",
          "cost_basis": 676,
          "created_at": "2015-04-13T18:01:23Z",
          "currency_code": "USD",
          "cusip": "18383M878",
          "daily_change": 2.5,
          "description": "Guggenheim Defensive Equity ETF",
          "external_guid": null,
          "guid": "HOL-d65683e8-9eab-26bb-bcfd-ced159c9abe2",
          "holding_type": "MONEY_MARKET",
          "market_value": 899.5,
          "member_guid": "test_atrium_member",
          "metadata": null,
          "purchase_price": 26.3,
          "shares": 6,
          "symbol": "DEF",
          "updated_at": "2015-04-13T18:01:23Z",
          "user_guid": "test_atrium"
        },
        {
          "account_guid": "ACT-17u7f41q-cwie-0f6e-5271-01f12w70enk2",
          "cost_basis": 354,
          "created_at": "2016-02-19T13:05:17Z",
          "currency_code": "USD",
          "cusip": "922906201",
          "daily_change": 2.1,
          "description": "Vanguard Prime Money Market Fund",
          "external_guid": null,
          "guid": "HOL-342e7f0f-15ad-4f71-92d8-6424c3400e8c",
          "holding_type": "MONEY_MARKET",
          "market_value": 243.5,
          "member_guid": "test_atrium_member",
          "metadata": null,
          "purchase_price": 89.4,
          "shares": 29,
          "symbol": "VMMXX",
          "updated_at": "2016-02-19T13:05:17Z",
          "user_guid": "test_atrium"
        }
      ],
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 2,
        "total_pages": 1
      }
    }
    

    Main docs.

    List holdings for an account

    Endpoint: GET /users/test_atrium/accounts/test_atrium_account/holdings

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/accounts/test_atrium_account/holdings \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "holdings": [
        {
          "account_guid": "ACT-d65683e8-9eab-26bb-bcfd-ced159c9abe2",
          "cost_basis": 676,
          "created_at": "2015-04-13T18:01:23Z",
          "currency_code": "USD",
          "cusip": "18383M878",
          "daily_change": 2.5,
          "description": "Guggenheim Defensive Equity ETF",
          "external_guid": null,
          "guid": "HOL-d65683e8-9eab-26bb-bcfd-ced159c9abe2",
          "holding_type": "MONEY_MARKET",
          "market_value": 899.5,
          "member_guid": "test_atrium_member",
          "metadata": null,
          "purchase_price": 26.3,
          "shares": 6,
          "symbol": "DEF",
          "updated_at": "2015-04-13T18:01:23Z",
          "user_guid": "test_atrium"
        },
        {
          "account_guid": "ACT-17u7f41q-cwie-0f6e-5271-01f12w70enk2",
          "cost_basis": 354,
          "created_at": "2016-02-19T13:05:17Z",
          "currency_code": "USD",
          "cusip": "922906201",
          "daily_change": 2.1,
          "description": "Vanguard Prime Money Market Fund",
          "external_guid": null,
          "guid": "HOL-342e7f0f-15ad-4f71-92d8-6424c3400e8c",
          "holding_type": "MONEY_MARKET",
          "market_value": 243.5,
          "member_guid": "test_atrium_member",
          "metadata": null,
          "purchase_price": 89.4,
          "shares": 29,
          "symbol": "VMMXX",
          "updated_at": "2016-02-19T13:05:17Z",
          "user_guid": "test_atrium"
        }
      ],
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 2,
        "total_pages": 1
      }
    }
    

    Main docs.

    Read a holding

    Endpoint: GET /users/test_atrium/holdings/test_atrium_holding

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/holdings/test_atrium_holding \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "holding": {
        "account_guid": "ACT-d65683e8-9eab-26bb-bcfd-ced159c9abe2",
        "cost_basis": 676,
        "created_at": "2015-04-13T18:01:23Z",
        "currency_code": "USD",
        "cusip": "18383M878",
        "daily_change": 2.5,
        "description": "Guggenheim Defensive Equity ETF",
        "external_guid": null,
        "guid": "HOL-d65683e8-9eab-26bb-bcfd-ced159c9abe2",
        "holding_type": "MONEY_MARKET",
        "market_value": 899.5,
        "member_guid": "test_atrium_member",
        "metadata": null,
        "purchase_price": 26.3,
        "shares": 6,
        "symbol": "DEF",
        "updated_at": "2015-04-13T18:01:23Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    Institutions

    List institutions

    Endpoint: GET /test_institutions

    Example request:

    curl -X GET \
      https://vestibule.mx.com/test_institutions \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "institutions": [
        {
          "code": "mxbank",
          "medium_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png",
          "name": "MX Bank",
          "small_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png",
          "supports_account_identification": false,
          "supports_account_statement": false,
          "supports_account_verification": false,
          "supports_transaction_history": false,
          "url": "https://www.mx.com"
        },
        {
          "code": "chase",
          "medium_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png",
          "name": "Chase Bank",
          "small_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png",
          "supports_account_identification": true,
          "supports_account_statement": true,
          "supports_account_verification": true,
          "supports_transaction_history": true,
          "url": "https://www.chase.com"
        }
      ],
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 2,
        "total_pages": 1
      }
    }
    

    Main docs.

    List institution credentials

    Endpoint: GET /institutions/test_mxbank/credentials

    Example request:

    curl -X GET \
      https://vestibule.mx.com/institutions/test_mxbank/credentials \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "credentials": [
        {
          "display_order": 1,
          "field_name": "LOGIN",
          "guid": "CRD-9f61fb4c-912c-bd1e-b175-ccc7f0275cc1",
          "label": "Username",
          "type": "LOGIN"
        },
        {
          "display_order": 2,
          "field_name": "PASSWORD",
          "guid": "CRD-e3d7ea81-aac7-05e9-fbdd-4b493c6e474d",
          "label": "Password",
          "type": "PASSWORD"
        }
      ]
    }
    

    Main docs.

    Read an institution

    Endpoint: GET /institutions/test_mxbank

    Example request:

    curl -X GET \
      https://vestibule.mx.com/institutions/test_mxbank \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "institution": {
        "code": "mxbank",
        "medium_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/100x100/default_100x100.png",
        "name": "MX Bank",
        "small_logo_url": "https://content.moneydesktop.com/storage/MD_Assets/Ipad%20Logos/50x50/default_50x50.png",
        "supports_account_identification": false,
        "supports_account_statement": false,
        "supports_account_verification": false,
        "supports_transaction_history": false,
        "url": "https://www.mx.com"
      }
    }
    

    Main docs.

    Identification

    Identify

    Endpoint: POST /users/test_atrium/members/test_atrium_member/identify

    Example request:

    curl -i -X POST 'https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/identify' \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {mx_api_key}' \
      -H 'MX-Client-ID: {mx_client_id}'
    

    Example response:

    {
      "member": {
        "aggregated_at": "2019-09-03T20:49:43Z",
        "connection_status": "CONNECTED",
        "guid": "test_atrium_member",
        "identifier": "unique_id",
        "institution_code": "chase",
        "is_being_aggregated": false,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "INITIATED",
        "successfully_aggregated_at": "2019-09-03T20:49:43Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    Read account owners

    Endpoint: /users/test_atrium/members/test_atrium_member/account_owners

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/account_owners \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "account_owners": [
        {
          "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1",
          "address": "123 This Way",
          "city": "Middlesex",
          "country": "US",
          "email": "donnie@darko.co",
          "guid": "ACO-rt24667y1-36bp-q632-k03v-w62362509w15",
          "member_guid": "test_atrium_member",
          "owner_name": "Donnie Darko",
          "phone": "555-555-5555",
          "postal_code": "00000-0000",
          "state": "VA",
          "user_guid": "test_atrium"
        }
      ]
    }
    

    Main docs.

    Members

    Create a member

    Endpoint: POST /users/test_atrium/members

    Example request:

    curl -X POST \
      https://vestibule.mx.com/users/test_atrium/members \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'Content-Type: application/json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}' \
      -d '{
      "member": {
        "credentials": [
          {
            "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
            "value": "ExampleUsername"
          },
          {
            "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da",
            "value": "Pa$$vv@Rd"
          }
        ],
        "institution_code": "chase"
      }
    }'
    

    Example response:

    {
      "member": {
        "aggregated_at": "2019-08-28T16:23:32Z",
        "connection_status": "CONNECTED",
        "guid": "test_atrium_member",
        "identifier": "unique_id",
        "institution_code": "chase",
        "is_being_aggregated": false,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "INITIATED",
        "successfully_aggregated_at": "2019-08-28T16:23:32Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    List members

    Endpoint: GET /users/test_atrium/members/

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/ \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
        "members": [
            {
                "aggregated_at": "2019-08-28T16:08:46Z",
                "connection_status": "CONNECTED",
                "identifier": "unique_id",
                "status": "INITIATED",
                "successfully_aggregated_at": "2019-08-28T16:08:46Z",
                "guid": "test_atrium_member",
                "institution_code": "chase",
                "is_being_aggregated": false,
                "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
                "name": "Chase Bank",
                "user_guid": "test_atrium"
            }
        ],
        "pagination": {
            "current_page": 1,
            "per_page": 25,
            "total_entries": 1,
            "total_pages": 1
        }
    }
    

    Main docs.

    Read a member

    Endpoint: GET /users/test_atrium/members/test_atrium_member or

    Endpoint: GET /users/test_atrium/members/{connection_status}

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "member": {
        "aggregated_at": "2019-08-28T16:32:35Z",
        "connection_status": "CONNECTED",
        "guid": "test_atrium_member",
        "identifier": "unique_id",
        "institution_code": "chase",
        "is_being_aggregated": false,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "COMPLETED",
        "successfully_aggregated_at": "2019-08-28T16:32:35Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    This endpoint will return a test member in a state corresponding to the connection_status passed in the URL where a member_guid would typically go. Using the GUID test_atrium_member will return a member with the status CONNECTED.

    Update a member

    Endpoint: PUT /users/test_atrium/members/test_atrium_member or

    Endpoint: PUT /users/test_atrium/members/{connection_status}

    Example request:

    curl -X PUT \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'Content-Type: application/json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}' \
      -d '{
      "member": {
        "credentials": [
          {
            "guid": "CRD-598ec8d4-6200-8cda-345d-3dbb5fc17716",
            "value": "updated-username"
          },
          {
            "guid": "CRD-27d0edb8-1d50-5b90-bcbc-be270ca42b9f",
            "value": "updated-password"
          }
        ],
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-16\"}"
      }
    }'
    

    Example response:

    {
      "member": {
        "aggregated_at": "2019-08-28T17:25:56Z",
        "connection_status": "CONNECTED",
        "guid": "test_atrium_member",
        "identifier": "unique_id",
        "institution_code": "chase",
        "is_being_aggregated": false,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "INITIATED",
        "successfully_aggregated_at": "2019-08-28T17:25:56Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    This endpoint will return a test member in a state corresponding to the connection_status passed in the URL where a member_guid would typically go. Using the GUID test_atrium_member will return a member with the status CONNECTED.

    Delete a member

    Endpoint: DELETE /users/test_atrium/members/test_atrium_member

    Example request:

    curl -X DELETE \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    204 No Content
    

    Main docs.

    Aggregate a member

    Endpoint: POST /users/test_atrium/members/:connection_status/aggregate

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/atrium \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "member": {
        "aggregated_at": "2019-08-28T16:32:35Z",
        "connection_status": "CONNECTED",
        "guid": "test_atrium_member",
        "identifier": "unique_id",
        "institution_code": "chase",
        "is_being_aggregated": false,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "COMPLETED",
        "successfully_aggregated_at": "2019-08-28T16:32:35Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    This endpoint will return a test member in a state corresponding to the connection_status passed in the URL where a member_guid would typically go. Using the GUID test_atrium_member will return a member with the status CONNECTED.

    Read a member's connection status

    Endpoint: GET /users/test_atrium/members/:connection_status/status

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/challenged/status \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "member": {
        "aggregated_at": "2019-08-28T22:41:15Z",
        "connection_status": "CHALLENGED",
        "guid": "test_atrium_member",
        "has_processed_accounts": true,
        "has_processed_transactions": false,
        "is_being_aggregated": false,
        "status": "COMPLETED",
        "successfully_aggregated_at": "2019-08-28T22:41:15Z"
      }
    }
    

    Main docs.

    This endpoint will return a test member in a state corresponding to the connection_status passed in the URL where a member_guid would typically go. Using the GUID test_atrium_member will return a member with the status CONNECTED.

    Read a member's MFA challenges

    Endpoint: GET /users/test_atrium/members/:challenge_type/challenges

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/options/challenges \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "challenges": [
        {
          "field_name": "One time passcode",
          "guid": "CRD-ce76d2e3-86bd-ec4a-ec52-eb53b5194bf5",
          "label": "Where should we send your one time passcode?",
          "options": [
            {
              "label": "OPTION0",
              "value": "OPTION0"
            },
            {
              "label": "OPTION1",
              "value": "OPTION1"
            },
            {
              "label": "OPTION2",
              "value": "OPTION2"
            }
          ],
          "type": "OPTIONS"
        }
      ]
    }
    

    This endpoint takes one of four URL parameters which return three different types of MFA challenges: text, options, image, and image_options.

    Main docs.

    Resume aggregation from MFA

    Endpoint: PUT /users/test_atrium/members/test_atrium_member/resume

    Example request:

    curl -X PUT \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/resume \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'Content-Type: application/json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}' \
      -d '{
      "member": {
        "challenges": [
          {
            "guid": "institution-credential-guid",
            "value": "user-entered-value"
          },
          {
            "guid": "institution-credential-guid",
            "value": "user-entered-value"
          }
        ]
      }
    }'
    

    Example response:

    {
      "member": {
        "aggregated_at": "2019-09-03T15:52:26Z",
        "connection_status": "RESUMED",
        "guid": "test_atrium_member",
        "identifier": "unique_id",
        "institution_code": "chase",
        "is_being_aggregated": false,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "REQUESTED",
        "successfully_aggregated_at": "2019-09-03T15:52:26Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    List a member's credentials

    Endpoint: GET /users/test_atrium/members/test_atrium_member/credentials

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/credentials \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "credentials": [
        {
          "display_order": 1,
          "field_name": "LOGIN",
          "guid": "CRD-9f61fb4c-912c-bd1e-b175-ccc7f0275cc1",
          "label": "Username",
          "type": "LOGIN"
        },
        {
          "display_order": 2,
          "field_name": "PASSWORD",
          "guid": "CRD-e3d7ea81-aac7-05e9-fbdd-4b493c6e474d",
          "label": "Password",
          "type": "PASSWORD"
        }
      ]
    }
    

    Main docs.

    List a member's accounts

    Endpoint: GET /users/test_atrium/members/test_atrium_member/accounts

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/accounts \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "accounts": [
        {
          "account_number": null,
          "apr": null,
          "apy": null,
          "available_balance": 2263.28,
          "available_credit": null,
          "balance": 2263.28,
          "cash_balance": null,
          "cash_surrender_value": null,
          "created_at": "2017-03-02T17:50:03Z",
          "credit_limit": null,
          "currency_code": null,
          "day_payment_is_due": null,
          "death_benefit": null,
          "guid": "ACT-7129bwf4-b583-cee5-31e5-36d5e3db238c",
          "holdings_value": null,
          "institution_code": "chase",
          "interest_rate": null,
          "is_closed": false,
          "last_payment": null,
          "last_payment_at": null,
          "loan_amount": null,
          "matures_on": null,
          "member_guid": "test_atrium_member",
          "minimum_balance": null,
          "minimum_payment": null,
          "name": "Checking 10261",
          "original_balance": null,
          "payment_due_at": null,
          "payoff_balance": null,
          "started_on": null,
          "subtype": "PERSONAL",
          "total_account_value": null,
          "type": "CHECKING",
          "updated_at": "2019-01-08T17:24:13Z",
          "user_guid": "test_atrium"
        },
        {
          "account_number": "4390657065347709",
          "apr": null,
          "apy": null,
          "available_balance": null,
          "available_credit": 10342.81,
          "balance": 10342.81,
          "cash_balance": null,
          ...
        }
      ],
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 6,
        "total_pages": 1
      }
    }
    

    Main docs.

    List a member's transactions

    Endpoint: GET /users/test_atrium/members/test_atrium_member/transactions

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/transactions \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 2,
        "total_pages": 1
      },
      "transactions": [
        {
          "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1",
          "amount": 61.11,
          "category": "Groceries",
          "check_number": 1234,
          "check_number_string": "1234",
          "created_at": "2016-10-06T09:43:42Z",
          "currency_code": "USD",
          "date": "2013-09-23",
          "description": "Whole Foods",
          "guid": "TRN-265abee9-889b-af6a-c69b-25157db2bdd9",
          "is_bill_pay": false,
          "is_direct_deposit": false,
          "is_expense": true,
          "is_fee": false,
          "is_income": false,
          "is_international": false,
          "is_overdraft_fee": false,
          "is_payroll_advance": false,
          "latitude": -43.2075,
          "longitude": 139.691706,
          "member_guid": "test_atrium_member",
          "memo": null,
          "merchant_category_code": 5411,
          "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b",
          "original_description": "WHOLEFDS TSQ 102",
          "posted_at": "2016-10-07T06:00:00Z",
          "status": "POSTED",
          "top_level_category": "Food & Dining",
          "transacted_at": "2016-10-06T13:00:00Z",
          "type": "DEBIT",
          "updated_at": "2016-10-07T05:49:12Z",
          "user_guid": "test_atrium"
        },
        {
          "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1",
          "amount": 23.4,
          "category": "Books",
          "check_number": 15234,
          "check_number_string": "15234",
          "created_at": "2016-08-26T09:43:42Z",
          "currency_code": "USD",
          "date": "2013-09-23",
          "description": "Audible",
          "guid": "TRN-265abee9-889b-af6a-c69b-25157db2bdd9",
          "is_bill_pay": false,
          "is_direct_deposit": false,
          "is_expense": true,
          "is_fee": false,
          "is_income": false,
          "is_international": false,
          "is_overdraft_fee": false,
          "is_payroll_advance": false,
          "latitude": -43.2075,
          "longitude": 139.691706,
          "member_guid": "test_atrium_member",
          "memo": null,
          "merchant_category_code": 5411,
          "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b",
          "original_description": "AUDIBLEBKS",
          "posted_at": "2016-08-27T06:00:00Z",
          "status": "POSTED",
          "top_level_category": "Entertainment",
          "transacted_at": "2016-08-26T13:00:00Z",
          "type": "DEBIT",
          "updated_at": "2016-08-27T05:49:12Z",
          "user_guid": "test_atrium"
        }
      ]
    }
    

    Main docs.

    Merchants

    Read a merchant

    Endpoint: GET /merchants/test_atrium_merchant

    Example request:

    curl -X GET \
      https://vestibule.mx.com/merchants/test_atrium_merchant \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "merchant": {
        "created_at": "2017-04-20T19:30:12Z",
        "guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b",
        "logo_url": "https://s3.amazonaws.com/MD_Assets/merchant_logos/comcast.png",
        "name": "Comcast",
        "updated_at": "2018-09-28T21:13:53Z",
        "website_url": "https://www.xfinity.com"
      }
    }
    

    Main docs.

    Extended history

    Extend transaction history

    Endpoint: POST /users/test_atrium/members/test_atrium_member/extend_history

    Example request:

    curl -i -X POST 'https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/extend_history' \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {mx_api_key}' \
      -H 'MX-Client-ID: {mx_client_id}'
    

    Example response:

    {
      "member": {
        "aggregated_at": "2019-09-03T20:41:17Z",
        "connection_status": "CONNECTED",
        "guid": "test_atrium_member",
        "identifier": "unique_id",
        "institution_code": "chase",
        "is_being_aggregated": false,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "INITIATED",
        "successfully_aggregated_at": "2019-09-03T20:41:17Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    Transactions

    List transactions for a user

    Endpoint: GET /users/test_atrium/transactions

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/transactions \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 2,
        "total_pages": 1
      },
      "transactions": [
        {
          "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1",
          "amount": 61.11,
          "category": "Groceries",
          "check_number": 1234,
          "check_number_string": "1234",
          "created_at": "2016-10-06T09:43:42Z",
          "currency_code": "USD",
          "date": "2013-09-23",
          "description": "Whole Foods",
          "guid": "TRN-265abee9-889b-af6a-c69b-25157db2bdd9",
          "is_bill_pay": false,
          "is_direct_deposit": false,
          "is_expense": true,
          "is_fee": false,
          "is_income": false,
          "is_international": false,
          "is_overdraft_fee": false,
          "is_payroll_advance": false,
          "latitude": -43.2075,
          "longitude": 139.691706,
          "member_guid": "test_atrium_member",
          "memo": null,
          "merchant_category_code": 5411,
          "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b",
          "original_description": "WHOLEFDS TSQ 102",
          "posted_at": "2016-10-07T06:00:00Z",
          "status": "POSTED",
          "top_level_category": "Food & Dining",
          "transacted_at": "2016-10-06T13:00:00Z",
          "type": "DEBIT",
          "updated_at": "2016-10-07T05:49:12Z",
          "user_guid": "test_atrium"
        },
        {
          "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1",
          "amount": 23.4,
          "category": "Books",
          "check_number": 15234,
          "check_number_string": "15234",
          "created_at": "2016-08-26T09:43:42Z",
          "currency_code": "USD",
          "date": "2013-09-23",
          "description": "Audible",
          "guid": "TRN-265abee9-889b-af6a-c69b-25157db2bdd9",
          "is_bill_pay": false,
          "is_direct_deposit": false,
          "is_expense": true,
          "is_fee": false,
          "is_income": false,
          "is_international": false,
          "is_overdraft_fee": false,
          "is_payroll_advance": false,
          "latitude": -43.2075,
          "longitude": 139.691706,
          "member_guid": "test_atrium_member",
          "memo": null,
          "merchant_category_code": 5411,
          "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b",
          "original_description": "AUDIBLEBKS",
          "posted_at": "2016-08-27T06:00:00Z",
          "status": "POSTED",
          "top_level_category": "Entertainment",
          "transacted_at": "2016-08-26T13:00:00Z",
          "type": "DEBIT",
          "updated_at": "2016-08-27T05:49:12Z",
          "user_guid": "test_atrium"
        }
      ]
    }
    

    Main docs.

    Read a transaction

    Endpoint: GET /users/test_atrium/transactions/test_atrium_transaction

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/transactions/test_atrium_transaction \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "transaction": {
        "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1",
        "amount": 61.11,
        "category": "Groceries",
        "check_number": 1234,
        "check_number_string": "1234",
        "created_at": "2016-10-06T09:43:42Z",
        "currency_code": "USD",
        "date": "2013-09-23",
        "description": "Whole Foods",
        "guid": "TRN-265abee9-889b-af6a-c69b-25157db2bdd9",
        "is_bill_pay": false,
        "is_direct_deposit": false,
        "is_expense": true,
        "is_fee": false,
        "is_income": false,
        "is_international": false,
        "is_overdraft_fee": false,
        "is_payroll_advance": false,
        "latitude": -43.2075,
        "longitude": 139.691706,
        "member_guid": "test_atrium_member",
        "memo": null,
        "merchant_category_code": 5411,
        "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b",
        "original_description": "WHOLEFDS TSQ 102",
        "posted_at": "2016-10-07T06:00:00Z",
        "status": "POSTED",
        "top_level_category": "Food & Dining",
        "transacted_at": "2016-10-06T13:00:00Z",
        "type": "DEBIT",
        "updated_at": "2016-10-07T05:49:12Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    Categorize transactions

    Endpoint: POST /test_transactions/cleanse_and_categorize

    Example request:

    curl -X POST \
      https://vestibule.mx.com/test_transactions/cleanse_and_categorize \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'Content-Type: application/json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}' \
      -d '{
      "transactions": [
        {
          "amount": 11.22,
          "description": "BEER BAR 65000000764SALT LAKE C",
          "identifier": "12",
          "type": "DEBIT"
        },
        {
          "amount": 21.33,
          "description": "IN-N-OUT BURGER #239AMERICAN FO",
          "identifier": "13",
          "type": "DEBIT"
        },
        {
          "amount": 1595.33,
          "description": "ONLINE PAYMENT - THANK YOU",
          "identifier": "14",
          "type": "CREDIT"
        }
      ]
    }'
    

    Example response:

    {
      "transactions": [
        {
          "amount": 11.22,
          "category": "Alcohol & Bars",
          "description": "Beer Bar",
          "identifier": "12",
          "is_bill_pay": false,
          "is_direct_deposit": false,
          "is_expense": true,
          "is_fee": false,
          "is_income": false,
          "is_international": false,
          "is_overdraft_fee": false,
          "is_payroll_advance": false,
          "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b",
          "original_description": "BEER BAR 65000000764SALT LAKE C",
          "type": "DEBIT"
        },
        {
          "amount": 21.33,
          "category": "Fast Food",
          "description": "In N Out Burger",
          "identifier": "13",
          "is_bill_pay": false,
          "is_direct_deposit": false,
          "is_expense": true,
          "is_fee": false,
          "is_income": false,
          "is_international": false,
          "is_overdraft_fee": false,
          "is_payroll_advance": false,
          "merchant_guid": "MCH-4a889eb0-0459-f66f-a137-c5e06409d8e6",
          "original_description": "IN-N-OUT BURGER #239AMERICAN FO",
          "type": "DEBIT"
        },
        {
          "amount": 1595.33,
          "category": "Credit Card Payment",
          "description": "Online Payment Thank You",
          "identifier": "14",
          "is_bill_pay": false,
          "is_direct_deposit": false,
          "is_expense": false,
          "is_fee": false,
          "is_income": false,
          "is_international": false,
          "is_overdraft_fee": false,
          "is_payroll_advance": false,
          "merchant_guid": "MCH-a8fd973e-0c2d-f004-f8ef-ec87edc1dd6c",
          "original_description": "ONLINE PAYMENT - THANK YOU",
          "type": "CREDIT"
        }
      ]
    }
    

    Main docs.

    Users

    Create a user

    Endpoint: POST /test_users

    Example request:

    curl -X POST \
      https://vestibule.mx.com/test_users \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'Content-Type: application/json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}' \
      -d '{
      "user": {
        "identifier": "unique_id",
        "metadata": "{\"first_name\": \"Steven\"}"
      }
    }'
    

    Example response:

    {
      "user": {
        "guid": "test_atrium",
        "identifier": "unique_id",
        "is_disabled": false,
        "metadata": "{\"first_name\": \"Steven\"}"
      }
    }
    

    Main docs.

    List users

    Endpoint: GET /test_users

    Example request:

    curl -X GET \
      https://vestibule.mx.com/test_users\
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "pagination": {
        "current_page": 1,
        "per_page": 25,
        "total_entries": 2,
        "total_pages": 1
      },
      "users": [
        {
          "guid": "test_atrium",
          "identifier": "unique_id",
          "is_disabled": false,
          "metadata": "{\"first_name\": \"Steven\"}"
        },
        {
          "guid": "test_atrium",
          "identifier": "another_unique_id",
          "is_disabled": false,
          "metadata": "{\"first_name\": \"Alex\"}"
        }
      ]
    }
    

    Main docs.

    Read a user

    Endpoint: GET /users/test_atrium

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "user": {
        "guid": "test_atrium",
        "identifier": "unique_id",
        "is_disabled": false,
        "metadata": "{\"first_name\": \"Steven\"}"
      }
    }
    

    Main docs.

    Update a user

    Endpoint: PUT /users/test_atrium

    Example request:

    curl -X PUT \
      https://vestibule.mx.com/users/test_atrium \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'Content-Type: application/json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}' \
      -d '{
            "user": {
              "metadata": "{\"first_name\": \"Steven\", \"last_name\": \"Universe\"}"
            }
          }'
    

    Example response:

    {
      "user": {
        "guid": "test_atrium",
        "identifier": "unique_id",
        "is_disabled": false,
        "metadata": "{\"first_name\": \"Steven\"}"
      }
    }
    

    Main docs.

    Delete a user

    Endpoint: DELETE /users/test_atrium

    Example request:

    curl -X DELETE \
      https://vestibule.mx.com/users/test_atrium\
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    204 No Content
    

    Main docs.

    Verification

    Verify

    Endpoint: POST /users/test_atrium/members/test_atrium_member/verify

    Example request:

    curl -i -X POST 'https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/verify' \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {mx_api_key}' \
      -H 'MX-Client-ID: {mx_client_id}'
    

    Example response:

    {
      "member": {
        "aggregated_at": "2019-09-03T20:59:07Z",
        "connection_status": "CONNECTED",
        "guid": "test_atrium_member",
        "identifier": "unique_id",
        "institution_code": "chase",
        "is_being_aggregated": false,
        "metadata": "{\"credentials_last_refreshed_at\": \"2015-10-15\"}",
        "name": "Chase Bank",
        "status": "INITIATED",
        "successfully_aggregated_at": "2019-09-03T20:59:07Z",
        "user_guid": "test_atrium"
      }
    }
    

    Main docs.

    Read account numbers

    Endpoint: /users/test_atrium/members/test_atrium_member/account_numbers

    Example request:

    curl -X GET \
      https://vestibule.mx.com/users/test_atrium/members/test_atrium_member/account_numbers \
      -H 'Accept: application/vnd.mx.atrium.v1+json' \
      -H 'MX-API-Key: {your_api_key}' \
      -H 'MX-Client-ID: {your_client_id}'
    

    Example response:

    {
      "account_numbers": [
        {
          "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1",
          "account_number": "10001",
          "guid": "ACN-iw32636u4-26xu-p253-w27p-q26390201t21",
          "member_guid": "test_atrium_member",
          "routing_number": "68899990000000",
          "user_guid": "test_atrium"
        }
      ]
    }
    

    Main docs.

    Support

    When you go to contact MX Support, please include the following information for the various member statuses:

    Issue type Associated member status Resolution
    MFA REJECTED
    EXPIRED
    Use the workflows given above to resolve any MFA issues. Contact support only if you have trouble successfully implementing them. If you do contact support, please send the following information:

    • Member GUID;
    • MFA type;
    • Attempted API request and response — with any personally-identifiable information removed.
    Credentials DENIED
    PREVENTED
    IMPAIRED
    Use the workflows given above to resolve credential-related issues. Contact support only if a user can successfully log in to their FI's online portal, but has tried unsuccessfully to update their credentials using Atrium. If you contact support, please send the following information:

    • Member GUID;
    • FI website login URL;
    • Credential character lengths;
    • Screenshots of a successful log in at the FI website.
    FI website LOCKED
    IMPEDED
    End-user action is required to address these situations; the end user must log in to their FI website and address the issue.
    Aggregation issues DEGRADED
    DISCONNECTED
    Most aggregation issues are temporary and resolve themselves within 24 hours. Contact MX Support only after a member has landed on one of these statuses for more than two days. If you do contact support, please send the following information:

    • Member GUID.
    Failed update na If you believe a member is missing transactions or failing to update, please send MX Support the following information:

    • Member GUID;
    • Account GUID;
    • Date, amount, and payee of missing transaction(s);
    •Screenshots of missing transition(s) from FI website.

    Product mailing list

    For updates on new features and developments with Atrium, make sure to check back here and on the documentation website regularly.

    You can also sign up to be notified of important changes by email or RSS at our product website, product.mx.com.