# Welcome to the MX Documentation Source: https://docs.mx.com/index
Documentation

Use our guides and references to integrate with MX.

Connect Widget
FEATURED
Payment Verification Account Balance

Payment Verification

Quickly verify financial data including direct deposit account information, account balances, and account owners to ensure a smoother experience for consumers and help mitigate risk.
FEATURED
Deposit Account Opening

Deposit Account Opening

Provide a frictionless process for consumers to easily open and fund new financial accounts.

Browse by products

Connectivity

Connectivity

Connect to and verify financial data

Get account and routing numbers Get the name, address, and contact information for the owner of an account Verify account details by making two, small ACH deposits for end user confirmation Get the available balance for an end user's financial accounts Get account and transaction data by connecting end users' financial accounts Get up to 24 months of account and transaction data Get monthly account statements in PDF format
Data

Data

Cleanse and categorize financial data

Share your held data with an FDX open finance platform Use data-driven intelligence about your customers Create and deploy messaging campaigns to MX Experiences products or your internal app/website Create segmented user lists for targeted marketing campaigns Get enhanced investment holdings data and actionable insights into users' portfolios
Experience

Experience

Personalized, digital financial experiences

Create your own PFM solution using our widgets Deliver dynamic, personalized, and predictive financial insights using our widgets Create a mobile banking app for Android or iOS
# Account Aggregation Source: https://docs.mx.com/products/connectivity/account-aggregation/index Get account and transaction data by connecting end users' financial accounts **NEW TO MX CONNECTIVITY?** See the [Connectivity Overview](/products/connectivity/overview) to learn about our Connectivity products and integration options. Use the Connect Widget and Platform API to let end users connect to their accounts. Use the Platform API to power a non-MX UI connection experience. With Account Aggregation, connect to end users' financial institutions and retrieve 90 days of data for their accounts and transactions. Use this data for any number of solutions such as personal financial management or risk analysis. Data is available for accounts ranging from checking and savings to mortgages and credit cards — and everything in between. We cleanse this data to make it understandable to end users, and we automatically put it into more than 100 predefined categories. We also add enhanced information such as which merchant was involved in a transaction and whether it represents a direct deposit, bill pay, or subscription. Diagram flow of the steps to get account aggregation data ## Aggregation Aggregation is an important feature of the MX Platform API. Aggregating data enables people to see when, where, and how much they are spending. This helps you build solutions that can improve the financial lives of your institution's customers. The best way to aggregate data is with the [Connect Widget](/connect), MX's ready-made UI that can be embedded in your application to aggregate users' account data by prompting end users to connect to their financial institutions using their credentials. This is the preferred method of aggregation. ### Background Aggregation​ MX automatically aggregates each `member` approximately every 24 hours. This process is called **background aggregation**. It ensures that end users' data is always up to date. This is beneficial because, if a background aggregation is successful (for example, the `successfully_aggregated_at` field indicates a time within the last 24 hours), you can choose to skip foreground aggregation and jump right to reading account and transaction data, which can help you load things faster in your product. This background aggregation can be disabled by default for all members. Please reach out to MX to have this setting configured. Background aggregation can be disabled or enabled for individual members by setting the `background_aggregation_is_disabled` field when creating or updating a member (or the `disable_background_agg` configuration option when using the Connect Widget). Background aggregation is also disabled for members created when using the Connect Widget in verification mode. You can override this behavior by setting the `disable_background_agg` widget option to `false`. Note that this only affects newly created members. There are a few other general rules related to background aggregation: * The data source must allow background aggregation. Most sources do, but there are cases in which the data source does not. * The member must not have been aggregated in the last 20 hours. * The member must be in a `CONNECTED`, `UPDATED`, or `CREATED` state. ### Foreground Aggregation​ If an end user is present, you can choose to manually run a foreground aggregation. End users **must** be present during foreground aggregations because they may run into MFA, credential update requests, terms and conditions agreements, or other situations requiring end-user input. Just keep in mind that **you cannot run a new aggregation within three hours of a successful aggregation**, whether foreground or background. Thus, attention must be paid to the `aggregated_at` and `successfully_aggregated_at` member fields while you're developing your product with the Platform API. **INFO** Both foreground and background aggregation may be prevented by disabling a `user`. A `user` must be re-enabled before any aggregation can be attempted. We may suspend background aggregation on a particular `member` in some circumstances, such as when several consecutive aggregation attempts fail. However, you can always attempt a foreground aggregation on a suspended `member`. ## Quick Links Learn about the full features of the Platform API. Learn about the Connect Widget. View the demo app on GitHub. ## Account Sample Data This sample response shows the data you can expect to get for financial accounts. ```json theme={null} { "accounts": [ { "account_number": "5366", "apr": 1.0, "apy": 1.0, "available_balance": 1000.0, "available_credit": 1000.0, "balance": 1000.0, "cash_balance": 1000.0, "cash_surrender_value": 1000.0, "created_at": "2016-10-13T17:57:37.000Z", "credit_limit": 100.0, "currency_code": "USD", "day_payment_is_due": 20, "death_benefit": 1000, "guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "holdings_value": 1000.0, "id": "1040434698", "imported_at": "2015-10-13T17:57:37.000Z", "institution_code": "chase", "insured_name": "Frodo Baggins", "interest_rate": 1.0, "is_closed": false, "is_hidden": false, "last_payment": 100.0, "last_payment_at": "2015-10-13T17:57:37.000Z", "loan_amount": 1000.0, "matures_on": "2015-10-13T17:57:37.000Z", "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "member_id": "member-9876", "member_is_managed_by_user": false, "metadata": "some metadata", "minimum_balance": 100.0, "minimum_payment": 10.0, "name": "Test account 2", "nickname": "My Checking", "original_balance": 10.0, "pay_out_amount": 10.0, "payment_due_at": "2015-10-13T17:57:37.000Z", "payoff_balance": 10.0, "premium_amount": 1.0, "routing_number": "68899990000000", "started_on": "2015-10-13T17:57:37.000Z", "subtype": "NONE", "total_account_value": 1.0, "type": "SAVINGS", "updated_at": "2016-10-13T18:08:00.000Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "partner-2345" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` ## Transaction Sample Data This sample response shows the data you can expect to get for transactions. ```json theme={null} { "transactions": [ { "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "account_id": "account123", "amount": 61.11, "category": "Groceries", "category_guid": "CAT-9588eaad-90a4-bb5c-66c8-1812503d0db8", "check_number_string": "6812", "created_at": "2016-10-06T09:43:42.000Z", "currency_code": "USD", "date": "2013-09-23T00:00:00.000Z", "description": "Whole foods", "extended_transaction_type": "partner_transaction_type", "guid": "TRN-265abee9-889b-af6a-c69b-25157db2bdd9", "id": "transaction-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, "is_recurring": false, "is_subscription": false, "latitude": -43.2075, "localized_description": "This is a localized_description", "localized_memo": "This is a localized_memo", "longitude": 139.691706, "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "member_is_managed_by_user": false, "memo": "This is a memo", "merchant_category_code": 5411, "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b", "merchant_location_guid": "MCL-00024e59-18b5-4d79-b879-2a7896726fea", "metadata": "some metadata", "original_description": "WHOLEFDS TSQ 102", "posted_at": "2016-10-07T06:00:00.000Z", "status": "POSTED", "top_level_category": "Food & Dining", "transacted_at": "2016-10-06T13:00:00.000Z", "type": "DEBIT", "updated_at": "2016-10-07T05:49:12.000Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "partner-2345" }, // ••• ], "pagination": { "current_page": 1, "per_page": 10, "total_entries": 243, "total_pages": 25 } } ``` ## Related Products Gather end users' tax statements or credit card rewards, such as miles or points, by connecting to their accounts with our Account Aggregation product. For additional transaction history, continue with our Extended Transaction History product. With our Statements product, connect to an end user's financial account to retrieve PDF financial statements to gather more information for decisioning. # Account Owner Identification Source: https://docs.mx.com/products/connectivity/account-owner-identification/index Get the name, address, and contact information for the owner of an account **NEW TO MX CONNECTIVITY?** See the [Connectivity Overview](/products/connectivity/overview) to learn about our Connectivity products and integration options. Use the Connect Widget and Platform API to let end users connect to their accounts. Use the Platform API to power a non-MX UI connection experience. With Account Owner Identification, you can connect to an end user's financial account to retrieve information such as their name and address. You can use this data to verify the information provided by an end user. This can be used for solutions that require fraud and risk reduction, account opening, and digital banking. The Account Owner Identification product can be used as a standalone product or in combination with other MX products. If you use Account Owner Identification as a standalone product, you cannot use our Connect Widget interface for connecting accounts and will be required to complete an API-only integration. We encourage you to use Account Owner Identification in conjunction with Account Aggregation or Instant Account Verification so you can use our powerful Connect Widget. Diagram flow of the steps to get account owner information ## Quick Links Learn about the full features of the Platform API. Learn about the Connect Widget. View the demo app on GitHub. ## Account Owner Sample Data This sample response shows the data you can expect to get for account owners. ```json theme={null} { "account_owners": [ { "account_guid": "ACT-82a93692-f756-534f-9b2e-ad10a0f38462", "address": "123 This Way", "city": "Middlesex", "country": "US", "email": "donnie@darko.co", "first_name": "Donnie", "guid": "ACO-63dc7714-6fc0-4aa2-a069-c06cdccd1af9", "last_name": "Darko", "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "owner_name": "Donnie Darko", "phone": "555-555-5555", "postal_code": "00000-0000", "state": "VA", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` ## Related Products Get account and routing numbers. Get account and transaction data. Check an account's available balance. # Balance Checks Source: https://docs.mx.com/products/connectivity/balance-checks/index Get the available balance for an end user's financial accounts **NEW TO MX CONNECTIVITY?** See the [Connectivity Overview](/products/connectivity/overview) to learn about our Connectivity products and integration options. Use the Connect Widget and Platform API to let end users connect to their accounts. Use the Platform API to power a non-MX UI connection experience. With Balance Checks you can connect to an end user's financial institution and retrieve the available balance for an account, as well as a lot of other information about that account. Unlike Account Aggregation, this product does not pull in transaction data. This makes Balance Checks perfect for use cases like money movement or account opening where such data is not needed. Diagram flow of the steps to get account statements ## Quick Links Learn about the full features of the Platform API. ## Account Sample Data This sample response shows the kinds of data you can expect to get for financial accounts when using Balance Checks. ```json theme={null} { "account": { "account_number": "5366", "apr": 1.0, "apy": 1.0, "available_balance": 1000.0, "available_credit": 1000.0, "balance": 1000.0, "cash_balance": 1000.0, "cash_surrender_value": 1000.0, "created_at": "2016-10-13T17:57:37.000Z", "credit_limit": 100.0, "currency_code": "USD", "day_payment_is_due": 20, "death_benefit": 1000, "guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "holdings_value": 1000.0, "id": "1040434698", "imported_at": "2015-10-13T17:57:37.000Z", "institution_code": "chase", "interest_rate": 1.0, "is_closed": false, "is_hidden": false, "last_payment": 100.0, "last_payment_at": "2015-10-13T17:57:37.000Z", "loan_amount": 1000.0, "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "member_is_managed_by_user": false, "metadata": "some metadata", "minimum_balance": 100.0, "minimum_payment": 10.0, "name": "Test account 2", "nickname": "My Checking", "original_balance": 10.0, "payment_due_at": "2015-10-13T17:57:37.000Z", "payoff_balance": 10.0, "routing_number": "68899990000000", "started_on": "2015-10-13T17:57:37.000Z", "subtype": "NONE", "total_account_value": 1.0, "type": "SAVINGS", "updated_at": "2016-10-13T18:08:00.000Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "partner-2345" } } ``` ## Related Products Get account owner information like name, address, and email. Get account and routing numbers. Get account and transaction data. # Extended Transaction History Source: https://docs.mx.com/products/connectivity/extended-transaction-history/index Get up to 24 months of account and transaction data **NEW TO MX CONNECTIVITY?** See the [Connectivity Overview](/products/connectivity/overview) to learn about our Connectivity products and integration options. Use the Connect Widget and Platform API to let end users connect to their accounts. Use the Platform API to power a non-MX UI connection experience. With Extended Transaction History, you can connect to an end user's financial institution and retrieve up to 24 months of data for their accounts and transactions. Standard account aggregation provides only up to 90 days. You can use this data for any number of solutions such as personal financial management or risk analysis. Data is available for accounts ranging from checking and savings to mortgages and credit cards — and everything in between. We cleanse this data to make it understandable to end users, and we automatically put it into more than 100 predefined categories. We also add enhanced information such as which merchant was involved in a transaction and whether it represents a direct deposit, bill pay, or subscription. Diagram flow of the steps to get transaction history data ## Quick Links Learn about the full features of the Platform API. ## Account Sample Data This sample response shows the kinds of account data you can expect to get for financial accounts when using Extended Transaction History. ```json theme={null} { "account": { "account_number": "5366", "apr": 1.0, "apy": 1.0, "available_balance": 1000.0, "available_credit": 1000.0, "balance": 1000.0, "cash_balance": 1000.0, "created_at": "2016-10-13T17:57:37.000Z", "credit_limit": 100.0, "currency_code": "USD", "day_payment_is_due": 20, "guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "holdings_value": 1000.0, "id": "1040434698", "institution_code": "chase", "interest_rate": 1.0, "is_closed": false, "is_hidden": false, "last_payment": 100.0, "last_payment_at": "2015-10-13T17:57:37.000Z", "loan_amount": 1000.0, "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "member_is_managed_by_user": false, "metadata": "some metadata", "minimum_balance": 100.0, "minimum_payment": 10.0, "name": "Test account 2", "nickname": "My Checking", "original_balance": 10.0, "payment_due_at": "2015-10-13T17:57:37.000Z", "payoff_balance": 10.0, "routing_number": "68899990000000", "started_on": "2015-10-13T17:57:37.000Z", "subtype": "NONE", "total_account_value": 1.0, "type": "SAVINGS", "updated_at": "2016-10-13T18:08:00.000Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "partner-2345" } } ``` ## Transaction Sample Data This sample response shows the kinds of transaction data you can expect to get for financial accounts when using Extended Transaction History. ```json theme={null} { "transaction": { "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "account_id": "account123", "amount": 61.11, "category": "Groceries", "category_guid": "CAT-9588eaad-90a4-bb5c-66c8-1812503d0db8", "check_number_string": "6812", "created_at": "2016-10-06T09:43:42.000Z", "currency_code": "USD", "date": "2013-09-23T00:00:00.000Z", "description": "Whole foods", "guid": "TRN-265abee9-889b-af6a-c69b-25157db2bdd9", "id": "transaction-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, "is_recurring": false, "is_subscription": false, "latitude": -43.2075, "localized_description": "This is a localized_description", "localized_memo": "This is a localized_memo", "longitude": 139.691706, "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "member_is_managed_by_user": false, "memo": "This is a memo", "merchant_category_code": 5411, "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b", "metadata": "some metadata", "original_description": "WHOLEFDS TSQ 102", "posted_at": "2016-10-07T06:00:00.000Z", "status": "POSTED", "top_level_category": "Food & Dining", "transacted_at": "2016-10-06T13:00:00.000Z", "type": "DEBIT", "updated_at": "2016-10-07T05:49:12.000Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "partner-2345" } } ``` ## Related Products Get monthly account statements as PDFs. Get account and routing numbers. Get account and transaction data. # Instant Account Verification Source: https://docs.mx.com/products/connectivity/instant-account-verification/index Get account and routing numbers for demand deposit accounts **NEW TO MX CONNECTIVITY?** See the [Connectivity Overview](/products/connectivity/overview) to learn about our Connectivity products and integration options. Use the Connect Widget and Platform API to let end users connect to their accounts. Use the Platform API to power a non-MX UI connection experience. With Instant Account Verification, you can connect to an end user's financial institution and retrieve account and routing numbers for their demand deposit accounts. You can use this data for any number of solutions such as moving money or account opening. In many cases, Instant Account Verification must be used in conjunction with Account Owner Identification and Balance Checks to prevent problems like ACH returns. Diagram flow of the steps to get account and routing numbers ## Tokenized Account Numbers​ Tokenized Account Numbers (TANs) are substitute account numbers used for secure ACH money movement. When users connect accounts via OAuth with supported institutions, the institution provides a TAN instead of the actual account number. This allows third-party applications to interact with an account, such as facilitating ACH money movement, without accessing the user's actual account number. Because each application receives a unique TAN for the same bank account, users or their financial institutions can manage access on a per-application basis without exposing the underlying account details. **Understanding account objects:** MX uses two objects that display account numbers differently: | Feature | `accounts` object | `account_numbers` object | | --------------------- | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | | Available through | List Accounts, List Accounts by Member, Read Account, and Read Account by Member | List Account Numbers by Member and Read Account Numbers by Account | | Set by | Create Member or through the Connect Widget when the user connects to an institution | Verify Member or Create Member | | Account number format | `feed_account_number` field contains a masked account number (usually last 4 digits) from the institution | Contains either the full account number or a TAN (for supported institutions) | | Last 4 digits | Included in masked format | Does **not** include a field with the last 4 digits | | Data source | The `*_set_by` field shows the data source (typically `FEED` unless you send a user-specified value) | N/A | | Can be null | Yes, if the institution doesn't provide it | No | | TAN matching | N/A | When a TAN is returned, it won't match the masked digits from the `accounts` object | **Key properties:** * The TAN and routing number are valid for ACH transfers **only when used together**. They won't work for wire transfers, and third-party verification services may not recognize them. * Using a TAN with a different routing number—even from the same institution—will cause the transfer to fail. * You cannot reliably match TANs to your existing account records using the last 4 digits. The masked account number from the `accounts` object won't necessarily match the corresponding TAN. * OAuth connections: Call `/users/{user_guid}/members/{member_guid}/account_numbers` to retrieve the TAN in the `account_number` field. * Non-OAuth connections: Return traditional (non-tokenized) account and routing numbers. * The standard `accounts` object endpoints always return masked account numbers, regardless of connection type. Do not display the TAN in your UI; users won't recognize it. Show the masked account number from the `/users/{user_identifier}/accounts` endpoint instead. **Institution-specific behavior:** | Institution | TAN Behavior | | :---------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Chase | TAN becomes invalid if MX revokes consent, the user revokes consent directly, or Chase flags the account for fraud. | | U.S. Bank | TAN remains active for money movement even after the MX connection is deleted. See the [U.S. Bank Developer Portal](https://developer.usbank.com/) for details. | ## Quick Links Learn about the full features of the Platform API. Learn about the Connect Widget. View the demo app on GitHub. ## Account Number Sample Data This sample response shows the data you can expect to get for account owners. ```json theme={null} { "account_numbers": [ { "account_guid": "ACT-82a93692-f756-534f-9b2e-ad10a0f38462", "account_number": "10001", "institution_number": null, "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "routing_number": "091000019", "passed_validation": true, "transit_number": null, "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` ## Related Products Get account owner information like name, address, and email. Get account and transaction data. Prevent returns and other costly errors. # Best Practices Source: https://docs.mx.com/products/connectivity/instant-account-verification/processor-token/best-practice ## Reducing ACH Returns Below are best practices for preventing ACH returns and for dealing with the specific reasons for returns when they do occur. We advise you to run a real-time balance check on an account before submitting an ACH transaction for that account. ### R01 — Insufficient Funds **Prevent:** 1. Always run a balance check before submitting an ACH transaction to ensure that there are sufficient funds in the account. 2. Submit the ACH transaction as soon as possible after running the balance check. **Troubleshoot:** Wait until there are sufficient funds before submitting another ACH transaction for the account. ### R02 — Account Closed **Prevent:** Always run a balance check before submitting an ACH transaction to ensure that the account is still open. **Troubleshoot:** 1. Stop all future transfer requests for this account. 2. Have the end user verify a different account. ### R03 — Account Not Found **Troubleshoot:** Make sure that an account owner identification (identity) has been performed before initiating an ACH transaction. Confirm that the name provided by the end user is the same as the one from the account owner identification. ### R04 — Invalid Account Number **Prevent:** Clients should run an account verification for the account and confirm that the `passed_validation` field is true before passing an authorization code to processors. Processors should confirm that the `passed_validation` field is true before submitting an ACH transaction for the account. **Troubleshoot:** Stop all future transfer requests for this account. ## Logging ### Clients Should Log Every Authorization Code Logging each authorization `code` you create and deliver to a processor may be helpful in troubleshooting with MX. ### Processors Should Log Every `access_token` Processors should store all access tokens received from the `/payment_processor_token` endpoint. * Access tokens can be reused for the life of the token. Storing the token facilitates recurring payments as well as troubleshooting requests to MX should the need arise. * Access tokens expire 60 days from the time they were issued. ### Processors Should Log `account_guid`, `member_guid`, `user_guid` Log the `account_guid`, `member_guid`, and `user_guid` associated with each access token. * Access tokens are scoped to these specific GUIDs. Logging them will allow you to correctly map them to the stored token. This facilitates reuse and recurring payments. * These values are also necessary when troubleshooting problems with MX. * These values can be obtained from the client, and they are also returned in responses to processor endpoints. * MX does not currently check for duplicate tokens scoped to the same user/member/account. Thus, storing them on your end and mapping them appropriately will help prevent duplicates. ### Processors Should Log Every Success or Failure Processors should log the success or failure of each request where an access token is used. If an error occurs, MX will need the `access_token` and the associated `account_guid`, `member_guid`, and `user_guid` in order to troubleshoot. # How-to Guide for Clients Source: https://docs.mx.com/products/connectivity/instant-account-verification/processor-token/client-guide ## Getting Started This guide is intended for our clients using the MX Platform API. It explains how to move money with a processor by giving them access to user data with an authorization code. This authorization code is then sent to the processor and used by them to request an access token. Before you can begin, MX must enable the Platform API as well as the account verification and payment processing features. You must also ensure you have your `api_key` and `client_id` from the [Client Dashboard](https://dashboard.mx.com). ## Demo App Our demo app provides a concrete implementation of processor tokens and demonstrates how they fit into the MX ecosystem using a simple Ruby on Rails app. Install, run, and review the app's code to understand more about how the process works. [The demo app is hosted on GitHub.](https://github.com/mxenabled/processor-tokens-client-quickstart) ## Get an Authorization Code The workflow is as follows: 1. Create a user (API call). 2. Connect and verify account numbers (API call and Connect Widget UI). 3. List verified accounts (API call). 4. Identify account owners (optional; multiple API calls). 5. Request the authorization code. 6. If your processor does not require account owner information, you don't need to complete the identity step. A user represents your end user in the MX Platform. Make a request to the [Create User](/api-reference/platform-api/reference/users) endpoint (`POST /users`). We recommend that you include a unique [`id`](/api-reference/platform-api/overview/formats-requirements#identifiers-and-metadata) of your choice with the request. You may also include `metadata`, such as the date the `user` was created or the end user's name. Don't include any sensitive information here, such as credentials. **INFO** None of these parameters are required, but the `user` object can't be empty. We recommend that you always set the `id` parameter when creating a user. In the response, the API gives each new `user` an MX-defined `guid` (or `user_guid` when appearing outside the `user` object). Between your `id` and the `guid`, you can map between your system and ours. You'll need the user `guid` for nearly every request on the MX API, at least when using basic authorization. ```shell Request theme={null} curl -i -X POST 'https://int-api.mx.com/users' \ -u 'client_id:api_key' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -d '{ "user": { "id": "partner-2345", "is_disabled": false, "email": "example@example.com", "metadata": "Some metadata" } }' ``` ```json Response theme={null} { "user": { "email": "totally.fake.email@notreal.com", "guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "id": "partner-2345", "is_disabled": false, "metadata": "Yada yada yada" } } ``` Connect a `user` to a financial institution through a `member`. Verifying account numbers always happens through a member, and this verification is required in order to request an authorization code. Use the [Connect Widget](/connect) to create a member and verify it with an MX-provided user interface. You'll need this member's unique GUID for later steps as well. For more information on the Connect Widget, review the guide. Some processors require transaction data and some do not. Configuration of the Connect Widget depends on what data the processor requires. #### A. No Transaction Data Required 1. Make a `POST` request to the get widget URL endpoint with the `user_guid` from step one. 2. Set the `mode` to `verification`. 3. Set the `widget_type` to `connect_widget`. 4. Capture the URL from the response. 5. Load the Connect Widget URL. The end user will select an institution and proceed through the Connect Widget flow. 6. Capture the `member_guid` returned in the member connected postMessage during this flow. It will be used in the next step. ```shell Request theme={null} curl -i -X POST https://int-api.mx.com/users/USR-29eab3cf-6a87-fe97-6279-563b63e75a53/widget_urls \ -H 'Accept: application/vnd.mx.api.v1+json' \ -u 'client_id:api_key' \ -H 'Content-type: application/json' \ -d '{ "widget_url": { "widget_type": "connect_widget", "mode": "verification" } }' ``` ```json Response theme={null} { "widget_url": { "type": "connect_widget", "url": "https://int-widgets.moneydesktop.com/md/connect/yxcdk7f1nb99jwApp34lA24m0AZ8rzprgmw17gm8z8h2AzjyAnd1rj42qfv42r3xnn07Amfwlg3j09hwp8bkq8tc5z21j33xjggmp2qtlpkz2v4gywfhfn31l44tx2w91bfc2thc58j4syqp0hgxcyvA4g7754hk7gjc56kt7tc36s45mmkdz2jqqqydspytmtr3dAb9jh6fkb24f3zkfpdjj0v77f0vmrtzvzxkmxz7dklsq8gd0gstkbhlw5bgpgc3m9mAtpAcr2w15gwy5xc4blgxppl42Avnm63291z3cyp0wm3lqgmvgzdAddct423gAdqxdlfx5d4mvc0ck2gt7ktqgks4vxq1pAy5", "user_id": "U-jeff-201709221210" } } ``` #### B. Transaction Data is Required If you or your processor's use case requires account and transaction data in addition to account numbers, use the optional `include_transactions` parameter, which fetches the last 90 days of transactions at the same time as verifying account numbers. You also need to know whether the use case requires transaction data only once or continuously. This is determined with the `disable_background_agg` parameter. **For One-Time Transaction Data** 1. Make a `POST` request to the get widget URL endpoint with the `user_guid` from step one. 2. Set the `mode` to `verification`. 3. Set the `widget_type` to `connect_widget`. 4. Set `include_transactions` to `true`. 5. Set `disable_background_agg` to `true`. 6. Capture the URL for an embeddable version of the Connect Widget from the response. 7. Load the Connect Widget URL. The end user will select an institution and proceed through the Connect Widget flow. 8. Capture the `member_guid` returned in the member connected postMessage during this flow. It will be used in the next step. ```shell Request theme={null} curl -i -X POST https://int-api.mx.com/users/USR-29eab3cf-6a87-fe97-6279-563b63e75a53/widget_urls \ -H 'Accept: application/vnd.mx.api.v1+json' \ -u 'client_id:api_key' \ -H 'Content-type: application/json' \ -d '{ "widget_url": { "widget_type": "connect_widget", "mode": "verification", "include_transactions": true, "disable_background_agg": true } }' ``` ```json Response theme={null} { "widget_url": { "type": "connect_widget", "url": "https://int-widgets.moneydesktop.com/md/connect/yxcdk7f1nb99jwApp34lA24m0AZ8rzprgmw17gm8z8h2AzjyAnd1rj42qfv42r3xnn07Amfwlg3j09hwp8bkq8tc5z21j33xjggmp2qtlpkz2v4gywfhfn31l44tx2w91bfc2thc58j4syqp0hgxcyvA4g7754hk7gjc56kt7tc36s45mmkdz2jqqqydspytmtr3dAb9jh6fkb24f3zkfpdjj0v77f0vmrtzvzxkmxz7dklsq8gd0gstkbhlw5bgpgc3m9mAtpAcr2w15gwy5xc4blgxppl42Avnm63291z3cyp0wm3lqgmvgzdAddct423gAdqxdlfx5d4mvc0ck2gt7ktqgks4vxq1pAy5", "user_id": "U-jeff-201709221210" } } ``` **For Continuous Transaction Data (aggregated daily)** 1. Make a `POST` request to the get widget URL endpoint with the `user_guid` from step one. 2. Set the `mode` to `verification`. 3. Set the `widget_type` to `connect_widget`. 4. Set `include_transactions` to `true`. 5. Set `disable_background_agg` to `false`. 6. Capture the URL for an embeddable version of the Connect Widget from the response. 7. Load the Connect Widget URL. The end user will select an institution and proceed through the Connect Widget flow. 8. Capture the `member_guid` returned in the member connected postMessage during this flow. It will be used in the next step. ```shell Request theme={null} curl -i -X POST https://int-api.mx.com/users/USR-29eab3cf-6a87-fe97-6279-563b63e75a53/widget_urls \ -H 'Accept: application/vnd.mx.api.v1+json' \ -u 'client_id:api_key' \ -H 'Content-type: application/json' \ -d '{ "widget_url": { "widget_type": "connect_widget", "mode": "verification", "include_transactions": true, "disable_background_agg": false } }' ``` ```json Response theme={null} { "widget_url": { "type": "connect_widget", "url": "https://int-widgets.moneydesktop.com/md/connect/yxcdk7f1nb99jwApp34lA24m0AZ8rzprgmw17gm8z8h2AzjyAnd1rj42qfv42r3xnn07Amfwlg3j09hwp8bkq8tc5z21j33xjggmp2qtlpkz2v4gywfhfn31l44tx2w91bfc2thc58j4syqp0hgxcyvA4g7754hk7gjc56kt7tc36s45mmkdz2jqqqydspytmtr3dAb9jh6fkb24f3zkfpdjj0v77f0vmrtzvzxkmxz7dklsq8gd0gstkbhlw5bgpgc3m9mAtpAcr2w15gwy5xc4blgxppl42Avnm63291z3cyp0wm3lqgmvgzdAddct423gAdqxdlfx5d4mvc0ck2gt7ktqgks4vxq1pAy5", "user_id": "U-jeff-201709221210" } } ``` After you create and verify a member with the Connect Widget, make a request to the list account numbers by member endpoint to retrieve the account numbers tied to that `member`. This request requires the `member_guid` delivered with the Connect Widget's member connected postMessage in the previous step. Capture the `account_guid` returned in this response to use later. ```shell Request theme={null} curl -i 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0/account_numbers' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -u 'client_id:api_key' ``` ```json Response theme={null} { "account_numbers": [ { "account_guid": "ACT-82a93692-f756-534f-9b2e-ad10a0f38462", "account_number": "10001", "institution_number": null, "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "routing_number": "68899990000000", "passed_validation": true, "transit_number": null, "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` If a processor needs account owner information, complete the identification process before you request an authorization code. This enables processors to request account owner information using their token. It is important that you complete this process only after you've completed the steps outlined above. For more information on identity or account owner information, visit our Account Owner Identification guide. Identifying account owner information is itself a multi-step process which can potentially involve multi-factor authentication and can't be completed with the Connect Widget. You must begin it by making a POST request to the identify member endpoint with the `user_guid` and `member_guid` you captured in previous steps, which is shown in the example below. ```shell Request theme={null} curl -i -X POST 'https://int-api.mx.com/users/USR-fa7537f3-48aa-a683-a02a-b18940482f54/members/MBR-7c6f361b-e582-15b6-60c0-358f12466b4b/identify' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -u 'client_id:api_key' ``` ```json Response theme={null} { "member": { "aggregated_at": "2016-10-13T18:07:57.000Z", "connection_status": "CONNECTED", "guid": "MBR-7c6f361b-e582-15b6-60c0-358f12466b4b", "id": "unique_id", "institution_code": "chase", "is_being_aggregated": false, "is_managed_by_user": false, "is_oauth": false, "metadata": "\"credentials_last_refreshed_at\": \"2015-10-15\"", "name": "Chase Bank", "oauth_window_uri": "https://mxbank.mx.com/oauth/authorize?client_id=b8OikQ4Ep3NuSUrQ13DdvFuwpNx-qqoAsJDVAQCyLkQ&redirect_uri=https%3A%2F%2Fint-app.moneydesktop.com%2Foauth%2Fredirect_from&response_type=code&scope=openid&state=d745bd4ee6f0f9c184757f574bcc2df2", "successfully_aggregated_at": "2016-10-13T17:57:38.000Z", "user_guid": "USR-fa7537f3-48aa-a683-a02a-b18940482f54", "user_id": "user123" } } ``` You're now ready to request an authorization code with the following steps: Make a `POST` request to the `/authorization_code` endpoint. In the body of the request, you must include the `user_guid`, `member_guid`, and `account_guid` captured in previous steps. You'll receive an authorization code in the response. **INFO** Authorization codes are one-time use. ```shell Request theme={null} curl -i -X POST 'https://int-api.mx.com/authorization_code' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -u 'client_id:api_key' \ -d '{ "authorization_code": { "scope": "user-guid:USR-101ad774-288b-44ed-ad16-da87d522ea20 member-guid:MBR-54feffb9-8474-47bd-8442-de003910113a account-guid:ACT-32a64160-582a-4f00-ab34-5f49cc35ed35 read-protected" } }' ``` ```json Response theme={null} { "authorization_code": { "code": "9nN-9D8_4Z3WYazx7-zXfmqsD3jwgL_2W927Sb3otI" } } ``` ## Next Steps You've completed your part of the process. Send the authorization code to your payment processor. They'll need to review the steps in the How-to Guide for Processors. # Intro to Processor Token Source: https://docs.mx.com/products/connectivity/instant-account-verification/processor-token/index > Reduce the risk of storing financial account information. Request a token that can be used by a processor to retrieve information from MX. ## Overview We've provided an example to help you understand how Processor Token works. It includes a description of the roles involved in tokenization and how the API generates tokens that can be exchanged by processors for account-related information. We've assumed the following participants: | Persona | Description | | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Client | Financial institutions, fintech companies, or service providers that provide platforms and applications that enable digital financial services for their end users. | | Processor | Vendors our clients use that provide services that enable their platforms and applications. An example of these services may be payment processing. Processors require access to our data to complete transactions and provide services to our clients. | ## The Problem Because our Clients are offering their end users services powered by MX data, our Clients have to store and manage the data they receive from us. Their interactions with Processors rely on managing and transferring this data. This process requires our Clients to maintain a complex framework that can support secure data management, which increases security risks and costs while limiting our Clients' ability to use our services to meet their end users' needs. ## The Solution Using our Processor Token API, our Clients can authorize Processors to access the data they need directly from us by using a token. This reduces the risks our Clients experience when managing the data they pull from us. Clients can achieve the solution by using the steps below: | Step | Responsible | Action | | ---- | ----------- | ----------------------------------------------------------------------------------------------------------- | | 1. | Client | Aggregate, verify, or do both using the Connect Widget. | | 2. | Client | Identify a member to retrieve account owner information (optional). | | 3. | Client | Request an authorization code. | | 4. | Client | Provide the processor with the authorization code. | | 5. | Processor | Use the authorization code to request an access token. | | 6. | Processor | Use the access token to request payment account numbers, account owner information, or transaction history. | ## Next steps To receive and use a processor token, both the Client and the Processor must use this process. * If you’re our Client and have not received an authorization code, refer to the How-to Guide for Clients. * If you’re a Processor and have already received an authorization code from one of our Clients, refer to the How to Guide for Processors. # How-to Guide for Processors Source: https://docs.mx.com/products/connectivity/instant-account-verification/processor-token/processor-guide ## Getting Started This guide explains how to request an access token and how to retrieve different types of information using the access token. It is intended for processors working with an MX client that have already received an `authorization_code`. In addition to this code, you need your `api_key` and `processor_id`, which can be found on the [Client Dashboard](https://dashboard.mx.com). ## 1. Request an Access Token **INFO** The authorization code used in this request is one-time use. After you have received a `code`, request an `access_token` as follows. The response returns an `access_token` which you'll use in later steps to actually request user data. Every `access_token` expires after 60 days. To get a new token after an old one has expired, you must get a new code from the client. 1. Make a `POST` request to the /token endpoint. 2. In the query string parameters, include the code as shown in example. 3. In the authorization header, include your `processor_id` and `api_key`. See the reference section on authentication for more information on this header. ```shell Request theme={null} curl -i -L -X POST 'https://int-api.mx.com/token?grant_type=authorization_code&code=9nN-9D8_4Z3WYazx7-zXfmqsD3jwgL_2W927Sb3otI' \ -H 'accept: application/vnd.mx.api.v1+json' \ -u 'payment_processor_id:api_key' ``` ```json Response theme={null} { "access_token": "DCOwM2Zxxc0YO507ZZqIiJ8gBN5HdSQG4_g3v3xjFlGUM", "expires_at": null, "scope": "user-guid:USR-101ad774-288b-44ed-ad16-da87d522ea20 member-guid:MBR-54feffb9-8474-47bd-8442-de003910113a account-guid:ACT-32a64160-582a-4f00-ab34-5f49cc35ed35 read-protected", "token_type": "Bearer" } ``` ## 2. Use your Access Token Once you have your `access_token`, you can request the following types of information: * [Real-time account balance](/products/connectivity/instant-account-verification/processor-token/processor-guide#real-time-account-balances) (This should be the first request you make; it helps prevent failures due to insufficient funds, closed accounts, etc.). * [Account numbers](/products/connectivity/instant-account-verification/processor-token/processor-guide#account-and-routing-numbers) * [Account owner information](/products/connectivity/instant-account-verification/processor-token/processor-guide#account-owner-information) * [Transaction history](/products/connectivity/instant-account-verification/processor-token/processor-guide#transaction-history) * [Payment account information](/products/connectivity/instant-account-verification/processor-token/) ### Real-time Account Balances First, use your access token to get the real-time balance for the account. This involves a request to gather (aggregate) the information, followed by a request to read the information. Checking balances before processing a payment or submitting a transaction to a system like ACH helps prevent errors resulting from insufficient funds or closed accounts. It also allows you to inform end users about potential overdraft fees and other potential issues. 1. Use the `/account/check_balance` endpoint to fetch the latest balance information. 2. Use the `/payment_account` endpoint to read the fetched balance information. #### 1. Check Real-Time Account Balance Checking a balance returns a `member` object. This `member` describes the state of the connection between the user and their financial institution and indicates whether the requested balance information has been successfully gathered. For more information on checking balances, review our Balance Checks guide. **INFO** This endpoint only aggregates balance-related data; it does not include transactional data. Neither does it return balance data in the response. You'll read balance data in the next step. 1. Make a `POST` request to the `/account/check_balance` endpoint. * In the `Authorization` header, set the type to `Bearer` and include the `access_token` retrieved at the beginning of this guide. * This first call should return with a status of `200 OK` and include a member object in the body. * Gathering balance data may take time, so check on the status of the connection. Initially, you should see the `is_being_aggregated` field return with `true`. ```shell Request theme={null} curl -L -X POST 'https://int-api.mx.com/account/check_balance' -H 'Accept: application/vnd.mx.api.v1+json' -H 'Authorization: Bearer PROCESSOR_TOKEN_GOES_HERE' ``` ```json Response theme={null} { "member": { "aggregated_at": "2022-11-30T17:25:27Z", "background_aggregation_is_disabled": false, "connection_status": "CONNECTED", "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa", "id": null, "institution_code": "mxbank", "is_being_aggregated": true, "is_managed_by_user": true, "is_oauth": false, "metadata": "Additional information", "name": "MX Bank", "successfully_aggregated_at": "2022-11-30T09:36:10Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "U-201709221210" } } ``` Check the status of the connection by calling the `/account/check_balance` endpoint again. * These subsequent calls should return with a status of `202 Accepted` rather than `200 OK`, and they will include the current state of the member. * Keep in mind, however, that you can only call this endpoint 5 times every 2 hours for a given member. Move on to the next step when the following state is reached: * `connection_status: CONNECTED` * `is_being_aggregated: false` * `successfully_aggregated_at` updates to the current time. ```shell Request theme={null} curl -L -X POST 'https://int-api.mx.com/account/check_balance' -H 'Accept: application/vnd.mx.api.v1+json' -H 'Authorization: Bearer PROCESSOR_TOKEN_GOES_HERE' ``` ```json Response theme={null} { "member": { "aggregated_at": "2022-11-30T17:25:27Z", "background_aggregation_is_disabled": false, "connection_status": "CONNECTED", "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa", "id": null, "institution_code": "mxbank", "is_being_aggregated": true, "is_managed_by_user": true, "is_oauth": false, "metadata": "Additional information", "name": "MX Bank", "successfully_aggregated_at": "2022-11-30T09:36:10Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "U-201709221210" } } ``` #### 2. Read Balance Information Read the aggregated balance data as follows. The response includes the account's balance and other information about the payment account. 1. Make a `GET` request to the `/payment_account` endpoint. 2. In the `Authorization` header, set the type to `Bearer` and include the `access_token` retrieved at the beginning of this guide. ```shell Request theme={null} curl -L -X GET 'https://int-api.mx.com/payment_account' \ -H 'accept: application/vnd.mx.api.v1+json' \ -H 'Authorization: Bearer PROCESSOR_TOKEN_GOES_HERE' ``` ```json Response theme={null} { "payment_account": { "account_guid": "ACT-32a64160-582a-4f00-ab34-5f49cc35ed35", "account_name": "MX Bank Checking", "account_number": "6366816006", "account_type": "CHECKING", "available_balance": 1000, "balance": 1000, "created_at": "2022-03-17T20:38:58Z", "member_guid": "MBR-54feffb9-8474-47bd-8442-de003910113a", "routing_number": "242722023", "transit_number": null, "updated_at": "2022-11-29T08:02:07Z", "user_guid": "USR-101ad774-288b-44ed-ad16-da87d522ea20" } } ``` ### Account and Routing Numbers Request account numbers as follows. The response includes information like `account_number`, `routing_number`, and more. 1. Make a `GET` request to the `/account/account_numbers` endpoint. 2. In the `Authorization` header, set the type to `Bearer` and include the `access_token` retrieved in step 1. ```shell Request theme={null} curl -L -X GET 'https://int-api.mx.com/account/account_numbers' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Authorization: Bearer PROCESSOR_TOKEN_GOES_HERE' ``` ```json Response theme={null} { "account_numbers": [ { "account_guid": "ACT-32a64160-582a-4f00-ab34-5f49cc35ed35", "account_number": "6366816006", "guid": "ACN-68c0b681-78c2-4731-9b41-d6e8ae2846cf", "institution_number": null, "loan_guarantor": null, "loan_reference_number": null, "member_guid": "MBR-54feffb9-8474-47bd-8442-de003910113a", "passed_validation": true, "routing_number": "242722023", "sequence_number": null, "transit_number": null, "user_guid": "USR-101ad774-288b-44ed-ad16-da87d522ea20" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` ### Account Owner Information Request account owner or identity information as follows. The response includes information like the name and address of the account's owner. 1. Make a `GET` request to the `/account/account_owners` endpoint. 2. In the `Authorization` header, set the type to `Bearer` and include the `access_token` retrieved in Step 1. ```shell Request theme={null} curl -L -X GET 'https://int-api.mx.com/account/account_owners' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Authorization: Bearer PROCESSOR_TOKEN_GOES_HERE' ``` ```json Response theme={null} { "account_owners": [ { "guid": "ACO-a06b74ec-6a58-4c0b-b437-8de5e03194ac", "user_guid": "USR-101ad774-288b-44ed-ad16-da87d522ea20", "member_guid": "MBR-54feffb9-8474-47bd-8442-de003910113a", "account_guid": "ACT-283132a4-1401-486a-909e-1605f1623d11", "owner_name": "Janita Pollich", "address": "3541 Adrian Street", "city": "North Kishaberg", "state": "Maine", "postal_code": "45054-7764", "country": null, "email": "janita.pollich823@beerpowlowski.ca", "phone": "676-932-5861" }, { "guid": "ACO-74eb553b-2612-4b09-9b8b-a8c2dcdd4025", "user_guid": "USR-101ad774-288b-44ed-ad16-da87d522ea20", "member_guid": "MBR-54feffb9-8474-47bd-8442-de003910113a", "account_guid": "ACT-32a64160-582a-4f00-ab34-5f49cc35ed35", "owner_name": "Janita Pollich", "address": "3541 Adrian Street", "city": "North Kishaberg", "state": "Maine", "postal_code": "45054-7764", "country": null, "email": "janita.pollich823@beerpowlowski.ca", "phone": "676-932-5861" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 7, "total_pages": 1 } } ``` ### Transaction History Request transaction data as follows. The response returns up to 90 days of transaction history. For more information on response fields, see the transaction reference. 1. Make a `GET` request to the `/account/transactions` endpoint. 2. In the `Authorization` header, set the type to `Bearer` and include the `access_token` retrieved in step 1. ```shell Request theme={null} curl -L -X GET 'https://int-api.mx.com/account/transactions' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Authorization: Bearer PROCESSOR_TOKEN_GOES_HERE' ``` ```json Response theme={null} { "transactions": [ { "category": "Restaurants", "created_at": "2022-03-10T08:44:18Z", "date": "2022-03-09", "posted_at": "2022-03-09T16:46:00Z", "status": "POSTED", "top_level_category": "Food & Dining", "transacted_at": "2022-03-09T16:46:00Z", "type": "DEBIT", "updated_at": "2022-03-10T08:44:18Z", "account_guid": "ACT-abf38024-53cd-43ee-93a6-6252e7714a69", "account_id": "account-968af910-7706-4b7c-a815-c7b1a9618e0a", "amount": 18.0, "category_guid": "CAT-006862be-64a0-e778-f035-0936445b9c16", "check_number_string": null, "currency_code": null, "description": "Bob's Test", "extended_transaction_type": "", "guid": "TRN-be454fa0-f3da-455c-80a0-83e54ad94fd2", "id": "transaction-db60fda2-3748-47e9-ba08-294658645e22", "is_expense": true, "is_fee": false, "is_income": false, "is_international": false, "is_recurring": null, "latitude": null, "localized_description": null, "localized_memo": null, "longitude": null, "member_guid": "MBR-54feffb9-8474-47bd-8442-de003910113a", "member_is_managed_by_user": true, "memo": null, "merchant_category_code": 0, "merchant_guid": null, "merchant_location_guid": null, "metadata": "some hard-coded transaction metadata", "original_description": "Bob's Test", "user_guid": "USR-101ad774-288b-44ed-ad16-da87d522ea20", "user_id": "My-Unique-ID", "business_category": null, "business_category_guid": "FCT-230b6f73-145d-42cf-b5a9-176d4fa4fd82", "is_business": false, "is_bill_pay": false, "is_direct_deposit": false, "is_overdraft_fee": false, "is_payroll_advance": false, "is_subscription": false } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` ### Payment Account Information Read the balance data as follows. The response will include the account's balance and other information about the payment account. 1. Make a `GET` request to the `/payment_account` endpoint. 2. In the `Authorization` header, set the type to `Bearer` and include the `access_token` retrieved at the beginning of this guide. ```shell Request theme={null} curl -L -X GET 'https://int-api.mx.com/payment_account' \ -H 'accept: application/vnd.mx.api.v1+json' \ -H 'Authorization: Bearer PROCESSOR_TOKEN_GOES_HERE' ``` ```json Response theme={null} { "payment_account": { "account_guid": "ACT-32a64160-582a-4f00-ab34-5f49cc35ed35", "account_name": "MX Bank Checking", "account_number": "6366816006", "account_type": "CHECKING", "available_balance": 1000, "balance": 1000, "created_at": "2022-03-17T20:38:58Z", "member_guid": "MBR-54feffb9-8474-47bd-8442-de003910113a", "routing_number": "242722023", "transit_number": null, "updated_at": "2022-11-29T08:02:07Z", "user_guid": "USR-101ad774-288b-44ed-ad16-da87d522ea20" } } ``` ## Next Steps At this point, you can use your token to request account numbers, account owner information, or transaction history. Take a look at our API reference if you need information about our endpoints at a glance. # Build a Microdeposits Flow with our API Source: https://docs.mx.com/products/connectivity/microdeposits/api-only Build a microdeposits flow using the Platform API to let end users verify their accounts with institutions that don't support Instant Account Verification. Building a microdeposits flow lets your end users verify their accounts with institutions that don't support Instant Account Verification. This guide shows you that process if you're using our Platform API to power your own connection experience. Learn about Microdeposit fields in the API. Learn about the Microdeposits webhook. After you have an account number, routing number, and account type, request [Create a Microdeposit](/api-reference/platform-api/reference/microdeposits). ```shell Request theme={null} curl -L -X POST 'https://int-api.mx.com/users/:user_guid/micro_deposits' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data-raw '{"micro_deposit":{"account_name":"My test account","account_number":"3331261","account_type":"CHECKING","email":"joshyboy2@example.com","first_name":"Joshy","last_name":"Grobanne","routing_number":"091000019"}}' ``` ```json Response theme={null} { "micro_deposit": [ { "account_name": "My test account", "account_number": "3331261", "account_type": "CHECKING", "email": "example@example.com", "first_name": "Josh", "last_name": "Smith", "routing_number": "091000019", "error_message": null, "guid": "MIC-09ba578e-8448-4f7f-89e1-b62ff2517edb", "institution_code": "mxbank", "institution_name": "MX Bank", "status": "INITIATED", "updated_at": "2023-06-01T19:18:06Z", "verified_at": null } ] } ``` To track the status of microdeposits, you can either use the [Microdeposits webhook](/resources/webhooks/microdeposits) or poll the [Read a Microdeposit for a User](/api-reference/platform-api/reference/microdeposits) endpoint at regular intervals. Approximately 36 hours after creating a microdeposit, begin polling the [Read a Microdeposit for a User](/api-reference/platform-api/reference/microdeposits) endpoint at an interval of 15 minutes (which is the interval MX updates it at) until its `status` is either `DEPOSITED` or `ERRORED`. We recommend waiting 36 hours because microdeposits typically don't reach a `DEPOSITED` or `ERRORED` status for 12 to 36 hours. **NOTE** For a full list of all microdeposit statuses, see [Microdeposit Statuses](/api-reference/platform-api/reference/microdeposits#microdeposit-statuses). If the `status` of the microdeposit is `DEPOSITED`, prompt the end user to verify the deposit amounts and send their input using [Verify Microdeposit](/api-reference/platform-api/reference/microdeposits). If the `status` of the microdeposit is `VERIFIED`, you can check the `connection_status` of the `member` to ensure you can retrieve any data from that connection. # Microdeposits Workflow in the Connect Widget Source: https://docs.mx.com/products/connectivity/microdeposits/connect-widget To verify account information with microdeposits: 1. [Request a microdeposit verification](#1-requesting-workflow) when an end user searches for an institution that doesn't support Instant Account Verification. 2. [Prompt the end user to verify](#2-verifying-workflow) their deposit amounts. ## 1. Requesting Workflow A request workflow for microdeposits To let end users request a microdeposit verification using their account numbers: 1. Request a Widget URL with `widget_type` set to `connect_widget` and `data_request.products` set to include `account_verification`. 2. The widget loads, which triggers the [Connect Loaded](/connect/widget-events#connect-loaded) widget event. 3. End user searches for an institution (which triggers the [Institution Search](/connect/widget-events#institution-search) widget event) then selects an institution (which triggers the [Institution Selected](/connect/widget-events#institution-selected) widget event). 4. The institution the end user selected doesn't support instant account verification. The end user then selects the option to verify using account numbers, which triggers the [Microdeposit Flow Loaded](/connect/widget-events#microdeposit-flow-loaded) widget event. * **Routing number**: If the user enters a blocked routing number, the [Blocked Routing Number](/connect/widget-events#microdeposit-blocked-routing-number) widget event is triggered. Depending on the reason given in the event, the verification process either can't proceed or the widget will suggest the end user follows the instant account verification flow. * **Account information**: Such as account type and number. * **Account holder information**: Such as first name, last name, and email. 5. End user reviews and confirms what they entered. 6. [Account Details Submitted](/connect/widget-events#microdeposit-account-details-submitted) widget event triggers, containing a `microdeposit_guid` in the `metadata`. You **must** save this `microdeposit_guid`, since you'll use it when the end user returns to verify their deposit amounts. 7. Widget informs the end user to check back soon after they see two small deposits in their account to confirm those amounts. When the end user selects the primary button on this screen, the [Microdeposit Come Back, Primary Action Selected](/connect/widget-events#microdeposit-come-back-primary-action-selected) widget event is triggered. **NOTE** In the microdeposit flow, no `member` is created. ## 2. Verifying Workflow A verification workflow for microdeposits To track the status of microdeposits, you can either use the [Microdeposits webhook](/resources/webhooks/microdeposits) or poll the [Read a Microdeposit for a User](/api-reference/platform-api/reference/microdeposits) endpoint at regular intervals. This section outlines the microdeposit verification workflow using polling to check the status. 1. Wait at least 36 hours after creating a microdeposit, then begin polling the [Read a Microdeposit](/api-reference/platform-api/reference/microdeposits) endpoint at an interval of 15 minutes until its `status` is either `DEPOSITED` or `ERRORED`. Starting at 36 hours ensures deposits have been processed, though you can begin polling before this time if needed. 2. Once the `status` is `DEPOSITED`, load the Connect Widget. Set `data_request.products` to include `account_verification` and `current_microdeposit_guid` to the `microdeposit_guid` you captured from the [Account Details Submitted](/connect/widget-events#microdeposit-account-details-submitted) widget event. 3. The end user will then enter the two small deposit amounts. * **Incorrect Amounts**: If the amounts are entered incorrectly, the widget will display an error. The end user can reenter the amounts or select the primary button on this screen, which triggers the [Microdeposit Error, Primary Action Selected](/connect/widget-events#microdeposit-error-primary-action-selected) widget event. You must listen for this event, close the widget, and delete the `microdeposit_guid` by calling the [Delete a Microdeposit](/api-reference/platform-api/reference/microdeposits) endpoint. * **Correct Amounts**: If the amounts are entered correctly, the [Microdeposit Verified](/connect/widget-events#microdeposit-verified) widget event is triggered. The end user will see a **Verified** screen and then select **Confirm**. This action triggers the [Microdeposit Verified, Primary Action Selected](/connect/widget-events#microdeposit-verified-primary-action-selected) widget event, signaling that you can now safely close the widget and delete the `microdeposit_guid` using the [Delete a Microdeposit](/api-reference/platform-api/reference/microdeposits) endpoint. **SUCCESS** You built a flow to let end users verify their accounts using microdeposits. ## Related Widget Events The following table lists all the widget events that can be triggered during the microdeposits workflow in the Connect Widget. See [Widget Events](/connect/widget-events) to understand how to handle these events and for more complete descriptions and guidance for each event. | Widget Event | Description | | :----------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | | [Connect Loaded](/connect/widget-events#connect-loaded) | Sent when the Connect Widget loads. | | [Institution Search](/connect/widget-events#institution-search) | Sent when the end user searches for an institution. | | [Institution Selected](/connect/widget-events#institution-selected) | Sent when an end user selects an institution from the institution list. | | [Microdeposit Flow Loaded](/connect/widget-events#microdeposit-flow-loaded) | Sent when the microdeposit flow is loaded in the Connect Widget. | | [Microdeposit Blocked Routing Number](/connect/widget-events#microdeposit-blocked-routing-number) | Sent when the end user submits a blocked routing number on the **Enter Details** step. | | [Microdeposit Account Details Submitted](/connect/widget-events#microdeposit-account-details-submitted) | Sent when the end user submits account details for a given institution for the first time and a `microdeposit` object is created on the MX system. | | [Microdeposit Come Back, Primary Action Selected](/connect/widget-events#microdeposit-come-back-primary-action-selected) | Sent when the end user selects the primary button on the **Come Back** step. This step is visible while the microdeposit is in the `REQUESTED` status. | | [Microdeposit Error, Primary Action Selected](/connect/widget-events#microdeposit-error-primary-action-selected) | Sent when the end user selects the primary button on the **Error** step. This page is visible after entering deposits and getting a `PREVENTED` status. | | [Microdeposit Verified](/connect/widget-events#microdeposit-verified) | Sent when an end user successfully verifies the microdeposit amounts. | | [Microdeposit Verified, Primary Action Selected](/connect/widget-events#microdeposit-verified-primary-action-selected) | Sent when the end user selects the primary button on **Verified** step. This step is visible after entering the correct deposit amounts. | # Microdeposits Source: https://docs.mx.com/products/connectivity/microdeposits/index Verify account details by making two, small ACH deposits for end user confirmation. **NEW TO MX CONNECTIVITY?** See the [Connectivity Overview](/products/connectivity/overview) to learn about our Connectivity products and integration options. Use the Connect Widget and Platform API to let end users connect to their accounts. Use the Platform API to power a non-MX UI connection experience. With Microdeposits, make two, small ACH deposits into a user's account using the provided account and routing number. You can then require that the end user confirm the exact amount of each deposit. In doing so, you can verify that the consumer owns the account and meets NACHA requirements for account verification. You must have Microdeposits enabled by MX. Please contact MX if this feature hasn't been enabled. **INFO** MX doesn't debit back the microdeposits that are credited to a user's account. ## Microdeposit Sample Data This sample response shows the data you can expect to get for microdeposits. ```json theme={null} { "micro_deposit": { "account_name": "My Test Account", "account_number": "33331261", "account_type": "CHECKING", "created_at": "2023-06-01T21:12:49Z", "email": "example@example.com", "error_code": null, "error_message": null, "first_name": "Josh", "guid": "MIC-d1351d87-fafc-4935-b2f0-158973e68d34", "institution_code": null, "institution_name": null, "last_name": "Smith", "routing_number": "091000019", "status": "REQUESTED", "updated_at": "2023-06-01T21:12:49Z", "verified_at": null } } ``` ## Integration Options You can integrate Microdeposits by using our Connect Widget, or by using our API to power your own connection experience. See one of the following guides: * [Integrate Microdeposits using our Connect Widget](/products/connectivity/microdeposits/connect-widget) * [Integrate Microdeposits using our API for your own connection experience](/products/connectivity/microdeposits/api-only) ## Microdeposit Limits Users can attempt to verify the amounts associated with a given microdeposit `guid` three times. After the third incorrect attempt, the microdeposit moves to a `PREVENTED` status and the process can no longer continue. If the user wishes to try again, they must start a new microdeposit verification. Users can verify up to three accounts per email address using microdeposits. For instance, if a user had four different accounts all associated with the same email, only three accounts could be verified using microdeposits. ## Timing and Polling The time it takes for microdeposits to appear can vary. Deposits initiated in the morning might appear by evening, or they could take up to 7 days. Wait at least 36 hours after initiating a microdeposit before checking for status changes to ensure deposits have been processed. You can start polling before this time (for example, after 24 hours), but you may not see `DEPOSITED` or `ERRORED` status changes until 12 to 36 hours after initiation. Poll no more frequently than once every 15 minutes, as MX only checks status with the deposit provider every 15 minutes. More frequent polling provides no benefit. ## Data Retention Microdeposits that remain in the status `INITIATED`, `REQUESTED`, or `DEPOSITED` for 21 or more days are soft-deleted from the MX Platform. ## Block Lists You can prevent microdeposit verifications with certain institutions by using a routing number block list. Institutions associated with any routing number on a block list will not be available for microdeposit verifications. To block an institution, visit the Client Dashboard. See [Block an Institution](/resources/client-dashboard#block-an-institution) for more info. ## Test Scenarios You can simulate some common microdeposit scenarios in our integrations environment using the microdeposit amounts we provide. **USING THE CONNECT WIDGET?** See [Testing Microdeposits in the Connect Widget](#testing-microdeposits-in-the-connect-widget). The following table shows the fields and microdeposit amounts you must provide to simulate each scenario. Use different account numbers to avoid errors. For field requirements, see [Formats](#formats). | Test Scenario | Inputs | Microdeposit Amounts | | :------------------------------------------ | :------------------------------------------------------------------- | :-------------------------------------------------------- | | A Successful Verification | First name, last name, email address, routing number, account number | `0.09` for both amounts | | A Failed Verification that Can't Be Retried | First name, last name, email address, routing number, account number | `0.04` for the first amount, `0.01` for the second amount | | A Failed Verification that Can Be Retried | First name, last name, email address, routing number, account number | `0.02` for both amounts | ### Formats The following shows the accepted format for each input field. | Input Field | Format | | :------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | First Name | Must be less than or equal to 50 characters and contain no special characters, for example, `Dave` but not `D#ve`. | | Last Name | Must be less than or equal to 50 characters and contain no special characters. For example, `Smith` but not `Sm_th`. | | Email | Must be in standard email format, for example, `example@email.com`. | | Routing Number | Must follow standard American Banking Association rules for routing numbers, for example, `091000019` but not `222222226` or `021000021`. | | Account Number | Any integer that begins with `3333` (for example, `333312345`) will be interpreted as a valid account number. Valid account numbers produce an `INITIATED` status for the microdeposit object that is created, followed by a `REQUESTED` status; `REQUESTED` will change to `DEPOSITED` after two minutes. | | Microdeposit Amounts | Specific amounts correspond to specific scenarios, described in [Test Scenarios](#test-scenarios). | ### Testing Microdeposits in the Connect Widget For the microdeposits flow to occur in the Connect Widget: 1. Set `data_request.products` to include `account_verification` in your widget URL request. If you're simulating a user returning to the Connect Widget to verify their microdeposit amounts, also set `current_microdeposit_guid` to the `guid` of the microdeposit the user needs to verify. 2. In the Connect Widget, enter an input into the searchbar that doesn't result in an institution. For example, you can enter "vvv." 3. Select **Connect with account numbers**. 4. Enter the inputs as specified in [one of the test scenarios](#test-scenarios). # Best Practices Source: https://docs.mx.com/products/connectivity/overview/best-practices These best practices focus on preventing ACH returns when using Instant Account Verification (IAV) for account verification and transfers. For broader guidance on implementing the Connect Widget and driving user engagement, see [Connect Widget Best Practices](/connect/best-practices). ## Reducing ACH Returns To limit the number of ACH returns: * Read the account balance immediately after an IAV. * Submit an ACH transaction as soon as possible after an IAV. * Run a balance check and read the account balance before submitting future ACH transfers for an account. The following table outlines the preventative steps and resolution steps for each return code. | Return Code | Preventative Steps | Resolution Steps | | :------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **R01 — Insufficient Funds** | 1. Read the account balance immediately after an IAV to confirm there are sufficient funds.
2. Submit an ACH transaction as soon as possible after an IAV.
3. Run a balance check and read the account balance before submitting future ACH transfers for an account. | Wait until there are sufficient funds before submitting another ACH transaction for the account. | | **R02 — Account Closed** | Run a balance check and then read the account details to confirm that the account is still open: `is_closed: false`. |
  • Stop all future transfer requests for this account.
  • Have the end user verify a different account.
| | **R03 — Account Not Found** | N/A | 1. Make sure that an [account owner identification (identity)](/products/connectivity/account-owner-identification/) has been performed before initiating an ACH transaction.
2. Confirm that the name provided by the end user is the same as the one from the account owner verification. | | **R04 — Invalid Account Number** | Confirm that the `passed_validation` field is `true` before submitting an ACH transaction for the account. | Stop all future transfer requests for this account. | ### Run Only One IAV Per Account There is usually no need to run multiple IAV jobs for a single account. Once you have the account and routing/transit numbers, these can be reused any number of times for multiple future ACH transfers. There is no need to run an IAV before each ACH transfer with the same account. However, for ACH transfers that occur more than a few hours after the initial IAV, you must run a [balance check](/products/connectivity/balance-checks) and [read the account balance](/api-reference/platform-api/reference/read-account) in order to confirm the account is still open and there are sufficient funds in it. # Integrate without using MX's Connect Widget Source: https://docs.mx.com/products/connectivity/overview/connectivity-integration-guides/api-only-flow By the end of this guide, you'll be able to connect a user to their financial institution and retrieve their financial data using the Platform API to power a non-MX UI connection experience. **LOOKING FOR OUR LEGACY GUIDES?** If you're using Platform API v2011101, see [Legacy Guides](/other/legacy-connectivity-guides). ## Prerequisites Before using this guide, ensure the following: * You've signed up for the Client Dashboard and can access your API keys * Your IP addresses are whitelisted in the Client Dashboard * Users exist on the MX system or you've [created a user](/products/connectivity/overview/connectivity-integration-guides/#creating-users) * You have your own end-user facing connection experience instead of using our Connect Widget * You have [registered for OAuth](/resources/oauth-guide/#registration), unless you're using our test institution * You've set up how you'll [send held data](/products/connectivity/overview/held-data/) to MX (if your institution has held data) ## 1. Search for an Institution To connect a user to a specific financial institution, you first need to find that institution in MX's institution list. Make a GET request to the [List Institutions](/api-reference/platform-api/reference/list-institutions) endpoint and set the `name` query parameter to list only institutions in which the appended string appears. You can also check which institutions support the products (data) you need before connecting users by using the `supported_products` parameter with the [List Institutions](/api-reference/platform-api/reference/list-institutions). The response returns a paginated list of institutions, filtered by the query parameters you set. The next step covers which fields to look for in the response. **INFO** For caching the institutions list to improve performance, see [Caching our Institutions List and Credentials](/api-reference/platform-api/reference/institutions#caching-our-institutions-list-and-credentials). ```shell Request theme={null} curl -i -X GET 'https://int-api.mx.com/institutions?name=mx' \ -u 'client_id:api_key' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Accept-Version: v20250224' ``` ```json Response theme={null} { "institutions": [ { "code": "mxbank", "created_at": "2025-02-13T18:08:00+00:00", "forgot_password_url": "https://example.url.mxbank.com/forgot-password", "forgot_username_url": "https://example.url.mxbank.com/forgot-username", "guid": "INS-1572a04c-912b-59bf-5841-332c7dfafaef", "instructional_text": "Some instructional text for end users.", "instructional_text_steps": [ "Step 1: Do this.", "Step 2: Do that." ], "is_disabled_by_client": false, "is_hidden": true, "iso_country_code": "US", "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", "supported_products": [ "account_verification" ], "supports_oauth": true, "supports_tax_document": true, "trouble_signing_in_url": "https://example.url.mxbank.com/login-trouble", "url": "https://www.mxbank.com" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` ## 2. Get the Institution's Requirements The response from the previous step included a `supports_oauth` field that reflects 2 conditions: 1. The institution supports OAuth. 2. You have gone through the [OAuth registration process](https://dashboard.mx.com/oauth-settings). If this field is `true`, you must create an OAuth member in the next step. If this field is `false`, make a request to the [List Institution Credentials](/api-reference/platform-api/reference/list-institution-credentials) endpoint and set the institution `code` from the previous step in the path. The following example uses `mxbank` as the `code` and returns the `guid` for each required credential, which you'll use to match the end user's credentials to the required credential types. ```shell Request theme={null} curl -i -X GET 'https://int-api.mx.com/institutions/mxbank/credentials' \ -u 'client_id:api_key' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Accept-Version: v20250224' ``` ```json Response theme={null} { "credentials": [ { "display_order": 1, "field_name": "LOGIN", "field_type": "LOGIN", "guid": "CRD-9f61fb4c-912c-bd1e-b175-ccc7f0275cc1", "label": "Username", "type": "TEXT" }, { "display_order": 2, "field_name": "PASSWORD", "field_type": "PASSWORD", "guid": "CRD-e3d7ea81-aac7-05e9-fbdd-4b493c6e474d", "label": "Password", "type": "TEXT" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 2, "total_pages": 1 } } ``` ## 3. Create Member Now that you have the institution's authentication requirements, create the `member` and specify the data to retrieve after the connection is established. The products you set in the Create Member request (through the `data_request.products`) determine what data will be aggregated. If the institution's `supports_oauth` field is `true`, create an OAuth member (see our [OAuth guides](/resources/oauth-guide#guides)). Otherwise, create a credential-based member as shown below. To create a credential-based member, you need the `user_guid`, `institution_code`, and credential values from the end user. The following example uses MX Bank test credentials (username: `mxuser`, password: `password`). Make a request to the [Create Member](/api-reference/platform-api/reference/create-member) endpoint (`POST /users/{user_guid}/members`): * **Required:** Put the `user_guid` in the path. * **Required:** Include the credential GUIDs and their values in the `credentials` array. * **Required:** Set `data_request.products` to define the data you want to aggregate. * **Recommended:** Set `id` to a unique value when creating a member so you can sync between your systems and ours. * **Recommended:** Set `metadata`. * **Optional:** Disable background aggregation by setting `background_aggregation_is_disabled` to `true`. For more info, see [Background Aggregation](/products/connectivity/account-aggregation#background-aggregation). The response returns with the newly created `member` and indicates that the connection process has started: `connection_status` is `CREATED` and `is_being_aggregated` is `true`. **WARNING** Don't add multiple members that connect to the same `institution` using the same `credentials` on the same `user`. This will result in a `409 Conflict` error. ```shell Request theme={null} curl -i -X POST 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members' \ -u 'client_id:api_key' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Accept-Version: v20250224' \ -d '{ "member": { "credentials": [ { "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da", "value": "mxuser" }, { "guid": "CRD-1ec152cd-e628-e81a-e852-d1e7104624da", "value": "password" } ], "id": "member-9876", "institution_code": "mxbank", "metadata": "some metadata" } }' ``` ```json Response theme={null} { "member": { "aggregated_at": null, "background_aggregation_is_disabled": false, "connection_status": "CREATED", "guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "id": "member-9876", "institution_code": "mxbank", "is_being_aggregated": false, "is_managed_by_user": true, "is_oauth": false, "metadata": "some metadata", "name": "MX Bank", "successfully_aggregated_at": null, "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "partner-2345" } } ``` ## 4. Monitor Connection Statuses When a user connects to an institution, a `member` is created in the MX system. To proactively resolve connections issues that may arise, such as MFA challenges or credential changes, you **must** monitor the `connection_status` of each `member` that belongs to a user. For guidance on how to handle each possible status, see [Member Connection Statuses](/api-reference/platform-api/reference/members#member-connection-statuses). ## 5. Ensure Data Aggregated To ensure that the member is in a state where you can retrieve data, you must implement a polling workflow: 1. Request the [Read Member Status](/api-reference/platform-api/reference/read-member-status) endpoint. 2. In the response, check the `connection_status` and `is_being_aggregated` fields. 3. If `connection_status` is `CONNECTED` and `is_being_aggregated` is `false`, exit this workflow and retrieve the data. If not, we recommend waiting 3 seconds before repeating this polling workflow. ## 6. Read Data Once the member's `connection_status` is `CONNECTED` and `is_being_aggregated` is `false`, retrieve the data using the endpoints below. **INFO** Not every field will populate for each product, as data availability depends on what the institution provides. | Requested Data | Retrieve Data | | :------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `accounts` and/or `transactions` | [List Accounts](/api-reference/platform-api/reference/list-user-accounts), [List Member Accounts](/api-reference/platform-api/reference/list-member-accounts), [Read Account](/api-reference/platform-api/reference/read-account), [Read Account by Member](/api-reference/platform-api/reference/read-account-by-member), [List Transactions by Account](/api-reference/platform-api/reference/list-transactions-by-account), [List Transactions](/api-reference/platform-api/reference/list-transactions), or [Read Transaction](/api-reference/platform-api/reference/read-transaction) | | `identification` | [List Account Owners by Member](/api-reference/platform-api/reference/list-account-owners-by-member) | | `verification` | [List Account Numbers by Member](/api-reference/platform-api/reference/list-account-numbers-by-member) or [List Account Numbers by Account](/api-reference/platform-api/reference/list-account-numbers-by-account) | | `statements` | 1. [List Statements by Member](/api-reference/platform-api/reference/list-statements-by-member) or [Read Statement by Member](/api-reference/platform-api/reference/read-statement-by-member)
2. (Optional) [Download Statement PDF](/api-reference/platform-api/reference/download-statement-pdf) | | `transaction_history` | 1. [List Member Accounts](/api-reference/platform-api/reference/list-member-accounts), [Read Account](/api-reference/platform-api/reference/read-account), or another `GET` accounts endpoint and save the resulting `guid`
2. Use the `guid` from the previous response in [List Transactions by Account](/api-reference/platform-api/reference/list-transactions-by-account) | | `investments` | [List Holdings by Member](/api-reference/platform-api/reference/list-holdings-by-member), [List Holdings by User](/api-reference/platform-api/reference/list-holdings-by-user), [List Holdings by Account](/api-reference/platform-api/reference/list-holdings-by-account), or [Read Holding](/api-reference/platform-api/reference/read-holding) | | `rewards` | [List Rewards](/api-reference/platform-api/reference/list-rewards) or [Read Reward](/api-reference/platform-api/reference/read-reward) | ## 7. Update Data Later **NOTE** MX automatically aggregates account and transaction data approximately every 24 hours. Check the `successfully_aggregated_at` field to determine if manual aggregation is needed. To refresh data after the initial connection: 1. Make a `POST` request using the appropriate endpoint from the table below. 2. Verify aggregation is complete using the workflow from step 5. 3. Retrieve the updated data. | Requested Data | Aggregate Data | Retrieve Data | | :---------------------------- | :------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `accounts` and `transactions` | [Aggregate Member](/api-reference/platform-api/reference/aggregate-member) | [List Accounts](/api-reference/platform-api/reference/list-user-accounts), [List Member Accounts](/api-reference/platform-api/reference/list-member-accounts), [Read Account](/api-reference/platform-api/reference/read-account), [Read Account by Member](/api-reference/platform-api/reference/read-account-by-member), [List Transactions by Account](/api-reference/platform-api/reference/list-transactions-by-account), [List Transactions](/api-reference/platform-api/reference/list-transactions), or [Read Transaction](/api-reference/platform-api/reference/read-transaction) | | `identification` | [Identify Member](/api-reference/platform-api/reference/identify-member) | [List Account Owners by Member](/api-reference/platform-api/reference/list-account-owners-by-member) | | `verification` | [Verify Member](/api-reference/platform-api/reference/verify-member) | [List Account Numbers by Member](/api-reference/platform-api/reference/list-account-numbers-by-member) or [List Account Numbers by Account](/api-reference/platform-api/reference/list-account-numbers-by-account) | | `statements` | [Fetch Statements](/api-reference/platform-api/reference/fetch-statements) | 1. [List Statements by Member](/api-reference/platform-api/reference/list-statements-by-member) or [Read Statement by Member](/api-reference/platform-api/reference/read-statement-by-member)
2. (Optional) [Download Statement PDF](/api-reference/platform-api/reference/download-statement-pdf) | | `transaction_history` | [Extend History](/api-reference/platform-api/reference/extend-history) | 1. [List Member Accounts](/api-reference/platform-api/reference/list-member-accounts), [Read Account](/api-reference/platform-api/reference/read-account), or another `GET` accounts endpoint and save the resulting `guid`
2. Use the `guid` from the previous response in [List Transactions by Account](/api-reference/platform-api/reference/list-transactions-by-account) | | `investments` | [Aggregate Member](/api-reference/platform-api/reference/aggregate-member) | [List Holdings by Member](/api-reference/platform-api/reference/list-holdings-by-member), [List Holdings by User](/api-reference/platform-api/reference/list-holdings-by-user), [List Holdings by Account](/api-reference/platform-api/reference/list-holdings-by-account), or [Read Holding](/api-reference/platform-api/reference/read-holding) | | `rewards` | [Fetch Rewards](/api-reference/platform-api/reference/fetch-rewards) | [List Rewards](/api-reference/platform-api/reference/list-rewards) or [Read Reward](/api-reference/platform-api/reference/read-reward) | **SUCCESS** You've used our Platform API to build connections between a user and their financial institution and can retrieve data from that connection. # Integrate using MX's Connect Widget Source: https://docs.mx.com/products/connectivity/overview/connectivity-integration-guides/connect-widget-flow By the end of this guide, you'll be able to connect a user to their financial institution, resolve connection errors, and retrieve financial data using the Platform API and [Connect Widget](/connect). **LOOKING FOR PLATFORM V2011101 GUIDES?** If you're using Platform API v2011101, see [Legacy Guides](/other/legacy-connectivity-guides). ## Prerequisites Before using this guide, ensure the following: * You've signed up for the Client Dashboard and can access your API keys * Your IP addresses are whitelisted in the Client Dashboard * Users exist on the MX system or you've [created a user](/products/connectivity/overview/connectivity-integration-guides/#creating-users) * You have [registered for OAuth](/resources/oauth-guide/#registration), unless you're using our test institution * You have set up how you'll [send held data](/products/connectivity/overview/held-data/) to MX (if your institution has held data) ## 1. Get the Widget URL To open the Connect Widget, you'll use the [Request Widget URL](/api-reference/platform-api/reference/request-widget-url) endpoint to retrieve a unique URL. The parameters you set in this request determine how the widget behaves. **INFO** The URL expires after ten minutes or upon first use, whichever occurs first. You'll need to obtain a new URL each time the page loads or reloads. In this request, set `widget_type` to `connect_widget` and `data_request.products` to include the products you want to aggregate. **Considerations** The products you set in your widget URL request (through the `data_request.products`) determine what data will be aggregated and which institutions appear in the widget search results. You can define the products using the following values. **NOTE** Balance data is always included and doesn't need to be set. | Product | Value | | :--------------------------- | :---------------------- | | Instant Account Verification | `account_verification` | | Account Owner Identification | `identity_verification` | | Account Aggregation | `transactions` | | Extended History | `transaction_history` | | Statements | `statements` | | Investments | `investments` | | Rewards | `rewards` | **INFO** Not every field will populate for each product, as data availability depends on what the institution provides. Specifying multiple products restricts the widget to show only institutions that support **all** the requested products. This filtering affects conversion in the following ways: * Fewer Available Institutions: Many institutions support only one product. More products requested means fewer institutions displayed to users. For example, requesting both `account_verification` and `identity_verification` will only show institutions that are capable of providing both products. * OAuth Consent Requirements: For OAuth institutions, users must grant permission for all requested products. If they decline any permission, the connection will fail and they'll need to restart the OAuth flow. Balance your data needs against potential reduction in available institutions and connection success rates. ```shell Request theme={null} curl -i -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -u 'client_id:api_key' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ -H 'Accept-Version: v20250224' \ -d '{ "widget_url": { "widget_type": "connect_widget", "data_request": { "products": [ "account_verification" ] } } }' ``` ```json Response theme={null} { "widget_url": { "type": "connect_widget", "url": "https://int-widgets.moneydesktop.com/md/connect/yxcdk7f1nb99jwApp34lA24m0AZ8rzprgmw17gm8z8h2AzjyAnd1rj42qfv42r3xnn07Amfwlg3j09hwp8bkq8tc5z21j33xjggmp2qtlpkz2v4gywfhfn31l44tx2w91bfc2thc58j4syqp0hgxcyvA4g7754hk7gjc56kt7tc36s45mmkdz2jqqqydspytmtr3dAb9jh6fkb24f3zkfpdjj0v77f0vmrtzvzxkmxz7dklsq8gd0gstkbhlw5bgpgc3m9mAtpAcr2w15gwy5xc4blgxppl42Avnm63291z3cyp0wm3lqgmvgzdAddct423gAdqxdlfx5d4mvc0ck2gt7ktqgks4vxq1pAy5", "user_id": "u-1234" } } ``` ## 2. Embed the Connect Widget The following guides are available to help you embed the widget, depending on your needs: * [Web Widget SDK](/connect/guides/web-sdk) * [React Native SDK](/connect/guides/react-native-sdk) * [Embed in a browser](/connect/guides/widget_loader_deprecated) using the JavaScript Loader * [Embed in a Webview](/connect/guides/webviews) **BEST PRACTICES** Follow our [best practices](/connect/best-practices) to enhance the user experience and improve conversion. ## 3. Handle Widget Events To let you know what's happening inside the widget as the widget takes the user through the connection process, MX sends widget events. For example, the **Connect Loaded** event tells you when the widget loads. While you can leverage some events for data-tracking purposes, others you must handle. The way you'll handle these events depends on the method you chose to embed the widget. For a list of all events and how to handle them, see [Widget Events](/connect/widget-events). **Considerations** For a list of important widget events and what to do when you retrieve them, see [Notable Widget Events](/connect/widget-events#notable-widget-events). Your native app must intercept **all** widget events and decide to either block or allow the event and send the user to the browser (like when a user is trying to visit a bank's site or trying to authenticate via OAuth). Failure to appropriately handle navigation events in a WebView can lead to broken behavior, like replacing the Connect Widget with the bank's website with no way for the user to get back. ## 4. Build an OAuth Flow **REGISTERING FOR OAUTH** Before you can use OAuth with real institutions, you must [register for OAuth](/resources/oauth-guide/#registration) and request production access. If you haven't registered yet, you can still use our test institutions. [OAuth](/resources/oauth-guide) is a secure and standardized way to perform authentication without exchanging sensitive credentials like usernames and passwords. To connect a user to their financial institution using OAuth, you'll follow this general workflow: 1. Send the user to the financial institution's site 2. Return the user to the Connect Widget **REACT NATIVE SDK** If you're using our [React Native SDK](/connect/guides/react-native-sdk), OAuth is automatically handled. Follow our [separate guide](/resources/oauth-guide/oauth-in-connect-widget) to connect users to institutions that require OAuth. You can use the MXCU test institution to test a more realistic OAuth flow. See [Testing OAuth with MXCU](/resources/test-platform/mxcu/testing-oauth-with-mxcu). ## 5. (Optional) Build a Microdeposits Flow If you're using the widget to verify account details, you can use [Microdeposits](/products/connectivity/microdeposits) so users can still verify their details with institutions that don't support [Instant Account Verification](/products/connectivity/instant-account-verification). For more info, see [Microdeposits Workflow in the Connect Widget](/products/connectivity/microdeposits/connect-widget). ## 6. Monitor Connection Statuses When a user connects to an institution, a `member` is created in the MX system. To proactively resolve connections issues that may arise, such as MFA challenges or credential changes, you **must** monitor the `connection_status` of each `member` that belongs to a user. For guidance on how to handle each possible status, see [Member Connection Statuses](/api-reference/platform-api/reference/members#member-connection-statuses). ## 7. Ensure Data Aggregated If the `member` has a `connection_status` of `CONNECTED` and the `is_being_aggregated` field is `false`, you're ready to retrieve the data from this connection. When the widget is open, the [Member Connected](/connect/widget-events#member-connected) widget event will signal to you when the connection between the user and the financial institution has been successfully established. To handle cases where the user initiated a connection to their institution then closed the widget before it finished aggregating, you must implement a polling workflow: 1. Request the [Read Member Status](/api-reference/platform-api/reference/read-member-status) endpoint. 2. In the response, check the `connection_status` and `is_being_aggregated` fields. 3. If `connection_status` is `CONNECTED` and `is_being_aggregated` is `false`, exit this workflow and retrieve the data. If not, we recommend waiting 3 seconds before repeating this polling workflow. ## 8. Retrieve Data If the member has a `connection_status` of `CONNECTED` and the `is_being_aggregated` field is `false`, you're ready to retrieve the data from this connection. **TIP** Consider checking the `successfully_aggregated_at` field. Depending on when the member last aggregated successfully, you can choose to aggregate the `member` again. The following table shows you how to retrieve the data you set in your widget URL request. For your convenience, some data may have multiple endpoints for its retrieval. | Requested Data | How to Retrieve It | | :--------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `accounts` or `transactions` | [List Accounts](/api-reference/platform-api/reference/list-user-accounts), [List Member Accounts](/api-reference/platform-api/reference/list-member-accounts), [Read Account](/api-reference/platform-api/reference/read-account), [Read Account by Member](/api-reference/platform-api/reference/read-account-by-member), [List Transactions by Account](/api-reference/platform-api/reference/list-transactions-by-account), [List Transactions](/api-reference/platform-api/reference/list-transactions), or [Read Transaction](/api-reference/platform-api/reference/read-transaction) | | `identification` | [List Account Owners by Member](/api-reference/platform-api/reference/list-account-owners-by-member) | | `verification` | [List Account Numbers by Member](/api-reference/platform-api/reference/list-account-numbers-by-member) or [List Account Numbers by Account](/api-reference/platform-api/reference/list-account-numbers-by-account) | | `statements` | 1. [List Statements by Member](/api-reference/platform-api/reference/list-statements-by-member) or [Read Statement by Member](/api-reference/platform-api/reference/read-statement-by-member)
2. (Optional) [Download Statement PDF](/api-reference/platform-api/reference/download-statement-pdf) | | `transaction_history` | 1. [List Member Accounts](/api-reference/platform-api/reference/list-member-accounts), [Read Account](/api-reference/platform-api/reference/read-account), or another `GET` accounts endpoint and save the resulting `guid`
2. Use the `guid` from the previous response in [List Transactions by Account](/api-reference/platform-api/reference/list-transactions-by-account) | | `investments` | [List Holdings by Member](/api-reference/platform-api/reference/list-holdings-by-member), [List Holdings by User](/api-reference/platform-api/reference/list-holdings-by-user), [List Holdings by Account](/api-reference/platform-api/reference/list-holdings-by-account), or [Read Holding](/api-reference/platform-api/reference/read-holding) | | `rewards` | [List Rewards](/api-reference/platform-api/reference/list-rewards) or [Read Reward](/api-reference/platform-api/reference/read-reward) | **SUCCESS** You've embedded our widget and can now retrieve data from a user's connection to their financial institution! # Connect Accounts Source: https://docs.mx.com/products/connectivity/overview/connectivity-integration-guides/index After users connect their accounts, you can retrieve financial data such as account balances, transaction history, account numbers, and more. To do this, integrate using either MX's Connect Widget or using only MX's Platform API. Your use case and technology determines which method of integration you should use. Use the following table to decide which integration method is the best for you. | Method | Description | When to Use | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Connect Widget** | The [Connect Widget](/connect) is a pre-built, client-facing component that's presented to end users. It allows them to select and connect to their accounts.

You can use the Connect Widget for Web and Mobile applications. SDKs are available for Web and React Native. | You want to use our ready-made connection experience that handles:
  • Gathering end user’s credentials
  • Connecting to end user’s accounts to gather financial data
  • PostMessages for notification of status
  • OAuth (optional)
| | **API Only** | Use API endpoints to connect to an end user's account and fetch data, using a non-MX UI connection experience.

You’ll have to manage connection statuses, webhooks, and more manually with this integration. | You want to build your own end-user facing connection experience instead of using our Connect Widget, or you’re looking to build a customized verification solution within your application. | ## Sending Held Data For financial institutions that have held data to share with MX, see [Sending Held Data](/products/connectivity/overview/held-data/). ## Creating Users A user represents your end user in the MX system. There are two ways to create a user on the MX system: * Platform API * [MDX Real Time](/api-reference/more-apis/mdx/mdx-real-time/reference/users/create-user) To create a user with the Platform API, make a request to the [Create User](/api-reference/platform-api/reference/users) endpoint. **BEST PRACTICES** In this request, we recommend that you include: * A unique `id` of your choice. See [Identifiers and Metadata](/api-reference/platform-api/overview/formats-requirements#identifiers-and-metadata). * `metadata`, such as the date the user was created or the end user's name. Don't include any sensitive information here, such as credentials. * A first name, last name, and email if the data is available. This data greatly improves analytics data and troubleshooting for support issues on specific users. ## Next Steps Use one of these guides based on the integration method you chose. Use our Connect Widget and Platform API to let end users connect to their accounts. Use our Platform API and a non-MX connection experience. # MX Data Architecture Source: https://docs.mx.com/products/connectivity/overview/data-architecture The MX platform is built on seven core resources: accessors, clients, users, members, institutions, accounts, and transactions. ## Diagram Here's how these resources relate to each other. Data Architecture ## Resources The following table describes each resource, its relationships, and who creates it. | Resource | Description | Relationship | Created By | | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------ | | Accessors | Top-level hierarchy representing MX clients. Each has an API key for authentication and manages IP whitelisting. | Can have multiple clients | MX only | | Clients | Individual MX clients within an accessor. Each has a `client_id` for authentication and serves as the customization point for product branding. **Example:** A banking provider serving 100 institutions has one accessor with 100 clients—one per institution. | Belongs to one accessor; can have multiple users | MX only | | [Users](/api-reference/platform-api/reference/users) | End users whose financial data is aggregated and analyzed. | Belongs to one client; can have multiple members | MX clients | | [Members](/api-reference/platform-api/reference/members) | Connection between a user and an institution. Stores credentials, handles MFA, and performs aggregation. Can have multiple accounts. Duplicates not allowed. **Example:** A user with checking and savings at Wells Fargo has one member with two accounts. | Belongs to one user; can have multiple accounts | MX clients or end users | | [Institutions](/api-reference/platform-api/reference/institutions) | Financial institutions like Chase or Wells Fargo. A real-world institution may have multiple objects if divisions use separate systems. A client may set a default institution representing the partner organization itself. **Example:** Wells Fargo may have separate objects for mortgages, banking, and credit cards. | Referenced by members | MX only | | [Accounts](/api-reference/platform-api/reference/accounts) | Individual financial accounts (checking, savings, mortgage, 401(k), and [more](../../../api-reference/platform-api/reference/accounts#account-types)). | Belongs to one member; can have multiple transactions | MX products, aggregation, or MDX On Demand | | [Transactions](/api-reference/platform-api/reference/transactions) | Money movement into or out of an account (purchases, deposits, transfers, withdrawals, and so on). | Belongs to one account | MX products, aggregation, or MDX On Demand | # Held Data Best Practices Source: https://docs.mx.com/products/connectivity/overview/held-data/best-practices This document provides a comprehensive overview of the system architecture and its key components. The purpose is to outline the design principles, components, and the interactions between them. ## IDs ### ID Prefixes We recommend using prefixes for all IDs to make them easily identifiable. A user ID would start with "U-", a member ID with "M-", an account ID with "A-", and a transaction ID with "T-". This makes it very easy to always know what kind of ID is being used in each place, especially when using MDX Real Time when multiple IDs will be on the URL. ### ID Format IDs appear on the URL in MDX Real Time and MDX On Demand requests. They must be URL-safe. The MDX specification limits them to letters, numbers, and the dash and underscore characters. If the value you need to use as an ID is not URL-safe then we recommend you encode it with hex encoding or url-safe base64-encoding. If using the base64 option it is recommended that you pad the ID to a multiple of three bytes before converting it to base64 so that there will be no padding characters on it since the padding character is not URL-safe. This avoids the need to do URL percent-encoding on the IDs. ### Using User IDs For a user ID, we recommend that you use a value that already exists in the user's record but not an account number or other sensitive value. If you have a record number or a similar value, that is ideal. Using a value that already exists in the user's record makes it predictable which will facilitate expanding your integration later to include additional APIs. The ID does need to be URL-safe since it appears on the URL in our API requests. If the value you choose contains non URL-safe characters, you can simply encode using hex-encoding or URL-safe base64 encoding. We recommend prepending "U-" to the front of user IDs to make them easily identifiable. ### Using Member IDs The member ID can be based on the same value as the user ID so you only have a single value to deal with. We recommend that you prefix the member ID with "M-" to make it easily identifiable. For example, If your ID value is "1234", then the user ID would be "U-1234" and the member ID would be "M-1234". ### Using Account IDs Most systems have an account ID that is either globally unique or unique per user. That value can be used as the account ID because in the MX system an account ID need only be unique within the member. The account ID does show up on the URL in MDX On Demand and MDX Real Time requests. If the account ID value is a sensitive value, either use another value such as a record number, or ensure the value is encrypted or hashed. We recommend prepending "A-" to the account ID to make it easily identifiable. ### Using Transaction IDs Transaction IDs must be unique within the account and consistent from one data feed to the next. If you already have a value available that meets these criteria then you can use it. When possible we recommend prepending "T-" to transaction IDs to make them easily identifiable. If you need to manufacture a transaction ID, there is a combination of available values. Many systems have a sequence number that is unique per day and a combination of the posted date and the sequence number would be unique within the account. For example, if the sequence number is six digits then the transaction ID can be similar to this pattern: "T-20150820-123456". Pending transactions that do not have a posted date can use the transaction date or other fields to ensure uniqueness. If possible it is ideal to use a transaction ID that will not change when a transaction changes from a pending status to a posted status. If this is not possible the MDX specification does allow the ID to change when the transaction status changes. ## Data Management MX is unable to handle requests to perform mass deletes or mass updates of data held on MX's servers. For this reason, it is best practice for you to consider these needs in the initial phases of integrating to MX. MX APIs provide endpoints to perform all create, read, update, and delete actions (CRUD) on data entities in the MX platform. Consider using all of these endpoints in their integration to keep objects up to date. When using MDX On Demand, the ongoing updating of accounts and transactions data will be handled through the daily On Demand requests. Also consider how to keep User and Member data up to date. Potential needs may include: deleting inactive or canceled users, updating user info, updating member credentials if using login/password, and others. If these steps are not integrated in the initial phases and you desire to have large sets of data deleted or updated, then plan to do so using a script. Using the MDX Real Time API, create an API script to run through a list of object ids and perform the desired API calls to MX. ## Auto-enrollment and Login Workflow We have provided a recommended workflow for auto-enrolling Users to implement in your login process. We recommend this workflow - even for the all-in approach and for those who are keeping track of Users created. Use of this workflow will eliminate unnecessary API calls; it will also ensure that the User and Member exist and are up-to-date in case anything goes wrong or data gets out of sync between MX and your systems. ## Userkeys When we send an MDX On Demand create session request, we will provide the userkey you assigned to the member when you created it. The userkey is not the same as the member ID which you also assign to the member. The member ID appears on the URL in API requests to identify the member in our system. The userkey is a credential that you will use to validate the user, and it is only used when we send you an MDX On Demand create session request. You can base the userkey on the same value you use for the user ID and member ID or use a different value in your system that will uniquely identify the user. We recommend it be a static value that won't change. The userkey may be as simple as "K-1234" or you may hash it or encrypt it. The userkey can contain any UTF-8 character so it is not limited to URL-safe characters. ## Sending First Name, Last Name and Email Although not required, we recommend sending first name, last name, and email if the data is available. Having this data in the MX system will greatly improve analytics data as well as improve troubleshooting for support issues on specific users. ## Handling Closed Accounts We encourage all data providers to provide account and transaction details for recently-closed accounts (those closed within the past 30 days, for example). This allows us to update these accounts on the MX platform so the user will see the closed status and final zero balance. In the past, many data providers have not included closed accounts in their data feed. This works well for new users who might not want to see closed accounts when they first open the software, but it does not work well for existing users who already have that account in their MX data. ### Example Consider the case of a car loan. The user opens the loan and makes payments for years in which MX has received as a part of the data feed. When the user makes the final payment, their car loan account is closed. MX did not receive a zero balance or the final transaction for the account because it was no longer included in the data feed so we do not display the account as paid off or closed to the end user. The best user experience occurs if the data provider includes information on recently-closed accounts. This allows the final zero balance to be provided to MX and, if using the MDX protocol, the `is_closed` field can be set to true to signal that the account is closed. MX will then automatically mark the account as closed for the user, update the balance to zero, and then request transactions for that account. These final transactions that occurred as the account closed will then complete the user's financial picture for that account. MX intelligently handles closed accounts received in the data feed. If the user already has that account then we will update it, but we will not add it if the user does not already have it. This allows MX to ignore recently closed accounts for a brand-new user, but to be able to update accounts that close if the user already has them in their data. ## Queueing MDX on Demand Requests We recommend that you build a mechanism into your MDX On Demand service to manage the number of simultaneous requests you can process. This is particularly important if the available connections needed to get the data are limited. The number of requests received in a short period of time may vary due to the number of users logging in. The queueing mechanism will help to smooth out the request load so it can be processed successfully. MX will wait for up to 60 seconds for the response to an MDX On Demand request. After 60 seconds MX will terminate the request and cancel the job. A queueing mechanism can take advantage of this and allow a delay in responding to the request until you are able to do so. ### How the Queueing Mechanism Works * Set up a queue that can "hold" requests that cannot be executed immediately. * When a request is received, process it immediately if the request queue is empty and there is a connection available to get the data. If no data connection is available, put the request into the queue, along with the Job Type (see below) and a timestamp of when the request was received. * Check the MDX-Job-type header of the request being queued. If the job type is foreground, put the request in the queue ahead of requests where the job type is background so that it takes priority. * When a data connection becomes available, check the queue for pending requests. When present, process the next request in the queue. * If a request in the queue is approaching the 60-second timeout limit and cannot be processed, return a 429 Too Many Requests error and remove it from the queue. This is preferred to letting the request expire since the 429 error makes it clear that there is a capacity issue, rather than the job simply failing for a lack of response. **INFO** Foreground jobs are given priority over Background jobs because the user is present during a Foreground job so we need to ensure their data is updated. We suggest that you make transactions requests a priority. If you are receiving a transactions request after the sessions and accounts requests have already succeeded, it is recommended to reject a sessions request for a new job, or an accounts request for a job that is almost finished. ## What to Provide in a Data Field When a Value is Not Available The best practice is to omit a field from the request when you do not have a value to provide. This avoids any possibility that a field value will be set inadvertently. This is particularly important in an update (PUT) request. If a field is provided with a `null` value, it may overwrite any existing value on that field. Only provide a field in an update request when you specifically want to set the value of that field. It is also best to omit empty fields in a create (POST) request. In rare cases where that is not possible, pass the field without a value. An empty set of tags or a self-closing tag can be provided when using XML format, e.g.,` or `. A value of `null` can be provided when using JSON format, e.g., `"apr":null`. Do not provide placeholder values in data fields, e.g., providing a value of `0` in the `apr` field of an account. The MX system will interpret this as an actual `apr` value of zero, not as the lack of a value. Similarly, empty strings, e.g., `""`, must not be provided as the value of a field when using JSON format. Do not provide a value for a field when the correct value is not available. MX has separate fields for the transaction date (`transacted_at`, `transacted_on`) and the posted date (`posted_at`, `posted_on`). Provide values for both when the transaction has posted, i.e., when it's `status = POSTED`. If only one date is available in your system, provide that date as both the transaction date and the posted date. Only provide valid dates; do not use a placeholder or default value such as `1970-01-01`. This is important when using MDX On Demand, where the posted date is used for reconciliation purposes. ## Storing Data in the Metadata Field Most objects on the MX platform include a writable `metadata` field. This field enables you to store additional information related to that object. For example, creating a transaction may send information in the `metadata` field with its create request. We recommend you use a key-value format such as JSON for `metadata` content. This allows you to store any number of key-value pairs. Encode the contents using an encoding such as base64 so the information can be included in either JSON- or XML-formatted responses. MX will not remove or alter the `metadata` field. See the FAQ article for information on which party controls the `metadata` field in each object. ### Encoding example If you want to store two pieces of information in the `metadata` field, these can be represented by two key-value pairs: `rewards_eligible` (a boolean field) and `reward_program` (a string field). JSON-formatted data: `{"rewards_eligible":true,"reward_program":"MILES"}` These data are then encoded using base64. Base64-encoded JSON data: `eyJyZXdhcmRzX2VsaWdpYmxlIjp0cnVlLCJyZXdhcmRfcHJvZ3JhbSI6Ik1JTEVTIn0=` Store the base64 value in the metadata field when they create the transaction. When you read the transaction, decode the base64 value to get the JSON key-value pairs. This method allows key-value pairs to be added as needed without compromising any existing data. # Sending Held Data Source: https://docs.mx.com/products/connectivity/overview/held-data/index This guide explains how to send data held by your financial institution to MX for processing, enhancement, and delivery to end users. Financial institutions differ in their system configurations and available resources. We provide three methods for sending your data: * [MDX Real Time](/products/connectivity/overview/held-data/mdx-real-time) - Push data to MX for real-time processing * [Batch](/api-reference/more-apis/batch-api/) - Send batch files to MX for processing * [MDX On Demand](/products/connectivity/overview/held-data/mdx-on-demand) - MX pulls data from you Each method has strengths and weaknesses depending on your systems and use case. They can be combined to achieve an optimal solution. ## Held Data vs. Aggregated Data​ We handle both data held by your financial institution and externally aggregated data from other institutions. MDX Real Time, Batch, and MDX On Demand v5 manage held data. The Platform API handles aggregated data and the aggregation process. For example, an end user may have checking and savings accounts with you (held data sent using the methods outlined here) and a credit card from another institution (aggregated data handled via the Platform API). ## Determining the Best Method to Use​ Keep the following questions in mind when determining which integration method is appropriate for you. * What do your systems look like? Does your back end or banking core produce data continuously or does it produce data in batches? * Is your data housed on-premises or with a third party? * If with a third party, can your data be accessed continually, or do you have access to batches of summary data? * Can you perform reconciliation of things like pending versus posted transactions? * What kinds of costs can you handle? Frequent requests to core banking services managed by a third party may be costly even if it provides the best experience for end users. ## MDX Real Time​ MDX Real Time is the best solution for clients with real-time data available in their systems. Real Time is a RESTful API that lets you push user, member, account, transaction, and holding data directly to MX as soon as changes occur. Real Time is optimal for event-driven backends where transaction and account updates post throughout the day, not just in nightly batches. You'll need to push data for all accounts, including those held by third parties. You must handle data reconciliation. For example, if you send a `PENDING` transaction, you must either delete it or update it to `POSTED`. If a `POSTED` transaction can change or be deleted, these changes must also be tracked and sent to MX. **Possible Advantages**: * Event-driven. Push data whenever it changes. * End users see updated data as soon as it exists rather than waiting for daily change or for back-end aggregation to occur. **Possible Concerns**: * You must handle data reconciliation. * Scale: Your systems must be able to handle the large number of requests necessary to keep everything up to date. ## Batch API​ With Batch, you push data to MX using large CSV-formatted files (via SFTP) on a periodic basis rather than making numerous requests for individual changes. The common pattern is to create a batch file nightly and send it for processing, which takes several minutes to hours depending on size. Because of processing delays, Batch is not ideal for intra-day transactions. Batch is optimal if account and transaction updates process on your banking core once daily and you have access to summary data for all accounts. If account data is held by a third party and daily summaries aren't available, Batch can't be used for those accounts. Batch can also be used for other scenarios: pre-loading historical data before go-live, deleting inactive users, and updating incorrectly sent fields. **Possible Advantages**: * A large amount of data representing millions of changes can be processed in an efficient manner. * Batch may closely match your existing backend or core banking system. **Possible Concerns**: * Not event-driven. * Data isn't available to your end users in real time. * It takes time for us to process batch files; you don't get immediate feedback on changes like you do with real time. * You must handle data reconciliation, as with Real Time. * Intra-day transactions are not well supported due to the delayed nature of batch processing. ## MDX On Demand v5​ MDX On Demand v5 is essentially the reverse of Real Time. You implement a RESTful API on your systems according to our specification, and we make requests to that API as necessary. We handle data reconciliation. To use On Demand, your users and members must already exist on our platform, meaning you must have created them using Batch or Real Time. The On Demand model simplifies handling account data housed by third parties, such as credit cards with externally hosted transactions. MX requests data for each account individually, allowing your system to gather data from multiple sources. On Demand also supports user-managed members, where users create a second connection to their home institution (most often to bring in a spouse's accounts). We send the login and password provided by the user to retrieve data from you. Multifactor authentication (MFA) is supported and encouraged for user-managed connections. On Demand requires that you scale your systems to handle numerous requests. Expect at least one On Demand session per user per day, with each session requiring multiple requests to various endpoints. **Possible Advantages**: * There's no need to reconcile data on your end. * It's easier for you to retrieve data from third parties including data that can only be accessed one user at a time. * Good handling of user-managed members. **Possible Concerns**: * It's resource intensive. * Scale: Your systems must be able to handle the large number of requests necessary to keep everything up to date. ## Hybrid Approaches​ Because Real Time, Batch, and On Demand v5 share the same resource structure and similar data models, you can combine multiple methods to achieve an optimal solution. Common hybrid approaches include: * Send a one-time initial data load using Batch, then use Real Time for ongoing updates * Send daily batch files for most data, but handle intra-day events (transfers, bill payments) via Real Time * Use Batch to push internally-held account data and On Demand to pull third-party account data, or vice versa Hybrid approaches require consistent IDs for users, accounts, and other resources across all methods. ## MX-Defined GUIDs vs IDs Defined by You​ All resources managed via Real Time, Batch, and/or On Demand v5 must be assigned unique IDs by you. These IDs are how you create, update, and track accounts, transactions, and other resources. We also assign a unique GUID to every resource you create. This separate GUID is required for externally aggregated data and is returned in Real Time responses and Batch response files. The Platform API requires MX-defined GUIDs for accessing and managing resources, including those created via Real Time. If your integration uses the Platform API, you must track MX-defined GUIDs and map them to the unique IDs you assign. MX-assigned GUIDs are UUID values with a three-letter prefix identifying the object type. For example, user GUIDs start with `USR-`. These prefixes are reserved for MX-generated GUIDs and must not be used for your assigned IDs. Examples include: * `USR-` * `MBR-` * `ACT-` * `TRN-` * `HLD-` # MDX On Demand v5 Source: https://docs.mx.com/products/connectivity/overview/held-data/mdx-on-demand ## On Demand is a Good Fit for... Integrations where partners cannot support Real Time data creation (when users, accounts, or transactions are created, updated, or deleted in the partner's system) in the MX Platform. In this case, On Demand serves as the primary tool for creating accounts, transactions, and holdings in the MX Platform. Users and members must always be created with the Real Time API. **INFO** Read our [MDX On Demand API Reference](/api-reference/more-apis/mdx/mdx-on-demand/) for more information. ## Required APIs for an On Demand Integration 1. MDX Real Time - User and member creation 2. SSO API - User authentication and software access 3. MDX On Demand - Primary tool for aggregating accounts, transactions, and holdings These three APIs ensure that users are created in the MX Platform (MDX Real Time), their accounts, transactions, and holdings are created (MDX On Demand), and users can be authenticated to load the widgets (SSO). ## Creating a User and Member Creating a user and member When a user clicks on the PFM link for the first time, a request is made to your server to create a new user. Your server then issues a [create user request](/api-reference/more-apis/mdx/mdx-real-time/reference/users/create-user) to Real Time. Real Time responds by creating a new user. Your server then makes a [create member request](/api-reference/more-apis/mdx/mdx-real-time/reference/members/create-member) to Real Time. ## Requesting a Widget URL requesting a widget URL After the user and associated member(s) are created, you request a URL from the [MX SSO API](/api-reference/sso/v3/) to load the widget in the user's browser. MX responds with a widget URL, which you load into the user's browser. This loads MX's widget and is considered a log-in event. ## Requesting Accounts, Transactions, and Holdings Requesting accounts, transactions, and holdings **INFO** Holdings are optional and not shown in the diagram above. However, they follow the same pattern as transactions. The log-in event causes MX to issue an On Demand request to your server to pull the user's accounts, transactions, and holdings. MX requests a session, and you respond with a session `key`. This key is used in every subsequent On Demand request. MX requests the user's `accounts`. [You respond with the account information](/api-reference/more-apis/mdx/mdx-on-demand/reference/accounts/list-accounts). MX requests `transactions` within a specific date range for each account. You respond with all [transactions for the account within the date range](/api-reference/more-apis/mdx/mdx-on-demand/reference/transactions/list-transactions). If your account response included any accounts with `true`, MX requests `holdings` for those accounts. You respond with all [holdings for the account](/api-reference/more-apis/mdx/mdx-on-demand/reference/holdings/list-holdings). All of the account, transaction, and holding data is presented to the user in the widget UI. This step is automatic and no further action is needed. ## Performance Testing You can test your MDX On Demand service by simulating the calls made in a typical aggregation process from MX. This includes calculating MD5 and HMAC headers and making API calls in the proper order. We've provided a JMeter template for this purpose. This document explains how to set up and run these tests using JMeter. Download release build binary from the [JMeter download site](http://jmeter.apache.org/download_jmeter.cgi) and follow the instructions for installation. Download the `mx_jmeter.zip` packaged files [here](/assets/mx_jmeter.zip). Included files are: * `jruby-complete-1.7.9.jar`: this library is required to run the specific templates provided * `ondemand_unamepass.jmx`: JMeter template for testing On Demand with Username and Password * `ondemand_userkey.jmx`: JMeter template for testing On Demand with Userkey 1. Place the jruby library in the `/lib/` directory. 2. Place the `.jmx` template files in the `/bin/` directory. The JMeter test templates require a list of user credentials to pass to the Sessions call. This list should be set up as a CSV file called `login.csv` and placed in the `/bin/` directory. * For username/password credentials, use the format `username,password` with one record per line. * For userkey credentials, use the format `userkey` with one record per line. **INFO** It is recommended to have enough sets of credentials to allow for simultaneous threads. * Run JMeter executable in the `/bin/` directory from a command console. * Load the `.jmx` template by going to File > Open and selecting the appropriate template for your credential type. Click on the Test Plan in the template tree and fill out the User Defined Variables. | `Name` | Definition | Example Value | | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | `site` | The URL of your On Demand service excluding the protocol prefix. | `abcbankweb.com/mxondemand.api/abcbank` | | `salt` | The SALT key in base64 format provided by MX for the HMAC calculation. Include double quotes. | "M2Z0NTg5cnR5dTc5NGFyNDExM2QyMjIzMDY5YTRmNGU=" | | `sha` | The digest encryption algorithm used to calculate the HMAC. This will be provided when the SALT is generated. | 'sha1' | | `days` | The number of days requested in each transactions request. For example, 90 days means each request covers transactions from today to 90 days ago. | 90 | | `users` | The number of users in the `login.csv` file. | `1` | **INFO** All fields must be populated with correct values for the tests to work. This includes the `salt` and `sha` fields. If you do not have these, they can be provided by MX. a screen of jmeter To test the user list multiple times, change the loop count by going to the top-level Session Request and modifying the "Loop Count" value. The default is 1. Start the tests by clicking the green "play" button in the JMeter toolbar. Monitor the API requests and responses in the "View Results Tree" section. # MDX Real Time Source: https://docs.mx.com/products/connectivity/overview/held-data/mdx-real-time ## What Is Possible With MDX Real Time? With a Real Time integration, you can help keep users on top of their finances with data available immediately after a financial transaction or account change. As financial records change in a partner's system, requests are made to MX systems to add those records. This ensures that the data with MX is a mirror image of the online banking experience. A Real Time integration offers the fastest possible loading time when opening MX-enabled products as all the data is available at log in. This ensures the end user has a great experience when interacting with MX-enabled products. MDX Real Time also gives you the ability to pre-load users' financial data onto MX systems for an enhanced initial user experience. **INFO** Read our [MDX On Real Time Reference](/api-reference/more-apis/mdx/mdx-real-time/) for more information. ## How Is MDX Real Time Different Than MDX On Demand? MDX Real Time gives you the ability to **push data to MX** as soon as it becomes available, even without the end user logging in. This means you can trigger real-time alerts without the end user having to log in. You have complete control over what data is sent and when it is sent to MX. Because of this, **you** are responsible for reconciling a user's data by managing `POSTED` and `PENDING` transactions as well as other changes to the data. Essentially, MX accepts whatever data actions you send. MDX On Demand, on the other hand, is when **MX makes requests to you** to pull data. Because MX is requesting, we'll pull the last 15 days of a user's data to perform reconciliation. With On Demand, MX only pulls data when a user logs in or during background aggregation if that user hasn't had a successful log in attempt in 24 hours. ## Required APIs for a Real Time Integration 1. MDX Real Time (user and member creation) 2. SSO (authenticating users and opening software) These two APIs are responsible for delivering the user's financial data to MX, authenticating a user, and displaying the software to the end user once they have been authenticated. ## How Is Data Pushed to MX? MD Chart Users, members, accounts, and transactions are created, updated, or deleted by you with the MDX Real Time API. These requests are ongoing and are triggered by a record being created, updated, or deleted in your system. This enables all the end user's data to be on MX systems before they log into the service. ## Creating a Queue to Push Data to MX RT Queue Flow This diagram shows how a partner might implement a queue to push real-time data to MX. This solution consists of adding action items to a database or cache and then processing those actions by pulling them into a queue, then using MDX Real Time to push that data to MX. Depending on the level of integration, a partner's system may have several actions that would need to trigger a call to the MX Real Time API in order to create, update, or delete objects in the MX system. Below is an example list of some events that would call a method to trigger an MDX Real Time API call. * User is created * Account is created * Account balance changes * Pending transaction is created * Pending transaction posts * Partner's system uses a nightly batch to push daily transactions ## Queue Processing Service The queue processing service will need to handle processing newly added actions and retrying for calls that don't succeed the first time. Some configuration settings that will be used in these examples follow: * `RetryThreshold`: How many retries should be attempted before discontinuation. * `RetryFrequency`: How often failed actions are retried. The queue processing service would determine which API action to call based on the MXAction item. ### Initial Queue This is the first queue that will attempt to push data to MX. The processing for the initial queue will have either a listener or a real-time read for when a new object is added to the database so it can immediately try to push to MX. The initial queue will also attempt each call twice before updating the database. This is to avoid failures due to race conditions. ### Retry Queue If an action fails twice it will be added to a retry queue which will be processed differently than the initial queue. The retry queue will be processed based on the `RetryFrequency` configuration and will run periodically by pulling items that need to be retried and attempting them once per pass. ### History and Alerts Logging Because it's possible to have actions that never succeed, you should implement logs and alerts. Some useful alerts might include: * Alert when an action fails to succeed the initial attempt. * Alert when an action has failed and the retry threshold has been reached. ## Best Practices for API Call Processes In order to create objects in the MX system, a tree structure of objects must exist above it according to the [MX Data Architecture](/products/connectivity/overview/data-architecture). The hierarchy is as follows: user > member > account > transaction. If you try to create a lower-level object before the parent object exists, you'll get an error. The following is an example of the steps necessary for creating a transaction, including possible errors and steps to resolve them. 1. Create transaction * 200 Response: UPDATE Account * 404 Response: Go to Step 2 * 409 Response: Transaction already exists 2. Create account * 200 Response: Go to Step 1 * 409 Response: Go to Step 1 * 404 Response: Go to Step 3.2 3. Create user/member 1. Create member * 200 Response: Go to Step 2 * 409 Response: Go to Step 2 * 404 Response: Go to Step 3.2 2. Create user * 200 Response: Go to Step 3.1 * 409 Response: Go to Step 3.1 * 404 Response: Double check `client_id` and URL A complete list of error codes and their definitions can be found [here](/api-reference/more-apis/mdx/mdx-real-time/#errors). ## Creating API Scripts In addition to building API calls and logic into online banking platforms, partners may also need to update large sets of data on MX's servers. If this is needed, MX recommends partners create a program or script which can loop through a table and perform simple API calls for each object. One common example is deleting a set of Users. The example that follows shows how an API script can be used to accomplish this task with little effort. ### Best Practices Before running any scripts to update large sets of data, please contact MX. This allows our teams to be aware of any increase in traffic and monitor for potential issues that may appear. ### 3-Step Process: Example Running a script to update a set of data entities can best be summarized in three steps: 1. Get a list of IDs for the objects to be updated. 2. Determine the API call to be made. 3. Create a loop to perform the API action for each entity. Let's say you want to delete inactive users from the MX platform. Using the 3-step process, you could identify and delete these users with an API script. 1. Get a list of `id`s. * Identify which users to delete based on your own analytics, and create a list of `id`s for those users. For this example, we will assume that a list of inactive users has been identified and exported to a CSV file. * If the objects being updated are further down the chain of the MX architecture, the `id`s of all parent objects must also be included. To update an account, for example, will require the `client_id`, `user_id`, `member_id`, and `account_id`. 2. Determine the API actions to perform. * The appropriate API endpoint to delete a user is [`DELETE /users/{user_id}`](/api-reference/more-apis/mdx/mdx-real-time/reference/users/delete-user), so our script must include a method that calls that endpoint. 3. Create a loop to perform the API action for each object * Step 3 involves importing our file into a data structure, using a loop to call the API method on each item in the data structure, and outputting a log to track the results. In our example, we'll pull the CSV file into a map structure. We then loop through the map, call the `mdx_delete_user` method on each iteration, and output a success or failure message to the console. * MX asks that you always include a throttle so that our system does not become overburdened. This is particularly important when deleting users since deleting a user will automatically cascade and delete all objects associated with that user. In this example we are performing delete user requests, so we'll add a time delay of 0.5 seconds after each cycle. **Example for Deleting a User in Ruby** ```ruby theme={null} require 'net/http' def mdx_delete_user(options) uri = URI("https://int-live.moneydesktop.com") uri.path << "/#{options[:client_id]}/users/#{options[:user_id]}" request = ::Net::HTTP::Delete.new(uri) request["Accept"] = "application/vnd.moneydesktop.mdx.v5+json" request["MD-API-KEY"] = options[:api_key] response = ::Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http| http.request(request) end end ``` **Example Loop in Ruby** ```ruby theme={null} require 'csv' user_list = CSV.table("users_to_delete.csv").map { |row| row.to_hash } user_list.each do |user| response = mdx_delete_user( :api_key => ":api_key", :client_id => ":client_id", :user_id => user[:user_id] ) case response when ::Net::HTTPNoContent puts "[SUCCESS] [#{response.code}] [#{user[:user_id]} user deleted]" else puts "[FAILURE] [#{response.code}] [#{user[:user_id]} user not deleted]" end sleep 0.5 end ``` # Connectivity Overview Source: https://docs.mx.com/products/connectivity/overview/index Connect users to their financial accounts and retrieve the enhanced data you need MX Connectivity products serve as a bridge between your application and financial institutions. They allow you to: * Connect end users to thousands of financial institutions * Retrieve financial data such as account details, transactions, and more * Enhance and standardize data * Power financial use cases including account opening, payments, and more To understand the core resources of our platform, see [MX Data Architecture](/products/connectivity/overview/data-architecture). Complete steps for integrating MX Connectivity products Follow our integration guides to connect user accounts ## Connectivity Products MX offers several connectivity products to address different use cases. **NOTE** Most connectivity products focus on retrieving specific types of data from connected accounts (such as transactions, balances, or account numbers). [Microdeposits](/products/connectivity/microdeposits) is different—it provides an alternate method for verifying account ownership by making small test deposits to an account. | Product | Description | | :---------------------------------------------------------------------------------- | :------------------------------------------------------------------------------ | | [Account Aggregation](/products/connectivity/account-aggregation) | Get account details and transactions by connecting to users' financial accounts | | [Account Owner Identification](/products/connectivity/account-owner-identification) | Verify account ownership information such as name and address | | [Balance Checks](/products/connectivity/balance-checks) | Check available balances for connected accounts | | [Extended Transaction History](/products/connectivity/extended-transaction-history) | Get up to 24 months of transaction history | | [Instant Account Verification](/products/connectivity/instant-account-verification) | Retrieve account and routing numbers for demand deposit accounts | | [Microdeposits](/products/connectivity/microdeposits) | Verify account ownership through small test deposits | | [Statements](/products/connectivity/statements) | Retrieve bank and credit card statements | ## Aggregating & Enhancing Data Our platform uses distributed services to aggregate, enhance, and deliver financial data to end users and institutions. The platform includes RESTful web APIs, embeddable digital money management tools, customer analytics and marketing software, and more. The following flow shows how MX aggregates and enriches data: 1. End users provide their login credentials for a financial account, such as their bank or retirement account (you can also [send your own customers' data to MX](/products/connectivity/overview/held-data/) using one or more of our APIs). 2. Those credentials are supplied to the MX system. 3. MX brings data from those accounts into its system, through a direct data-sharing connection or a third-party data provider. 4. MX enhances account and transaction data: * Account types and subtypes like `CHECKING` or `SAVINGS` are assigned * Every transaction is categorized into one of more than 100 default categories * When possible, additional classifiers like `is_bill_pay` or `is_direct_deposit` are assigned * Transaction descriptions are made readable. For example, `DBT CRD 1357 07/22/19 XXXX1357 JCWS RESTAU LEHI UT C#5144` becomes `JCW's Burgers` * Dates, locations, and merchant logos are added wherever possible * If two months of transaction data exists, user budgets are automatically calculated 5. MX delivers this enhanced financial data through our APIs, UIs, or daily change files. Additionally, we identify when end users have financial accounts with competitors and provide analytics on product usage and money management. ## Retrievable Data The following examples show what data you can expect with our Connectivity products. See [Account Aggregation](/products/connectivity/account-aggregation) for more info. To learn more about individual fields, see [Account Fields](/api-reference/platform-api/reference/accounts#account-fields) or [Transaction Fields](/api-reference/platform-api/reference/transactions#transaction-fields). ```json theme={null} { "accounts": [ { "account_number": "5366", "apr": 1.0, "apy": 1.0, "available_balance": 1000.0, "available_credit": 1000.0, "balance": 1000.0, "cash_balance": 1000.0, "cash_surrender_value": 1000.0, "created_at": "2016-10-13T17:57:37.000Z", "credit_limit": 100.0, "currency_code": "USD", "day_payment_is_due": 20, "death_benefit": 1000, "guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "holdings_value": 1000.0, "id": "1040434698", "imported_at": "2015-10-13T17:57:37.000Z", "institution_code": "chase", "insured_name": "Frodo Baggins", "interest_rate": 1.0, "is_closed": false, "is_hidden": false, "last_payment": 100.0, "last_payment_at": "2015-10-13T17:57:37.000Z", "loan_amount": 1000.0, "matures_on": "2015-10-13T17:57:37.000Z", "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "member_id": "member-9876", "member_is_managed_by_user": false, "metadata": "some metadata", "minimum_balance": 100.0, "minimum_payment": 10.0, "name": "Test account 2", "nickname": "My Checking", "original_balance": 10.0, "pay_out_amount": 10.0, "payment_due_at": "2015-10-13T17:57:37.000Z", "payoff_balance": 10.0, "premium_amount": 1.0, "routing_number": "68899990000000", "started_on": "2015-10-13T17:57:37.000Z", "subtype": "NONE", "total_account_value": 1.0, "type": "SAVINGS", "updated_at": "2016-10-13T18:08:00.000Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "partner-2345" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` ```json theme={null} { "transactions": [ { "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "account_id": "account123", "amount": 61.11, "category": "Groceries", "category_guid": "CAT-9588eaad-90a4-bb5c-66c8-1812503d0db8", "check_number_string": "6812", "created_at": "2016-10-06T09:43:42.000Z", "currency_code": "USD", "date": "2013-09-23T00:00:00.000Z", "description": "Whole foods", "extended_transaction_type": "partner_transaction_type", "guid": "TRN-265abee9-889b-af6a-c69b-25157db2bdd9", "id": "transaction-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, "is_recurring": false, "is_subscription": false, "latitude": -43.2075, "localized_description": "This is a localized_description", "localized_memo": "This is a localized_memo", "longitude": 139.691706, "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "member_is_managed_by_user": false, "memo": "This is a memo", "merchant_category_code": 5411, "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b", "merchant_location_guid": "MCL-00024e59-18b5-4d79-b879-2a7896726fea", "metadata": "some metadata", "original_description": "WHOLEFDS TSQ 102", "posted_at": "2016-10-07T06:00:00.000Z", "status": "POSTED", "top_level_category": "Food & Dining", "transacted_at": "2016-10-06T13:00:00.000Z", "type": "DEBIT", "updated_at": "2016-10-07T05:49:12.000Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "partner-2345" }, // ••• ], "pagination": { "current_page": 1, "per_page": 10, "total_entries": 243, "total_pages": 25 } } ``` See [Instant Account Verification](/products/connectivity/instant-account-verification) for more info. For field descriptions, see [Account Number Fields](/api-reference/platform-api/reference/accounts#account-number-fields). ```json theme={null} { "account_numbers": [ { "account_guid": "ACT-82a93692-f756-534f-9b2e-ad10a0f38462", "account_number": "10001", "institution_number": null, "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "routing_number": "091000019", "passed_validation": true, "transit_number": null, "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` See [Account Owner Identification](/products/connectivity/account-owner-identification) for more info. For field descriptions, see [Account Owner Fields](/api-reference/platform-api/reference/accounts#account-owner-fields). ```json theme={null} { "account_owners": [ { "account_guid": "ACT-82a93692-f756-534f-9b2e-ad10a0f38462", "address": "123 This Way", "city": "Middlesex", "country": "US", "email": "donnie@darko.co", "first_name": "Donnie", "guid": "ACO-63dc7714-6fc0-4aa2-a069-c06cdccd1af9", "last_name": "Darko", "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "owner_name": "Donnie Darko", "phone": "555-555-5555", "postal_code": "00000-0000", "state": "VA", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` [Extended Transaction History](/products/connectivity/extended-transaction-history) shows up to 24 months of transactions, instead of only up to 90 days. For field descriptions, see [Transaction Fields](/api-reference/platform-api/reference/transactions#transaction-fields). ```json theme={null} { "transactions": [ { "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "account_id": "account123", "amount": 61.11, "category": "Groceries", "category_guid": "CAT-9588eaad-90a4-bb5c-66c8-1812503d0db8", "check_number_string": "6812", "created_at": "2016-10-06T09:43:42.000Z", "currency_code": "USD", "date": "2013-09-23T00:00:00.000Z", "description": "Whole foods", "extended_transaction_type": "partner_transaction_type", "guid": "TRN-265abee9-889b-af6a-c69b-25157db2bdd9", "id": "transaction-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, "is_recurring": false, "is_subscription": false, "latitude": -43.2075, "localized_description": "This is a localized_description", "localized_memo": "This is a localized_memo", "longitude": 139.691706, "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "member_is_managed_by_user": false, "memo": "This is a memo", "merchant_category_code": 5411, "merchant_guid": "MCH-7ed79542-884d-2b1b-dd74-501c5cc9d25b", "merchant_location_guid": "MCL-00024e59-18b5-4d79-b879-2a7896726fea", "metadata": "some metadata", "original_description": "WHOLEFDS TSQ 102", "posted_at": "2016-10-07T06:00:00.000Z", "status": "POSTED", "top_level_category": "Food & Dining", "transacted_at": "2016-10-06T13:00:00.000Z", "type": "DEBIT", "updated_at": "2016-10-07T05:49:12.000Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c", "user_id": "partner-2345" }, // ••• ], "pagination": { "current_page": 1, "per_page": 10, "total_entries": 243, "total_pages": 25 } } ``` See [Statements](/products/connectivity/statements) for more info. For field descriptions, see [Statement Fields](/api-reference/platform-api/reference/statements#statement-fields). ```json theme={null} { "statements": [ { "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "content_hash": "ca53785b812d00ef821c3d94bfd6e5bbc0020504410589b7ea8552169f021981", "created_at": "2016-10-13T18:08:00+00:00", "guid": "STA-737a344b-caae-0f6e-1384-01f52e75dcb1", "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "updated_at": "2016-10-13T18:09:00+00:00", "uri": "uri/to/statement", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` ## Next Steps Complete steps for integrating MX Connectivity products Follow our integration guides to connect user accounts # Intro to Unified Product Ordering Source: https://docs.mx.com/products/connectivity/overview/intro-to-unified-product-ordering/index If you're using the Platform API, you can [include a version header](#how-to-access) for version 20250224 to aggregate data from multiple products in a single API call. ## What's Changed? The following endpoints are impacted with `v20250224`: * List Institutions: `GET /institutions`: Enhanced search and filtering capabilities based on the products supported by each institution. * Read Institution: `GET /institutions/{institution_code}`: More information provided about the products supported by the institution. * Create Member: `POST /users/{user_guid}/members`: Initiate the aggregation of any products specified in the request. * Request Widget URL: `POST /users/{user_guid}/widget_urls`: Initiate the aggregation of any products specified in the request. Make sure to [use the new version header](#how-to-access) for each of these endpoints. ## How To Access The MX Platform API requires basic access authentication using your `client_id` and `api_key`. These credentials must be Base64 encoded and included in the Authorization header of each API request to ensure secure access. To access this functionality, modify the request header to specify this version: `v20250224`. Here's an example using curl to access `v20250224`. Replace `https://int-api.mx.com/endpoint` with the actual API endpoint you wish to access and your Base64 encoded `client_id` and `api_key`. ```shell theme={null} curl -L -X POST 'https://int-api.mx.com/endpoint' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Accept-Version: v20250224' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' ``` ## Defining Products You can define the products using the following values in query parameters and request fields. **NOTE** Balance data is always included and doesn't need to be set. | Product | Value | | :--------------------------- | :---------------------- | | Instant Account Verification | `account_verification` | | Account Owner Identification | `identity_verification` | | Account Aggregation | `transactions` | | Extended History | `transaction_history` | | Statements | `statements` | | Investments | `investments` | | Rewards | `rewards` | ## Aggregate Multiple Products To use this functionality in the Connect Widget: 1. Call the [Request Widget URL](/api-reference/platform-api/reference/widgets) endpoint: * [Change the Authorization header](#how-to-access) to access `v20250224`. * [Define the products](#defining-products) you want to aggregate. This only starts the aggregation process, so in the next steps you'll retrieve that aggregated data. 2. Display this widget URL to the end user. 3. Wait for the end user to connect to an institution and create a member. 4. Verify aggregation is complete by polling the member until `connection_status` is `CONNECTED` and `is_being_aggregated` is `false`. See [Member Connection Statuses](/api-reference/platform-api/reference/members#member-connection-statuses). 5. Use one of the following endpoints to fetch that aggregated data: * **Instant Account Verification** (`account_verification`): [List Account Numbers by Member](/api-reference/platform-api/reference/accounts) or [List Account Numbers by Account](/api-reference/platform-api/reference/accounts) * **Account Owner Identification** (`identity_verification`): [List Account Owners by Member](/api-reference/platform-api/reference/accounts) * **Account Aggregation** (`transactions`): [List Accounts](/api-reference/platform-api/reference/list-user-accounts) or [List Transaction by Account](/api-reference/platform-api/reference/transactions) * **Extended History** (`transaction_history`): [List Transactions by Member](/api-reference/platform-api/reference/transactions) or use another `GET` Transactions endpoint * **Statements** (`statements`): [Read Statement by Member](/api-reference/platform-api/reference/statements) or [List Statements by Member](/api-reference/platform-api/reference/statements) * **Investments** (`investments`): [List Holdings by Member](/api-reference/platform-api/reference/investment-holdings) or use another `GET` Investment Holdings endpoint * **Rewards** (`rewards`): [List Rewards](/api-reference/platform-api/reference/mx-platform-api) or [Read Rewards](/api-reference/platform-api/reference/mx-platform-api) ## Accessing Priority Data **BETA FEATURE** This feature is in beta. The documentation is subject to change as updates are made. When requesting products, you can optionally retrieve **priority data** before all requested data has aggregated. This helps: * Reduce user drop-off during the connection flow * Power time-sensitive workflows such as account verification or balance display **Priority data** always includes a list of accounts with core details (name, type, and balance if available). Depending on what products you set, it may include account numbers and account owners. You'll know when priority data is ready via the [Initial Data Ready](/resources/webhooks/initial-data-ready) webhook (reach out to MX to enable). You can then close the widget and use the identifiers sent in the webhook to retrieve the priority data, while non-priority data continues to aggregate. **WARNING** The webhook may not be supported by all institutions. The following table outlines what data is available initially and what data is available for you to retrieve later by polling the member until the `connection_status` is `CONNECTED` and `is_being_aggregated` is `false`. | Products Requested | Priority Data | Data Available Later | | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | | `account_verification` | Accounts list with core details (name, type, and balance if available) | Account balances and account numbers | | `account_verification` + `identity_verification` | Accounts list with core details (name, type, and balance if available) | Account balances, account numbers, and account owners | | `account_verification` + `identity_verification` + `transactions` | Account numbers, account owners, and accounts list with core details (name, type, and balance if available) | Account balances and transactions | | `account_verification` + `transactions` | Account numbers and accounts list with core details (name, type, and balance if available) | Account balances and transactions | | `identity_verification` | Accounts list with core details (name, type, and balance if available) | Account balances and account owners | | `identity_verification` + `transactions` | Account owners and accounts list with core details (name, type, and balance if available) | Account balances and transactions | | `transactions` | Accounts list with core details (name, type, and balance if available) | Account balances and transactions | ## Impact on Conversion Specifying multiple products within the `data_request.products` array restricts the selection to institutions that support all the specified services. This selective visibility ensures that users interact only with institutions capable of fulfilling their complete service requirements, enhancing the efficiency and success rate of connections. Further benefits are: * **Streamlined Consent Process**: By requesting all necessary permissions during a single OAuth flow, the consent process becomes more straightforward for users. This approach reduces the likelihood of user drop-off caused by complicated consent adjustments. * **Optimized Data Retrieval**: Initializing all required products during the connection setup allows MX to commence data fetching immediately. This approach shortens the wait time for data availability and organizes the data retrieval process more efficiently, prioritizing the fetch sequence according to the integration needs. ### Example Scenario Suppose you configure the Connect Widget or API to require both Instant Account Verification (`account_verification`) and Account Owner Identification (`identity_verification`): * **Institution Availability**: Only institutions that support both verification services will be displayed to the user. This filter prevents scenarios where a user attempts to connect with an institution that cannot provide the necessary services. * **OAuth Permissions**: If the institution uses OAuth and supports configuring Account Owner data access as a separate permission, users must grant explicit consent for both services. Failure to do so triggers an error, prompting the user to revisit the OAuth flow and adjust their permissions. This ensures that all necessary data accesses are authorized from the outset. ## Identifying Product Availability To ensure the data is available for your desired institution, use the `supported_products` parameter in the List Institutions and Read Institution endpoints. # Handling Multifactor Authentication Source: https://docs.mx.com/products/connectivity/overview/mfa This guide explains how to handle multifactor authentication (MFA) when running an aggregation job. **INFO** MFA is controlled by the institution's security settings, not by MX. MFA can be encountered at any step in the aggregation process. If you've been prompted for MFA, you've likely completed these steps: 1. Called an aggregation endpoint such as aggregation, IAV, account owner identification, or extend transaction history. 2. Checked the member's connection status: `GET /users/{user_guid}/members/{member_guid}/status`. MFA is indicated when you see a `connection_status` of `CHALLENGED`. The response also returns a `challenges` array that includes the question(s) the end user must answer to proceed. Make a note of both the `guid` in the `challenges` array and the `label` (for example: `What city were you born in?`). Here is an example: ```json theme={null} { "member": { "aggregated_at": "2020-09-21T19:48:57Z", "challenges": [ { "field_name": null, "guid": "CRD-8f841084-66cb-4e3d-9253-96f97093100a", "label": "What city were you born in?", "type": 0 } ], "connection_status": "CHALLENGED", "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa", "is_authenticated": false, "is_being_aggregated": true, "successfully_aggregated_at": "2020-09-21T19:44:17Z" } } ``` ## Use the Resume Endpoint The `PUT /users/{user_guid}/members/{member_guid}/resume` endpoint allows you to answer the challenges presented during MFA and continue the process. There are also other forms of MFA, such as choosing from multiple options (like choosing from a list of phone numbers to text a code to) or choosing the correct pre-determined photo. These are not covered in this guide, but they are possible scenarios with the MX API. A relatively common scenario is requiring a one-time code texted to a phone number. In this case, use the resume endpoint twice: once to select the phone number and again to provide the correct code. Also, use the connection status endpoint multiple times to get two different challenge GUIDs: one for the phone number and one for the code. **TIP** In this guide, we're using MX Bank test institution. To mimic a successful answer, use `correct` as the value. In an actual MFA situation, the end user will need to provide the correct answer to the question. If the security question is `What city were you born in?`, the answer may be `Chicago`, `Tallahassee`, etc. In the body of the request, include the challenge `guid` provided in the previous response and the correct answer for the `label` field. Notice that `connection_status` changed to `RESUMED` while `is_being_aggregated` remains `true`. The `is_authenticated` field is still `false`—meaning the MFA answer was accepted and the connection is proceeding, but the member's login credentials haven't been fully authenticated yet. Continue to poll the member's status to confirm there are no additional challenges or errors. ```shell Request theme={null} curl -i -X PUT 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/members/MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa/resume' \ -u 'client_id:api_key' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -d '{ "member": { "challenges": [ { "guid": "CRD-8f841084-66cb-4e3d-9253-96f97093100a", "value": "correct" } ] } }' ``` ```json Response theme={null} { "member": { "aggregated_at": "2020-09-21T19:48:57Z", "connection_status": "RESUMED", "guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa", "id": null, "institution_code": "mxbank", "is_being_aggregated": true, "metadata": null, "name": "MX Bank", "successfully_aggregated_at": "2020-09-21T19:44:17Z", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } } ``` # Statements Source: https://docs.mx.com/products/connectivity/statements/index Get monthly account statements **NEW TO MX CONNECTIVITY?** See the [Connectivity Overview](/products/connectivity/overview) to learn about our Connectivity products and integration options. Use the Connect Widget and Platform API to let end users connect to their accounts. Use the Platform API to power a non-MX UI connection experience. With Statements, you can connect to an end user's financial institution and retrieve monthly account statements in PDF format. This data can be used as part of a number of solutions including personal financial management or risk analysis. Diagram flow of the steps to get account statements ## Quick Links Learn about the full features of the Platform API. ## Statement Sample Data This sample response shows the data you can expect to get for statements, in addition to a PDF copy of a given statement. ```json theme={null} { "statement": { "account_guid": "ACT-06d7f44b-caae-0f6e-1384-01f52e75dcb1", "content_hash": "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "created_at": "2016-10-13T17:57:37.000Z", "guid": "STA-737a344b-caae-0f6e-1384-01f52e75dcb1", "member_guid": "MBR-3bdc7d6b-efd4-1497-a0af-b23501cf9bd0", "updated_at": "2016-10-13T18:08:00.000Z", "uri": "uri/to/statement", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } } ``` ## Related Products Get up to 24 months of transaction history. Get account and routing numbers. Get account and transaction data. # Best Practices Source: https://docs.mx.com/products/experience/insights/best-practices Follow these best practices to maximize your results from Financial Insights. ## Engage Users​ Users engage with insights that are timely and relevant to their situation. We offer three widgets that, when used together, increase the visibility of insights: * [Insights Widget](/products/experience/insights/widget-overviews/insights-widget): A vertical feed of the user's insights. * [Mini Insights Widget](/products/experience/insights/widget-overviews/mini-widget): A small carousel of up to 5 insights, designed to be embedded as an entry point to the full Insights Widget. * [Micro Insights Widget](/products/experience/insights/widget-overviews/micro-widget): A smaller carousel of up to 5 insights, designed to be embedded as an entry point to the full Insights Widget. Consider your current banking experience when implementing Financial Insights. If you'd like to increase user engagement with Insights, follow these steps: 1. Create a dedicated page for the Financial Insights Widget. 2. Embed multiple instances of clearly labeled Mini or Micro Insights Widgets for Financial Insights on your main landing page or in high-traffic areas. Avoid low-traffic areas or nested pages. These smaller widgets serve as entry points to the full widget. 3. Set up the embedded Mini or Micro Insights Widget(s) to [link to the full Financial Insights Widget](/products/experience/insights/integration-guides/integrate-mini-widget#move-insight-to-top-of-feed). When users select **View More**, they'll be taken to the full Insights Widget with the selected insight at the top. This gives your users a brief glimpse into their financial insights the moment they log on, prompting them to take a deeper dive into the full Financial Insights experience. ## Create Your Experience​ Use a combination of custom-made and prebuilt insights to create a comprehensive experience for your users. ### Custom Insights​ You can create [custom insights](/products/experience/insights#create-custom-insights) to support your unique business goals, such as limited-time offers or campaigns. For example, you could run a 3-month Cash Back campaign where you flag all gas purchases and offer a reward (using a custom insight) if users pay with your bank credit card. You can turn off the insight once the campaign ends. ### Recommended Prebuilt Insights​ We also recommend choosing insights from our Insights Library that will be most helpful to your users. These are designed to be enabled indefinitely. We recommend starting with these and adding others as desired. Typical implementations enable around 35 insights. We recommend starting with these and adding others as desired. | Insight Name | Type | Description | | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Bill Amount Not Standard](/products/experience/insights/library/spend#bill-amount-not-standard) | Spend | Notifies users of a bill payment that's higher or lower than usual. | | [Category Budget](/products/experience/insights/library/spend#category-budget) | Spend | Notifies users about their budget status. | | [Category Spending](/products/experience/insights/library/spend#category-spending-v2) | Spend | Prompts users to create a spending limit when spending in a category is growing significantly. | | [Celebrate Credit Card Payoff](/products/experience/insights/library/borrow#celebrate-credit-card-payoff) | Borrow | Celebrates when users pay off a credit card balance. | | [Charge Dispute Refund](/products/experience/insights/library/spend#charge-dispute-refund) | Spend | Notifies users that they've received a credit related to a charge dispute. | | [Cost of Living to Income](/products/experience/insights/library/spend#cost-of-living-to-income) | Spend | Notifies users that MX has identified that their spending in one of five category types is high compared to their income. | | [Credit Card Close to Limit](/products/experience/insights/library/spend#credit-card-close-to-limit) | Spend | Notifies users that they've reached a specified percentage of their credit card spending limit. | | [Credit Utilization](/products/experience/insights/library/borrow#credit-utilization) | Borrow | Notifies users that their credit utilization is high. | | [Debt Payment Reminder](/products/experience/insights/library/borrow#debt-payment-reminder-v3) | Borrow | Notifies users of an upcoming payment for a liability account. | | [Designate Emergency Savings Account](/products/experience/insights/library/save#designate-emergency-savings-account) | Save | Allows users to choose, change, or open their emergency savings account. | | [Discovered Account](/products/experience/insights/library/spend#discovered-accounts) | Spend | Identifies discovered accounts from the user’s held account data and suggests they connect the discovered account. This insight is available only if you're using our PFM or Mobile product. | | [Duplicate Payment](/products/experience/insights/library/spend#duplicate-payment-v2) | Spend | Alerts users when a possible duplicate payment is detected. | | [Emergency Savings Milestone Reached](/products/experience/insights/library/save#emergency-savings-milestone-reached) | Save | Congratulates users as they pass milestones with their emergency savings balance. | | [Fee Detected](/products/experience/insights/library/spend#fee-detected) | Spend | Helps users identify fees charged to their account. | | [Introduce Insights](/products/experience/insights/library/plan#introduce-insights) | Plan | Introduces new users to insights. | | [Large Transaction](/products/experience/insights/library/spend#large-transaction) | Spend | Notifies the user of larger-than-normal transactions. | | [Low Account Balance](/products/experience/insights/library/spend#low-account-balance) | Spend | Notifies users when an account balance falls under a certain threshold. | | [Merchant Credit Received](/products/experience/insights/library/spend#merchant-credit-received) | Spend | Informs users that they've received a refund from a merchant, and displays the refund amount. | | [Microdeposits](/products/experience/insights/library/spend#microdeposits) | Spend | Alerts users when microdeposits have reached their account. | | [Missing Interest Rate](/products/experience/insights/library/borrow#missing-interest-rate) | Borrow | Asks users to share their interest rate. | | [Monthly Credit Card Interest Summary](/products/experience/insights/library/borrow#monthly-credit-card-interest-summary) | Borrow | Shows users how much they've spent in interest on their credit cards over the last 90 days. | | [Monthly Debt to Income Comparison](/products/experience/insights/library/borrow#monthly-debt-to-income-comparison-v2) | Borrow | Provides a comparison of debt-to-income spend for the previous four months. | | [Monthly Deposit Summary](/products/experience/insights/library/spend#monthly-deposit-summary-v2) | Spend | Tracks all credits coming into a user's accounts and provides a breakdown of regular versus other income. | | [Monthly Emergency Fund Review](/products/experience/insights/library/save#monthly-emergency-fund-review) | Save | Shows users a monthly summary of their emergency goal progress. | | [Monthly Emergency Savings Reminder](/products/experience/insights/library/save#monthly-emergency-savings-reminder) | Save | Reminds users to move money into their emergency savings account. | | [Monthly Obligations Status](/products/experience/insights/library/spend#monthly-obligations-status) | Spend | Informs users whether they're on or off track to pay off their monthly obligations. | | [Monthly Spend Comparison](/products/experience/insights/library/spend#monthly-spend-comparison-v2) | Spend | Provides users with a summary of total expenses in the previous month, together with a comparison of those total expenses against the average for prior months. | | [Monthly Spend to Income Comparison](/products/experience/insights/library/spend#monthly-spend-to-income-comparison-v2) | Spend | Shows users their spend-to-income comparison for the last four months. | | [Monthly Subscription Aggregate](/products/experience/insights/library/spend#monthly-subscription-aggregate-v2) | Spend | Identifies all subscriptions paid by users in the prior month. | | [Monthly Top Merchant Spending](/products/experience/insights/library/spend#monthly-top-merchant-spending-v3) | Spend | Shows users what merchants they spent the most non-essential money on in the previous month. | | [New Merchant](/products/experience/insights/library/spend#new-merchant) | Spend | Informs users when they have new transactions with a merchant that they haven't shopped with for at least a year. | | [Payday Cash Left Over Status](/products/experience/insights/library/spend#payday-cash-left-over-status) | Spend | Informs users if they're on or off track to have money left over when their next paycheck is received. | | [Peer-to-Peer Categorization](/products/experience/insights/library/spend#peer-to-peer-categorization) | Spend | Identifies all transactions which are person to person within the last 30 days. | | [Replenish Savings](/products/experience/insights/library/save#replenish-savings) | Save | Prompts users to replenish their savings account one week after they've made a withdrawal from the account. | | [Save an Extra \$100](/products/experience/insights/library/save#save-an-extra-%24100) | Save | Informs users if they will have enough cash left over on payday to save \$100 while maintaining a \$100 buffer. | | [Save Enough to Live On](/products/experience/insights/library/save#save-enough-to-live-on) | Save | Encourages users to have emergency savings beyond an initial \$1000. | | [Savings Account Deposit](/products/experience/insights/library/save#savings-account-deposit) | Save | Congratulates users when they save money and lets them know that a little savings can make a big difference. | | [Savings Opportunity](/products/experience/insights/library/save#savings-opportunity-v2) | Save | Tests users' projected cash position on a monthly basis and notifies them when extra cash may be available for savings. | | [Set Up Direct Deposit](/products/experience/insights/library/spend#set-up-direct-deposit) | Spend | Tells users that we've detected a held account that doesn't have a direct deposit coming in and prompts them to set it up. | | [Subscription Detected](/products/experience/insights/library/spend#subscription-detected) | Spend | Notifies users of a subscription in one of their accounts that hasn't been identified before. | | [Subscription Price Increase](/products/experience/insights/library/spend#subscription-price-increase) | Spend | Notifies users that a subscription price has increased. | | [Switch Direct Deposit](/products/experience/insights/library/spend#switch-direct-deposit) | Spend | Tells users that we've detected a direct deposit that doesn't route to their held account and prompts them to switch the deposit to the held account. | | [Transparent Overdraft](/products/experience/insights/library/spend#transparent-overdraft) | Spend | Warns users of a possible overdraft projected within the next seven days. | | [Uncategorized Transactions](/products/experience/insights/library/spend#uncategorized-transactions-v2) | Spend | Identifies all transactions which have been assigned **Uncategorized** as the transaction category within the last 30 days. | | [Unexpected Subscription Payment](/products/experience/insights/library/spend#unexpected-subscription-payment) | Spend | Notifies users when a transaction is created that contradicts the user feedback on an associated scheduled payment. | | [Unified Deposit](/products/experience/insights/library/spend#unified-deposit) | Spend | Notifies users of deposits that fall into a particular category. | | [Upcoming Bill](/products/experience/insights/library/spend#upcoming-bill) | Spend | Alerts users that in three days they have a bill payment due that's not a credit card and isn't a subscription. | | [Upcoming Subscription](/products/experience/insights/library/spend#upcoming-subscription) | Spend | Shows users their upcoming subscription three days before payment occurs. | | [User Feedback](/products/experience/insights/library/plan#user-feedback) | Plan | Lets users provide feedback on their insights. | | [Weekend Spending Summary](/products/experience/insights/library/spend#weekend-spending-summary-v2) | Spend | Provides users with a summary of total non-essential expenses from the previous weekend, grouped by category with total amount spent. | | [Weekly New Merchants](/products/experience/insights/library/spend#weekly-new-merchants-v2) | Spend | Notifies users when one or more new merchants are identified that they hadn't interacted with during the previous week. | | [American](/products/experience/insights/library/plan#american-federal-bank-holidays)/[Canadian](/products/experience/insights/library/plan#canadian-federal-bank-holidays) Federal Bank Holidays | Plan | Informs users about upcoming federal bank holidays. **Choose US or CA.** | | [American](/products/experience/insights/library/plan#american-upcoming-tax-deadline-alert)/[Canadian](/products/experience/insights/library/plan#canadian-upcoming-tax-deadline-alert) Upcoming Tax Deadline Alert | Plan | Notifies users about important upcoming tax deadlines. **Choose US or CA.** | # Financial Insights Source: https://docs.mx.com/products/experience/insights/index Deliver dynamic, personalized, and predictive financial insights using our widgets or API to inform, guide, and protect end users towards financial wellness Financial Insights are intelligent, data-driven notifications and recommendations that help your users make better financial decisions. They analyze each user's transaction patterns, spending behavior, and account activity to deliver them timely, relevant, and actionable information. Choose insights from our extensive [Insights Library](/products/experience/insights/library) or [create your own](#create-custom-insights). Example insight ### Types of Insights Financial Insights cover a wide range of financial scenarios, including: * **Borrow**: Information about credit and debt management * **Plan**: Alerts about key information, such as tax deadlines and bank holidays * **Save**: Notifications about savings accounts and behavior * **Spend**: Recommendations on current spending, including low balance alerts and fee detection ## Quick Links Learn more about each insight. Are you a developer? Here's all our guides in one place. With the mission of empowering the world to be financially strong, MX is focused on providing a robust experience for clients and end users of our products and guided by the WCAG 2.1 A and AA recommendations. For more info, see [Accessibility at MX PDF](/assets/accessibility-at-MX-2023-92123ccb451c95a04578b50836441098.pdf). ### WCAG Status​ MX's web-based application that hosts our Personal Finance Management and Financial Insights products is made up of smaller parts called widgets, all of which align with WCAG 2.0 recommendations when accessed through the most recent versions of Chrome, Edge, Firefox, and Safari browsers. All enhancements and new features are designed to have strong conformance to WCAG 2.1 A & AA guidelines. MX no longer supports IE11 as Microsoft has stopped supporting their browser on August 17th, 2021. While the WCAG guidelines are focused on web accessibility rather than native applications, MX products have been upgraded to have strong conformance with the WCAG 2.0 A and AA guidelines when used on iOS and Android devices. Continual enhancements prioritize WCAG 2.1 alignment based on feedback received through user testing. MX leverages LevelAccess solutions for education, evaluation and testing. ### Current Work​ MX has adopted a phased approach to development, guided by WCAG’s four key foundations: perceivability, operability, understandability, and robustness through which legacy systems are progressively improved as we endeavor to meet the needs of end users. New features are designed for accessibility improvements from conception through completion. ### Future Work​ #### Evaluation and accreditation​ Our goal is to improve both our knowledge and users’ experiences by working with experts in the field. We will accomplish this through internal education and external engagement with a11y community. We are also evaluating automation software that can improve the speed of solutions development and verification for all users. Several MX clients have provided 3rd party evaluations of our services. We will continue to respond to these reports as a means to improving our solutions. We continue to assess the merit of formal accreditation through a third party in the future. #### User testing​ Given the unique nature of some features, we recognize the value and insight that user testing provides. In our pursuit of achieving the best overall digital experience, we have begun to incorporate user testing in development and are continuing to refine and expand our testing efforts. ### Background on Guidelines​ The Americans with Disabilities Act (ADA) does not include any language specific to websites or web-development. However, Title II of the ADA mandates that all “places of public accommodation” (all businesses open to the public) are required to remove “access barriers” that would hinder a disabled person’s access to that business’s goods or services. The World Wide Web Consortium’s (W3C) Web Content Accessibility Guidelines (WCAG 2.0 AA) is seen as the world standard for defining what an “accessible” website is. While these are only guidelines, they have been adopted as the standard by court precedence, and any future regulation will likely point to this standard. In June 2018, W3C adopted the WCAG 2.1 guidelines (which are backward compatible with WCAG 2.0 recommendations) with the additional goal of improving accessibility for users with disabilities on mobile devices. ### Additional Info​ Here are some other useful links: * [W3c](https://www.w3.org/) * [Intro to WCAG](https://www.w3.org/WAI/intro/wcag) * [WCAG 2.1 Guidelines](https://www.w3.org/TR/WCAG21/) * [Checklist we follow for A & AA standards](https://www.wuhcag.com/wcag-checklist/) Your users' data is safe inside MX's personal financial management (PFM) tools. Because PFM is embedded inside online banking, access is protected by banking-level encryption, just like an online banking account. In addition, PFM and the Mobile Banking application use their own additional layer of security when transmitting data. When users add all of their accounts to PFM, they can monitor them in one place, and are much more likely to catch potential fraudulent transactions. ### Does MX Sell User Info to 3rd Parties?​ No. Financial information is never sold to third parties. ### When a User Adds an Account Who Can See It?​ No one at a user's financial institution has the ability to access user's information in PFM. The MX Support Team (who powers the tools) may view an account, for the purposes of providing support. No one has access to a user's account credentials. User data may be aggregated for trends analysis and target marketing, but no one at a financial institution can look for a specific individual’s account, or at any individual’s complete account information. Some financial institutions may allow account impersonation for the purpose of providing support. ### Privacy Policy​ We’re committed to keeping your user's information secure, and as such we implement privacy standards to guard against identity theft and unauthorized access to user's information. We also regularly monitor and reevaluate our privacy and security policies and adapt them as necessary to deal with new conditions. We use industry-accepted standards, protocols and precautions to protect personally identifiable information from loss, misuse, unauthorized access or disclosure, alteration or destruction. We maintain physical, electronic and procedural safeguards for personally identifiable information, including using firewall barriers, encryption techniques, authentication procedures, SSL (secure socket layer) encryption, and physical safeguards. In addition, we do not sell any personally identifiable information. We will post changes to the policy in the PFM tool so that users will always know what information we gather, how we might use that information, and when we will disclose that information to third parties, if at all. We may also inform users of any changes to this policy by a prominent notice within the services or by email. In addition, and at our discretion, in the event of an update or material change, users may be required to agree to the new privacy policy as a condition precedent to your continued use of the services. ## Create Custom Insights Reach out to your MX representative to create, configure, and deploy your own custom Insights to support your unique business goals. You can define language and calls to action (CTAs), and view performance metrics for the Insights you create. To create a custom insight, you will need: * The text of your insight (title, description). We recommend a title length of less than 25 characters and a description length of less than 150 characters. * The trigger conditions (choose one): * Schedule-based: The insight appears at specific intervals. Specify the number of cooldown days where applicable. * Event-based: The insight appears when specific account or transaction events occur. Criteria can include transaction name, type, amount, merchant, category, and many others. * Example: "If a transaction amount is greater than \$100 from Epic Bank" * The text of any CTAs * CTA button (this appears at the bottom of an insight) * CTA link (this appears as part of the description copy) * The string for the postMessage event that triggers when the user clicks the CTA **NOTE** You will need to be prepared to handle CTAs through [postMessage events](/products/experience/insights/integration-guides/integrate-insights-widget#postmessage-ui-events). Custom Insights appear alongside MX-provided insights and support the same analytics and API access. ## Insights Widgets There are three widgets that display insights. The [Insights Widget](/products/experience/insights/widget-overviews/insights-widget) is a vertical feed of insights. Insights Widget The [Mini Insights Widget](/products/experience/insights/widget-overviews/mini-widget) is a carousel of insights users can swipe through. Mini Insights Widget The [Micro Insights Widget](/products/experience/insights/widget-overviews/insights-widget#micro-widget-overview) is a smaller carousel of insights. Micro Insights Widget You can also use the Platform API to [build your own UI](/products/experience/insights/integration-guides/insights-api-guide). ## Insight Generation Insights generate when triggered by either: * a system event (such as a new transaction or account update) * a [scheduled trigger](#insight-schedules) After triggering, the insights will then need to meet certain requirements before they generate. See the [Insights Library](/products/experience/insights/library) for requirements for each insight type. New users may have few or no insights at first. As users connect more accounts, import historical transactions, and make transactions, more insights will generate. ## Insight Schedules Some, but not all, insights begin triggering based on one of the following schedules. | Schedule | When It Triggers (UTC) | | :----------- | :----------------------------------------------------------------------------------------------- | | Weekly | Every Monday or Wednesday, depending on the insight. | | Monthly | Randomly between the 5th and 9th day of each month. | | Mid-Monthly | On the 15th of every month. | | Quarterly | Randomly between the 5th and 15th day of the start of each quarter. | | Semiannually | Randomly between the 5th and 35th day of the start of each semiannual period (every six months). | ## Insight Notifications Users can receive notifications from over 20 insights through any of our notification channels (in-app, SMS, push notifications, or email). Reach out to your MX representative to turn them on. ## Static vs. Dynamic Insights Every insight uses static or dynamic data. Static insights use the data that's available when the insight is created. That data doesn't change and the insight remains the same in the feed. Dynamic insights generate the same way as static insights, but can be refreshed with the latest data. ## Insight Thresholds Some insights have thresholds that cause the insight to trigger. For example, by default, the `Deposit529` insight is triggered when a deposit of \$10 or more is made. Here's a list of all insights with configurable thresholds. | Insight Template | What Can Be Configured? | Default Threshold Value | | :------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :---------------------- | | `Deposit529` | Minimum deposit amount. | 10 | | `CategorySpendingV2` | Maximum number of times this insight can generate per month. | 3 | | `DebtPaymentReminderV2` | Days prior to the due date this insight is generated. For example, our default value generates this insight one day, three days, and five days before the due date. | 1, 3, 5 | | `GovernmentDeposit` | Minimum deposit amount. | 500 | | `HSADeposit` | Minimum deposit amount. | 10 | | `LargeDeposit` | Minimum deposit amount. | 500 | | `LargeTransaction` | Minimum transaction amount. | 500 | | `MonthlySavings` | Largest amount that a user is prompted to save in this insight. | N/A | | `SavingsDeposit` | Number of days to look back for a savings deposit. | 1 | | `SavingsDeposit` | Maximum number of times this insight is generated per month. | 5 | | `SavingsOpportunityV2` | Largest amount that a user is prompted to save in this insight. | 500 | | `SavingsOpportunityV2` | Days to wait before another `SavingsOpportunity` or `MonthlySavings` insight is generated. | 14 | | `SavingsOpportunityV2` | Least amount of money required to be left in checking after contributing to savings. | 200 | | `TransparentOverdraft` | Maximum number of days to look back to determine if a user is at risk. If set to 0, the at-risk requirement isn't utilized. | 180 | | `UncategorizedTransactionsV2` | Minimum number of days to wait before another Uncategorized Transactions insight generates. | 15 | | `NewMerchant` and `WeeklyNewMerchants` | Minimum age of a new merchant transaction's account (in days). | 1 | | `WeeklySmallPurchasesSummary` | Smallest transaction amount to be considered a small purchase. | 10 | | `WeeklySmallPurchasesSummary` | Minimum aggregate amount for small purchases. | 30 | ## Insight Versioning When we make a change to an insight that requires backend changes beyond what the insight was originally intended to do, we create a new version of the insight. An example of this is the WeekendSpendingSummary and WeekendSpendingSummaryV2 insight templates. We suggest you use the latest version for each insight. ## Supported Browsers​ MX supports HTML5-compliant browsers that support TLSv1.2 or higher (required since March 20, 2017). ### Supported Desktop Browsers​ MX tests its web applications on the **current** version and **previous** version of the following browsers: | Browser | PC | Mac | | -------------- | --- | --- | | Chrome | Yes | Yes | | Microsoft Edge | Yes | N/A | | Firefox | Yes | Yes | | Safari | No | Yes | **BLOCKED BROWSERS** MX doesn't support Internet Explorer and won't address related issues. MX may actively block some browsers from displaying our products when the results would provide a poor user experience. Browsers in Compatibility or Quirks mode may not function and can be blocked if performance is degraded. ### Supported Mobile Browsers​ MX tests its web applications on the **current** version and **previous** version of iOS and Android, using the following browsers: | Browser | iOS | Android | | --------------- | --- | ------- | | Chrome | No | Yes | | Safari | Yes | N/A | | WKWebView | Yes | N/A | | Android WebView | N/A | Yes | **NOTE** UIWebView is no longer supported. Apple recommends using [WKWebView](https://developer.apple.com/documentation/uikit/uiwebview). ### Older Browsers​ Older versions of supported browsers aren't explicitly tested. MX will review issues as reported, but compatibility is not guaranteed and you may be required to upgrade. # Insights Integration Guides Source: https://docs.mx.com/products/experience/insights/integration-guides/index Learn how to set up your Financial Insights user experience (formerly Developer Guides). We offer the following guides to help developers integrate with our Financial Insights product. Learn step-by-step how to embed our Insights Widget. Learn how to build your own insights UI based on the data we provide. ## Localize the Insights Widgets Pass the desired language as a parameter in the `Accept-Language` header with requests to the get widget URL endpoint. Widgets will default to `en-US`, but the widgets support `en-CA`, `en-US`, `es`, `fr`, and `fr-CA`. # Integrate the Insights Widget Source: https://docs.mx.com/products/experience/insights/integration-guides/integrate-insights-widget This guide shows you how to integrate the Insights Widget on a [website using an iFrame](#integrate-on-a-website-iframe), on a [website using the Widget Loader](#integrate-on-a-website-widget-loader), or on the [mobile app](#integrate-on-a-mobile-app). For information on widget behavior, reference the [Widget Overview](/products/experience/insights/widget-overviews/insights-widget). **INFO** Before you can integrate the widget, you must have worked with MX to enable your access to insights. For this guide, you'll either use the Platform API or SSO API. The API you use depends on what you have purchased and have enabled. If you have the Nexus API enabled, you'll use the SSO API. ## Integrate on a Website (iFrame) This shows how to integrate the widget on a website using an iFrame. #### Step 1 Create an iFrame. Make sure the width and height use the widget's [supported dimensions](../../insights/widget-overviews/insights-widget#supported-dimensions). If you use `sandbox`, some attributes must be whitelisted for the widget to work: `sandbox="allow-forms allow-same-origin allow-scripts"`. ```html Example focus={1-5} theme={null} ``` #### Step 2 In the iFrame's `src`, you'll need to request a widget URL and specify `pulse_widget` as the `widget_type` using the [Platform API](/api-reference/platform-api/reference/request-widget-url) or [SSO API](/api-reference/sso/v3/reference/widget-urls/get-widget-with-config-options). The URL you'll receive is single-use and expires after 10 minutes. You must request a new URL every time the page is rendered. See [Example API Requests](#example-api-requests) for different configurations. ```html Example focus={1-5} theme={null} ``` #### Step 3 Optionally create listeners for [application events](#application-events). See [Postmessage UI Events](#postmessage-ui-events) for more info. ```html Example focus={6-19} theme={null} ``` #### Step 4 Configure event listeners for each [Insights Widget event](#insights-widget-events). See [Postmessage UI Events](#postmessage-ui-events) for general info on our postMessage events. ```html Example focus={19-22} theme={null} ``` **SUCCESS** Congrats! You've integrated the Insights Widget! ## Integrate on a Website (Widget Loader) This shows how to integrate the widget on a website using the widget loader. #### Step 1 Add the widget loader script to the page. Place this file before any other code related to the widgets. This custom script loads the widgets onto the page. You can load the widget loader from the MX production server or download and store it in your local environment. We update the widget loader when needed, so if you're caching it on your server, refresh your cached version monthly. ```html Example focus={4} theme={null} My Web Page
``` #### Step 2 Add a widget placeholder element. Our widget loader will use this placeholder element to embed an iframe containing the widget. The element must have an `id` of `md-widget`. ```html Example focus={14} theme={null} My Web Page
``` #### Step 3 Load the widget into the placeholder element. Create a new instance of the `MoneyDesktopWidgetLoader` class, which is defined in the widget loader script. When you instantiate `MoneyDesktopWidgetLoader`, you must pass in an object with at least the required URL parameter (see step 4), and possibly one or more [optional parameters](#widget-loader-parameters). The widget loader will wait until the page has been loaded, and then load the widget into the placeholder element. Make sure the widget uses its [supported dimensions](/products/experience/insights/widget-overviews/insights-widget#supported-dimensions). ```html Example focus={5-11} theme={null} My Web Page
``` #### Step 4 You'll need to request a widget URL through the Platform API or SSO API and set it in the URL parameter. The URL you'll receive is single-use and expires after 10 minutes. You must request a new URL every time the page is rendered. You can request a widget URL for the Insights Widget by specifying `pulse_widget` as the `widget_type`, using the [Platform API](/api-reference/platform-api/reference/request-widget-url) or [SSO API](/api-reference/sso/v3/reference/widget-urls/get-widget-with-config-options). ```html Example focus={7} theme={null} My Web Page
``` #### Step 5 Optionally create listeners for [application events](#application-events). See [Postmessage UI Events](#postmessage-ui-events) for more information. ```html Example focus={15-29} theme={null} My Web Page
``` #### Step 6 Configure event listeners for the [Insights Widget events](#insights-widget-events). See [Postmessage UI Events](#postmessage-ui-events) for general info on our postMessage events. ```html Example focus={28-33} theme={null} My Web Page
``` **SUCCESS** Congrats! You've integrated the Insights Widget! *** ## Integrate on a Mobile App To integrate the widget on a mobile application: 1. Request `pulse_widget` as the `widget_type`, using the [Platform API](/api-reference/platform-api/reference/request-widget-url) or [SSO API](/api-reference/sso/v3/reference/widget-urls/get-widget-with-config-options). The URL you'll receive is single-use and expires after 10 minutes. You must request a new URL every time the page is rendered. 2. Load the URL received from the previous request into a WebView. 3. See [Events in Mobile WebViews](#events-in-mobile-webviews). 4. Capture and parse URLs for [application events](#application-events). 5. Capture and parse URLs for [Insights Widget events](#insights-widget-events). ### Common Problems This section covers some common problems with loading a widget URL into a WebView. #### Minimum Size To embed our mobile widgets into a WebView, we require a device width of at least 320 pixels. Depending on the implementation of the WebView, smaller devices may not be provided the full width, leading to display issues. #### WKWebView vs. UIWebView (iOS) In apps that run in iOS 8 and later, MX only supports WKWebView. If you previously implemented UIWebView, update your implementation to use WKWebView. Apple recommends this. For more information, see Apple's developer documentation for [UIWebView](https://developer.apple.com/documentation/uikit/uiwebview) and [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview). #### Default Padding (iOS) iOS adds padding to its WebViews by default, which can cause problems. To fix this: 1. Select the WebView providing the widgets in your application and navigate to the size inspector. 2. Change the layout margins from "Default" to "Explicit." 3. Update the left and right margins to "0." 4. Ensure the Width is at least 320 pixels. #### Default Margin (iOS and Android) Most browsers will have a default margin (set in the user agent stylesheet) on the body element when rendering the HTML page responsible for loading a widget. This margin is deducted from the total available width of the containing element, which will cause a problem. To fix this: 1. Determine the computed width available on the body element. The width available to the iframe can be confirmed by inspecting the iframe injected by MX and typing window\.innerWidth in the javascript console. The width available to the iframe must be at least 320 pixels. 2. Confirm the body and HTML elements have their padding and margin set to "0." #### Viewport (iOS and Android) For mobile widgets to render properly, the viewport must be set in a meta tag on the HTML page used to load the widget URL. The viewport is the size of the window through which a page is seen. It can be smaller or larger than the actual size of a page or device screen. On most mobile devices, the virtual viewport is larger than the actual screen size; web pages render according to the viewport size, then shrunk down to the actual screen size. This helps when viewing pages that aren't optimized for mobile, but for pages that are optimized for mobile (like the mobile widgets), the viewport meta tag is used to guarantee that the page renders correctly. Set a meta tag within the `` element as follows. ```html Example theme={null} ``` ## Example API Requests The following examples are for requesting a Micro Insights Widget URL in the Platform API. Request a widget to **embed on a website.** ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "widget_type": "pulse_widget" } }' ``` Request a widget to **embed on a mobile app through a WebView.** ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "is_mobile_webview": true, "widget_type": "pulse_widget" } }' ``` **Request the widget in Spanish** by adding the `Accept-Language` header and setting it to `es`. ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Accept-Language: es' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "widget_type": "pulse_widget" } }' ``` ## PostMessage UI Events When certain events are triggered in our UI, we send you a postMessage UI event. These events have the information you need to take action in your codebase in response to the event. If integrating on mobile through a WebView, an alternative to standard postMessage UI events is required. See [Events in Mobile WebViews](#events-in-mobile-webviews) for more information. **WARNING** Don't use postMessage UI events for keeping data in sync between platforms. [Webhooks](/resources/webhooks) are a more reliable way of coordinating events between your servers and MX servers. PostMessage UI events from MX have the following properties: * The `mx` field that lets you filter out postMessage UI events coming from MX. * The `type` field that identifies what the event represents at a high level. * The `metadata` object field that has information related to the `type`. The following is an example integration that lets you listen to the events we send. ```js Example Integration theme={null} function handleEvent(event) { if (event.data.mx) { // handle the mx post message using event.data.type and event.data.metadata. } } window.addEventListener('message', handleEvent) ``` ### Events in Mobile WebViews **NOTE** This section only applies if you are embedding the widget in a WebView. Because of the technical limitations of WebView-based widget integrations, an alternative to standard postMessage UI events is required if embedding the widget into a WebView. When requesting widget URLs using the Platform API or SSO API, you must include the `is_mobile_webview` field with a value of true in your request to access WebView event messages. In WebView integrations, you must capture the URLs delivered via `window.location = "someurl"` calls within the iframe and use the information provided in those calls to build the necessary logic for coordinating events. All MX URL message events will have the `mx://` prefix as well as the following format: `mx:///?metadata=`. The following is an example URL message: `mx://account/created?metadata="{'guid':'ACT-1'}"`. You must capture the URL, parse out the path and query string, then JSON-decode the `metadata` field. ### Application Events You must create listeners for our postMessage UI application events. #### Widget Load This event is triggered when the widget is loaded. ```json theme={null} { "type": "mx/load", "mx": true } ``` #### Widget Ping This event is used to keep the widget session alive. ```json theme={null} { "type": "mx/ping", "mx": true, "metadata": { "user_guid": "USR-123", "session_guid": "ANS-123" } } ``` #### Widget focusTrap This event is triggered when popover content which traps the focus onto a particular element is opened or closed, but only in the case that no other popover content is already open. This event is triggered by some drawers, menu buttons, and modals. ```json theme={null} { "type": "mx/focusTrap", "mx": true, "metadata": { "trapped": "true" } } ``` ### Insights Widget Events When displayed in the Insights Widget, some insights contain a call-to-action (CTA). Some CTAs will direct the user to the appropriate location by default, but others will require you to send the user somewhere to complete an action. This process is as follows: 1. We detect that a user has clicked a call-to-action (CTA) on one of our insights that require you to send the user somewhere outside of our widget. 2. We send you a postMessage UI event to let you know a user has clicked this CTA. Depending on the CTA and associated insight that the user clicked, we'll send you additional information about the event inside the postMessage UI event. 3. The listener **you** create for this event sends the user to the appropriate location within your mobile app or website based on the details we sent through the postMessage. You must create listeners for each of the following insight templates (only create listeners for the templates MX has enabled for you). | Insight Template | When MX Sends This Event | What You Must Do | | :----------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `DesignateEmergencySavingsAccount` | When the user clicks the **Open Savings Account** CTA in the scenario where the user doesn't have a savings account. | Send the user to open a savings account. | | `EmergencyFundWithdrawal` | When the user clicks the **View my emergency savings** CTA or the **Transfer funds** CTA. The CTA that appears depends on if you have transfers for funds enabled. | When MX sends you this event, you must either send the user to view their emergency savings or create a transfer, depending on whether you have transfers for funds enabled or disabled. | | `LowAccountBalance` | When the user clicks the **Transfer funds** CTA. | Send the user to transfer funds to their low balance account. | | `MonthlyEmergencyFundReview` (scenario 1) | When the user clicks the **View my emergency savings** CTA. | Send the user to where they can view their emergency savings amount. | | `MonthlyEmergencyFundReview` (scenario 2) | When the user clicks the **Create new goal** CTA. | Send the user to the Goals Widget. | | `MonthlyEmergencyFundReview` (scenario 3) | When the user clicks the **Create transfer** CTA. | Send the user somewhere where they can transfer money. | | `MonthlyObligationsStatus` | When the user clicks the **Make a transfer** CTA. | Send the user somewhere where they can transfer money. | | `MonthlySpendingPlanCelebration` | When the user clicks the **Visit spending plan** CTA. | Send the user to the Spending Plan Widget. | | `ReplenishSavings` | When the user selects the **Create Transfer** CTA. | Send the user to create a transfer to their savings account. | | `SaveAnExtra100Dollars` | When the user selects the **Make A Transfer** CTA. | Send the user to where they can make a transfer. | | `SavingsAccountDeposit` | When the user selects either the **View my emergency savings** or **Start saving for emergencies** CTA. | Send the user to the Goals Widget. From there the user can see their emergency savings goal or start an emergency savings goal. | | `SavingsMilestoneEmergencyFund` | When the user selects the **View my emergency savings** CTA. | Send the user to where they can view the Goals Widget. | | `SavingsOpportunityV2` (scenario 1) | This insight template has two scenarios. This covers scenario 1, where `"action": 'op_1'`. We'll send you a postMessage for this scenario when the user already has an eligible savings account to transfer money to and selects the **Transfer Funds** CTA. | Send the user to create a transfer to their savings account. | | `SavingsOpportunityV2` (scenario 2) | This insight template has two scenarios. This covers scenario 2, where `"action": 'op_2'`. We'll send you a postMessage for this scenario when the user doesn't have an eligible savings account to transfer money to and selects the **Open Savings Account** CTA. | Send the user to open a savings account. | | `SetUpDirectDeposit` | When the user clicks the **Set Up Direct Deposit** CTA. | When MX sends you this event, you must activate your direct deposit integration. | | `SpendingPlanCreatedCelebration` | When the user clicks either the **Start Spending Plan** or **Visit Spending Plan** CTA. | Send the user to the Spending Plan Widget. | | `SwitchDirectDeposit` | When the user clicks the **Switch Direct Deposit** CTA. | When MX sends you this event, you must activate your direct deposit integration. | | `TransparentOverdraft` | When the user clicks the **Transfer funds** CTA. | Send the user to transfer funds to their potentially overdrawn account. | | `UnifiedDepositEmergencyFund` (scenario 1) | When the user clicks the **Start saving for emergencies** CTA. | Send the user to the Goals Widget. | | `UnifiedDepositEmergencyFund` (scenario 2) | When the user clicks the **Transfer funds** CTA. | Send the user to a location where they can transfer funds to their emergency savings fund. | | `UnifiedDepositEmergencyFund` (scenario 3) | When the user clicks the **View my emergency savings** CTA. | Send the user to the Goals Widget. | | `WeeklyNoSpendDays` | When the user clicks the **Visit Spending Plan** CTA. | Send the user to the Spending Plan Widget, where they can see the widget as normal or onboard to it. | These are the base metadata fields for each event we send. Fields specific to certain insight templates appear in the sections that follow. | Field | Type | Definition | | --------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `action` | String | Represents the scenarios within the insight. This value, and additional fields relating to this value, are listed in the sections that follow. Most insights only have one scenario. The `SavingsOpportunityV2` insight will require you to configure events for two possible scenarios within that insight. | | `beat_guid` | String | Insights were previously called "beats." This is the unique identifier for the insight. Defined by MX. | | `beat_template` | String | Insights were previously called "beats." This is a short label for the insight being delivered. For example, `DesignateEmergencySavingsAccount`. | ```json Example theme={null} { "type": "mx/pulse/beat/cta", "mx": true, "metadata": { "action": "op_1", "beat_guid": "BET-123", "beat_template": "DesignateEmergencySavingsAccount" } } ``` #### DesignateEmergencySavingsAccount Action `"action": 'op_1'`. #### EmergencyFundWithdrawal Action `"action": 'op_1'` #### LowAccountBalance Action `"action": 'op_1'`. | Field | Type | Definition | | -------------- | ------ | ----------------------------------------------------- | | `account_guid` | String | The unique identifier for the account. Defined by MX. | #### MonthlyEmergencyFundReview Actions The following values for used for different scenarios in the insight and don't have any fields beyond the base metadata fields. * `"action": 'op_1'`. * `"action": 'op_2'`. * `"action": 'op_3'`. #### MonthlyObligationsStatus Action `"action": 'op_1'`. #### MonthlySpendingPlanCelebration Action `"action": 'op_1'`. #### ReplenishSavings Action `"action": 'op_1'`. | Field | Type | Definition | | ------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------ | | `account_guid` | String | The unique identifier for the account. Defined by MX. | | `account_name` | String | The human-readable name of the account. | | `accounts` | Array | An array of account objects, each of which contains the `account_guid` and `account_name` described in this table. | | `total_amount_withdrawn` | Integer | The total amount withdrawn from all included accounts. | #### SaveAnExtra100Dollars Action `"action": 'op_1'`. #### SavingsAccountDeposit Action `"action": 'op_1'`. | Field | Type | Definition | | :------------------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------------- | | `account_guid` | String | The unique identifier for the account. Defined by MX. | | `goal_guid` (if available) | String | The unique identifier for the goal. Defined by MX. This field will return an empty string for the "start saving for emergencies" scenario. | | `user_guid` | String | The unique identifier for the user. Defined by MX. | #### SavingsMilestoneEmergencyFund Action `"action": 'op_1'`. | Field | Type | Definition | | :------------- | :----- | :---------------------------------------------------- | | `account_guid` | String | The unique identifier for the account. Defined by MX. | | `goal_guid` | String | The unique identifier for the goal. Defined by MX. | | `user_guid` | String | The unique identifier for the user. Defined by MX. | #### SavingsOpportunityV2 Actions `"action": 'op_1'`. | Field | Type | Definition | | ------------------------- | ------- | --------------------------------------------------------------------------------- | | `amount` | Integer | The amount the user would like to transfer to savings. | | `destination_account_ids` | Array | The partner-defined identifiers for the accounts eligible to transfer funds to. | | `source_account_ids` | Array | The partner-defined identifiers for the accounts eligible to transfer funds from. | `"action": 'op_2'`. | Field | Type | Definition | | -------------------- | ------- | --------------------------------------------------------------------------------- | | `amount` | Integer | The amount the user would like to transfer to savings. | | `source_account_ids` | Array | The partner-defined identifiers for the accounts eligible to transfer funds from. | #### SpendingPlanCreatedCelebration Action `"action": 'op_1'`. #### TransparentOverdraft Action `"action": 'op_1'`. | Field | Type | Definition | | ---------------------------- | ------- | --------------------------------------------------- | | `destination_account_ids` | Array | Array of potentially overdrawn account numbers. | | `projected_overdraft_amount` | Integer | The projected amount the account will be overdrawn. | | `user_guid` | String | The unique identifier for the user. Defined by MX. | #### UnifiedDepositEmergencyFund Actions `"action": 'op_1'`. | Field | Type | Definition | | :------------- | :----- | :---------------------------------------------------------------------------------------------------------------- | | `account_guid` | String | The unique identifier for the account. Defined by MX. | | `goal_guid` | String | The unique identifier for the goal. Defined by MX. For this action, the `goal_guid` will be an empty string `''`. | | `user_guid` | String | The unique identifier for the user. Defined by MX. | `"action": 'op_2'`. | Field | Type | Definition | | :------------- | :----- | :---------------------------------------------------- | | `account_guid` | String | The unique identifier for the account. Defined by MX. | | `goal_guid` | String | The unique identifier for the goal. Defined by MX. | | `user_guid` | String | The unique identifier for the user. Defined by MX. | `"action": 'op_3'`. | Field | Type | Definition | | :------------- | :----- | :---------------------------------------------------- | | `account_guid` | String | The unique identifier for the account. Defined by MX. | | `goal_guid` | String | The unique identifier for the goal. Defined by MX. | | `user_guid` | String | The unique identifier for the user. Defined by MX. | #### WeeklyNoSpendDays Action `"action": 'op_1'`. ## Widget Loader Configurations This section is for integrating a widget on desktop using the Widget Loader. It shows the [parameters](#widget-loader-parameters) you'll use to set things like the widget's height and width, [additional configurations](#additional-configurations) that let you set configurations for specific widgets, and also has the following sections to further help your integration: * [Create a Loading Message](#create-a-loading-message) * [Keeping a Session Alive and Logging Out](#keeping-a-session-alive-and-logging-out) * [Loading Multiple Widgets](#loading-multiple-widgets) * [Loading Widgets at Different Times](#loading-widgets-at-different-times) * [Master Widget Deep Linking](#master-widget-deep-linking) ### Widget Loader Parameters When you instantiate `MoneyDesktopWidgetLoader`, you must pass in an object with at least the required URL parameter, and any of the following optional parameters. | Parameter | Required? | Default Value | Description | | ------------------ | --------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `autoload` | No | `true` | Determines if the widget loads automatically. See [Loading Widgets at Different Times](#loading-widgets-at-different-times). | | `config` | No | | This contains an object in which you can set configurations. Some of these configurations are for specific widgets. While setting configurations this way is supported, the most current way of settings these configurations is through the widget URL request. See [Configuration Options](#configuration-options) for more info. | | `deep_link_params` | No | | This allows you to request a widget URL and provide a desired `launch_integration` destination. This requested widget URL will immediately mount the Atomic direct-deposit UX. | | `height` | No | `600` | The widget's height, in pixels or a percentage. | | `id` | No | `'md-widget'` | Tells the widget loader what element to place the widget in. See [Loading Multiple Widgets](#loading-multiple-widgets). | | `width` | No | `'100%'` | The widget's width, in pixels or a percentage. | | `url` | Yes | | The widget's URL, received through an SSO API or Platform API request. | #### Config Parameter The `config` object, as shown in the following example, contains configurations options. ```html Example theme={null} var myWidget = new MoneyDesktopWidgetLoader({ url: getUrl(url), width: 850, height: 550, config: { pulse: { ui_message_version: 4 } }, postMessageOrigin: "*" }); ``` You can set the following configuration options. | Configuration Option | Data Type | Description | | -------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `is_mobile_webview` | Boolean | Defaults to `false`. Renders the widget in a mobile WebView. Executes URL updates in place of the JavaScript event postMessages. | | `language` | String | **Deprecated**. See [Localize Insights Widgets](/products/experience/insights/integration-guides#localize-the-insights-widgets). | | `ui_message_version` | Integer | Use this to specify which version of postMessage UI events are triggered. All new implementations must include this option when getting any widget URL and must set it to version `4`. Prior versions are deprecated and supported only for existing integrations. | #### Deep Linking Parameter You can set the following deep-linking options. | Deep Link Option | Data Type | Description | | -------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `launch_integration` | String | **Must be `direct-deposit`.** This lets the widget know to “deep link” to a specific integration. If the `account_guids` are provided under the `deep_link_params`, the direct-deposit session will be initiated with those accounts as potential deposit destinations. | ### Create a Loading Message Any HTML placed inside of the widget placeholder element will be replaced once the widget iframe has loaded. This means you can use the placeholder element's inner HTML to display a loading message. Since this is just HTML, it can be text, images, or anything you want. The following example adds some loading text that will appear until the widget has loaded. ```html Example theme={null} My Web Page
Loading...
``` ### Keeping a Session Alive and Logging Out MX provides two important functions for the widget loader: ping and logout. The `ping` function resets the session timer, allowing you to keep the session open as long as needed. The default timeout period is 900 seconds, and ping can be used anywhere in that period to restart the timer. A custom timeout period can be set by contacting MX, but MX recommends using the ping method rather than setting a longer timeout. ```html theme={null} ``` The `logout` function ends the session and redirects to the session timeout URL defined in your client profile. If no URL is defined, there is no redirect. Contact MX if you wish to set a specific session timeout URL. ### Loading Multiple Widgets To load multiple widgets on a single page: 1. Define multiple placeholder elements, each with a unique CSS `id`. 2. In your JavaScript, create an instance of `MoneyDesktopWidgetLoader` for each widget. 3. Connect each loader instance to a placeholder element by setting the `id` property value as the CSS `id`. After the page has loaded, all widgets will load in their respective elements. Here’s an example of loading 3 separate widgets onto a single page. ```html Example theme={null} My Web Page
``` ### Loading Widgets at Different Times By default, widgets load automatically once the web page has loaded. If you'd like to load your widgets manually you can use the autoload option by setting autoload to false when instantiating `MoneyDesktopWidgetLoader`. When you're ready to load a widget, call the load method on the instance of `MoneyDesktopWidgetLoader` with the URL. Here’s an example of loading the Accounts Widget on page load, then loading the Transactions Widget when a button is selected. ```html Example theme={null} My Web Page
``` # Integrate the Micro Insights Widget Source: https://docs.mx.com/products/experience/insights/integration-guides/integrate-micro-widget This guide shows you how to integrate the Micro Insights Widget on a [website using an iFrame](#integrate-on-a-website-iframe), on a [website using the Widget Loader](#integrate-on-a-website-widget-loader), or on a [mobile app](#integrate-on-a-mobile-app). For information on widget behavior, reference the [Widget Overview](/products/experience/insights/widget-overviews/micro-widget). **INFO** Before you can integrate the widget, you must have worked with MX to enable your access to insights. For this guide, you'll either use the Platform API or SSO API. The API you use depends on what you have purchased and have enabled. If you have the Nexus API enabled, you'll use the SSO API. ## Integrate on a Website (iFrame) This shows how to integrate the widget on a website using an iFrame. #### Step 1 Create an iFrame. Make sure the width and height use the widget's [recommended dimensions](/products/experience/insights/widget-overviews/insights-widget#recommended-dimensions). ```html Example focus={1-5} theme={null} ``` #### Step 2 In the iFrame's `src`, you'll need to request a widget URL specifying `micro_pulse_carousel_widget` as the `widget_type` using the [Platform API](/api-reference/platform-api/reference/request-widget-url) or [SSO API](/api-reference/sso/v3/reference/widget-urls/get-widget-with-config-options). The URL you'll receive is single-use and expires after 10 minutes. You must request a new URL every time the page is rendered. ```html Example focus={1-5} theme={null} ``` #### Step 3 Optionally create listeners for these two application events: * [Widget Load](#widget-load) – triggered when the widget is loaded. * [Widget Ping](#widget-ping) – used to keep the widget session alive. See [Postmessage UI Events](#postmessage-ui-events) for more info. ```html Example focus={6-19} theme={null} ``` #### Step 4 Configure event listeners for: * An event for when the user clicks the **View all >** CTA. When the user clicks this, you'll consume the info we send to you in the postMessage event and then send the user to the Insights Widget. * An event for when the user clicks the **Learn more** CTA. When the user clicks this, you'll consume additional information from the postMessage event. This will let you send the user to the Insights Widget with the insight the user clicked on at the top of the feed. See [Postmessage UI Events](#postmessage-ui-events) for general info on our postMessage events. ```html Example focus={19-22} theme={null} ``` **SUCCESS** Congrats! You've integrated the Micro Insights Widget! ## Integrate on a Website (Widget Loader) This shows how to integrate the widget on a website using the widget loader. #### Step 1 Add the widget loader script to the page. Place this file before any other code related to the widgets. This custom script loads the widgets onto the page. You can load the widget loader from the MX production server or download and store it in your local environment. We update the widget loader when needed, so if you're caching it on your server, refresh your cached version monthly. ```html Example focus={4} theme={null} My Web Page
``` #### Step 2 Add a widget placeholder element. Our widget loader will use this placeholder element to embed an iframe containing the widget. The element must have an `id` of `md-widget`. ```html Example focus={14} theme={null} My Web Page
``` #### Step 3 Load the widget into the placeholder element. Create a new instance of the `MoneyDesktopWidgetLoader` class, which is defined in the widget loader script. When you instantiate `MoneyDesktopWidgetLoader`, you must pass in an object with at least the required URL parameter (see step 4), and possibly one or more [optional parameters](#widget-loader-parameters). The widget loader will wait until the page has been loaded, and then load the widget into the placeholder element. Make sure the widget uses its [recommended dimensions](/products/experience/insights/widget-overviews/insights-widget#recommended-dimensions). ```html Example focus={5-11} theme={null} My Web Page
``` #### Step 4 You'll need to request a widget URL through the Platform API or SSO API and set it in the URL parameter (the example is hardcoded). The URL you'll receive is single-use and expires after 10 minutes. You must request a new URL every time the page is rendered. You can request a widget URL for the Micro Insights Widget by specifying `micro_pulse_carousel_widget` as the `widget_type`, using the [Platform API](/api-reference/platform-api/reference/request-widget-url) or [SSO API](/api-reference/sso/v3/reference/widget-urls/get-widget-with-config-options). See [Example API Requests](#example-api-requests) for different configurations. ```html Example focus={7} theme={null} My Web Page
``` #### Step 5 Optionally create listeners for these two application events: * [Widget Load](#widget-load) – triggered when the widget is loaded. * [Widget Ping](#widget-ping) – is used to keep the widget session alive. See [Postmessage UI Events](#postmessage-ui-events) for more info. ```html Example focus={15-29} theme={null} My Web Page
``` #### Step 6 Configure event listeners for the [Micro Insights Widget events](#micro-widget-events): * An event for when the user clicks the **View all >** CTA. When the user clicks this, you'll consume the info we send to you in the postMessage event and then send the user to the Insights Widget. * An event for when the user clicks the **Learn more** CTA. When the user clicks this, you'll consume additional information from the postMessage event. This will let you send the user to the Insights Widget with the insight the user clicked on at the top of the feed. See [Postmessage UI Events](#postmessage-ui-events) for general info on our postMessage events. ```html Example focus={28-31} theme={null} My Web Page
``` **SUCCESS** Congrats! You've integrated the Micro Insights Widget! ## Integrate on a Mobile App To integrate the widget on a mobile app: 1. Request `micro_pulse_carousel_widget` as the `widget_type`, using the [Platform API](/api-reference/platform-api/reference/request-widget-url) or [SSO API](/api-reference/sso/v3/reference/widget-urls/get-widget-with-config-options). The URL you'll receive is single-use and expires after 10 minutes. You must request a new URL every time the page is rendered. See [Example API Requests](#example-api-requests) for different configurations. 2. Load the URL received from the previous request into a WebView. 3. See [Events in Mobile WebViews](#events-in-mobile-webviews). 4. Capture and parse a URL for the widget load and widget ping [application events](#application-events). 5. Capture and parse two URLs, relating to the [Micro Insights Widget events](#micro-widget-events): * A URL for when the user clicks the **View all >** CTA. When the user clicks this, you'll consume the info we send to you in the URL and then send the user to the Insights Widget. * A URL for when the user clicks the **Learn more** CTA. When the user clicks this, you'll consume additional information from the URL. This will let you send the user to the Insights Widget with the insight the user clicked on at the top of the feed. **SUCCESS** Congrats! You've integrated the Micro Insights Widget! ## Move Insight to Top of Feed This guide shows you how to move an insight to the top of the feed in the Insights Widget. You'll want to use this if you're also using the Mini or Micro Insights Widget. This is so users can select **View More** above an insight in the Mini Insights Widget, which sends them to the full feed, then see that insight at the top. To request an Insights Widget with a specified insight displayed at the top: 1. Request the Insights Widget with the `insight_guid` configuration, as shown in the examples. Set the value for the `insight_guid` to the vale of the `beat_guid` you received from the Mini Insights Widget postmessage UI event. 2. The response from this Insights Widget request will contain the URL for an Insights Widget that has the specified insight at the top of the feed. ```shell SSO theme={null} curl -i -X POST https://int-sso.moneydesktop.com/{client_id}/users/{id}/urls.json \ -H 'Content-Type: application/vnd.moneydesktop.sso.v3+json' \ -H 'Accept: application/vnd.moneydesktop.sso.v3+json' \ -H 'MD-API-KEY: {api_key}' \ -d '{ "url": { "type": "pulse_widget", "insight_guid": "BET-123" } }' ``` ```shell Platform theme={null} curl -i -X POST 'https://int-api.mx.com/users/{user_id}/widget_urls' \ -u '{client_id}:{api_key}' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -d '{ "widget_url": { "widget_type": "pulse_widget", "insight_guid": "BET-123" } }' ``` ### Common Problems This section covers some common problems with loading a widget URL into a WebView. #### Minimum Size To embed our mobile widgets into a WebView, we require a device width of at least 320 pixels. Depending on the implementation of the WebView, smaller devices may not be provided the full width, leading to display issues. #### WKWebView vs. UIWebView (iOS) In apps that run in iOS 8 and later, MX only supports WKWebView. If you previously implemented UIWebView, update your implementation to use WKWebView. Apple recommends this. For more information, see Apple's developer documentation for [UIWebView](https://developer.apple.com/documentation/uikit/uiwebview) and [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview). #### Default Padding (iOS) iOS adds padding to its WebViews by default, which can cause problems. To fix this: 1. Select the WebView providing the widgets in your application and navigate to the size inspector. 2. Change the layout margins from "Default" to "Explicit". 3. Update the left and right margins to "0". 4. Ensure the Width is at least 320 pixels. #### Default Margin (iOS and Android) Whether using WebViews on Android or iOS, most browsers will have a default margin (set in the user agent stylesheet) on the body element when rendering the HTML page responsible for loading a widget. This margin is deducted from the total available width of the containing element, which will cause a problem. To fix this: 1. Determine the computed width available on the body element. The width available to the iframe can be confirmed by inspecting the iframe injected by MX and typing window\.innerWidth in the javascript console. The width available to the iframe must be at least 320 pixels. 2. Confirm the body and HTML elements have their padding and margin set to "0." #### Viewport (iOS and Android) For mobile widgets to render, the viewport must be set in a meta tag on the HTML page used to load the widget URL. The viewport is the size of the window through which a page is seen. It can be smaller or larger than the actual size of a page or device screen. On most mobile devices, the virtual viewport is larger than the actual screen size; web pages are rendered according to the viewport size, then shrunk down to the actual screen size. This helps when viewing pages that aren't optimized for mobile, but for pages that are optimized for mobile (like the mobile widgets), the viewport meta tag is used to guarantee that the page is rendered properly. Set a meta tag within the `` element as follows. ```html Example theme={null} ``` ## Example API Requests The following examples are for requesting a Micro Insights Widget URL in the Platform API. Request a widget to **embed on a website.** ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "widget_type": "micro_pulse_carousel_widget" } }' ``` Request a widget to **embed on a mobile app through a WebView.** ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "is_mobile_webview": true, "widget_type": "micro_pulse_carousel_widget" } }' ``` If **embedding multiple instances of the Micro Insights Widget**, you'll want to set `microwidget_instance_id` to a unique string value for every instance. This lets us collect data for each instance of the widget. For example, one instance that displays on the accounts page could be set as follows... ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "microwidget_instance_id": "accounts_page", "widget_type": "micro_pulse_carousel_widget" } }' ``` While another instance of the Micro Insights Widget that appears on the transactions page could be set as... ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "microwidget_instance_id": "transactions_page", "widget_type": "micro_pulse_carousel_widget" } }' ``` **Request the widget in Spanish** by adding the `Accept-Language` header and setting it to `es`. ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Accept-Language: es' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "widget_type": "micro_pulse_carousel_widget" } }' ``` ## PostMessage UI Events When certain events trigger in our UI, we send you a postMessage UI event. These events have the information you need to take action in your codebase in response to the event. It's your responsibility to add a listener to capture the properties of these triggered events and also handle what happens next. If integrating on mobile through a WebView, an alternative to standard postMessage UI events is required. See [Events in Mobile WebViews](#events-in-mobile-webviews) for more information. **WARNING** Don't use postMessage UI events for keeping data in sync between platforms. [Webhooks](/resources/webhooks) are a more reliable way of coordinating events between your servers and MX servers. PostMessage UI events from MX, as seen in the previous example, have the following properties: * The `mx` field that lets you filter out postMessage UI events coming from MX. * The `type` field that identifies what the event represents at a high level. * The `metadata` object field that has information related to the `type`. The following is an example integration that lets you listen to the events we send. ```js Example theme={null} function handleEvent(event) { if (event.data.mx) { // handle the mx post message using event.data.type and event.data.metadata. } } window.addEventListener('message', handleEvent) ``` ### Events in Mobile WebViews Because of the technical limitations of WebView-based widget implementations, an alternative to standard postMessages is required. MX has developed a URL-based updating mechanism to replace event messages that are available to other desktop implementations. You can capture this URL and use the information provided in them to build the necessary logic for coordinating application events. When requesting a widget URL using the SSO API or Platform API, you must include the `is_mobile_webview` field with a value of `true` in your request to access WebView event messages. If you don't want to handle these events, don't set the `is_mobile_webview` flag, or set it to `false`. For the Micro Insights Widget, this URL is delivered via a `window.location = "mx://pulse/micro-carousel/cta?metadata="` call within the iFrame. **DANGER** Not capturing this URL can cause the app to break. You must capture this URL, parse out the path and query string, then JSON-decode the metadata field. When decoded, the metadata will contain the `beat_guid`, `beat_template`, and `user_guid`. ### Application Events #### Widget Load This event triggers when the widget loads. ```json theme={null} { "type": "mx/load", "mx": true } ``` #### Widget Ping This event keeps the widget session alive. ```json theme={null} { "type": "mx/ping", "mx": true, "metadata": { "user_guid": "USR-123", "session_guid": "ANS-123" } } ``` ### Micro Insights Widget Events The Micro Insights Widget has two postMessage events. One postMessage event triggers when the end user clicks the **View all** CTA in the Micro Insights Widget's header. If you have the header enabled, you must add a listener for this postMessage that sends the user to the Insights Widget. This event will look like the following. ```json Example theme={null} { "type": "mx/pulse/micro-carousel/cta", "mx": true, "metadata": { "user_guid": "USR-abcd-1234" } } ``` Another event is triggered when the end user clicks the **Learn more** CTA. You must add a listener for this postMessage event that sends the user to the Insights Widget. In this postMessage event, the `metadata` includes a `beat_guid`. You'll use this GUID in your widget URL request for the Insights Widget so the specified insight shows at the top of the insights feed. See [Move Insight to Top of Feed](/products/experience/insights/integration-guides/integrate-micro-widget#move-insight-to-top-of-feed) for more info. This event will look like the following. ```json Example theme={null} { "type": "mx/pulse/micro-carousel/cta", "mx": true, "metadata": { "beat_guid": "BRT-2345-bcda", "beat_template": "MonthlySpendComparison", "user_guid": "USR-abcd-1234" } } ``` ## Widget Loader Configurations This section is for integrating a widget on desktop using the Widget Loader. It shows the [parameters](#widget-loader-parameters) you'll use to set things like the widget's height and width, [additional configurations](#additional-configurations) that let you set configurations for specific widgets, and also has the following sections to further help your integration: * [Create a Loading Message](#create-a-loading-message) * [Keeping a Session Alive and Logging Out](#keeping-a-session-alive-and-logging-out) * [Loading Multiple Widgets](#loading-multiple-widgets) * [Loading Widgets at Different Times](#loading-widgets-at-different-times) * [Master Widget Deep Linking](#master-widget-deep-linking) ### Widget Loader Parameters When you instantiate `MoneyDesktopWidgetLoader`, you must pass in an object with at least the required URL parameter, and any of the following optional parameters. | Parameter | Required? | Default Value | Description | | ---------- | --------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `autoload` | No | `true` | Determines if the widget loads automatically. See [Loading Widgets at Different Times](#loading-widgets-at-different-times). | | `config` | No | | This contains an object in which you can set configurations. Some of these configurations are for specific widgets. While setting configurations this way is supported, the most current way of setting these configurations is through the widget URL request. See [Config Parameter](#config-parameter) for more info. | | `height` | No | `600` | The widget's height, in pixels or a percentage. | | `id` | No | `'md-widget'` | Tells the widget loader what element to place the widget in. See [Loading Multiple Widgets](#loading-multiple-widgets). | | `width` | No | `'100%'` | The widget's width, in pixels or a percentage. | | `url` | Yes | | The widget's URL, received through an SSO API or Platform API request. | #### Config Parameter The `config` object, as shown in the following example, contains configurations options. ```html Example theme={null} var myWidget = new MoneyDesktopWidgetLoader({ url: getUrl(url), width: 450, height: 400, config: { micro_pulse_carousel: { ui_message_version: 4 } }, postMessageOrigin: "*" }); ``` You can set the following configuration options. | Configuration Option | Data Type | Description | | -------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `is_mobile_webview` | Boolean | Defaults to `false`. Renders the widget in a mobile WebView. Executes URL updates in place of the JavaScript event postMessages. | | `language` | String | **Deprecated**. See [Localize Insights Widgets](/products/experience/insights/integration-guides#localize-the-insights-widgets). | | `ui_message_version` | Integer | Use this to specify which version of postMessage UI events are triggered. All new implementations must include this option when getting any widget URL and must set it to version `4`. Prior versions are deprecated and supported only for existing integrations. | ### Create a Loading Message Any HTML placed inside of the widget placeholder element will be replaced once the widget iframe has loaded. This means you can use the placeholder element's inner HTML to display a loading message. Since this is just HTML, it can be text, images, or anything you want. The following example adds some loading text that will appear until the widget has loaded. ```html Example theme={null} My Web Page
Loading...
``` ### Keeping a Session Alive and Logging Out MX provides two important functions for the widget loader: ping and logout. The **ping** function resets the session timer, allowing you to keep the session open as long as needed. The default timeout period is 900 seconds, and ping can be used anywhere in that period to restart the timer. A custom timeout period can be set by contacting MX, but MX recommends using the ping method rather than setting a longer timeout. ```html theme={null} ``` The **logout** function ends the session and redirects to the session timeout URL defined in your client profile. If no URL is defined, there is no redirect. Contact MX if you wish to set a specific session timeout URL. ### Loading Multiple Widgets To load multiple widgets on a single page: 1. Define multiple placeholder elements, each with a unique CSS `id`. 2. In your JavaScript, create an instance of `MoneyDesktopWidgetLoader` for each widget. 3. Connect each loader instance to a placeholder element by setting the `id` property value as the CSS `id`. After the page has loaded, all widgets will load in their respective elements. Here’s an example of loading 3 separate widgets onto a single page. ```html Example theme={null} My Web Page
``` ### Loading Widgets at Different Times By default, widgets load automatically once the web page has loaded. If you'd like to load your widgets manually you can use the autoload option by setting autoload to false when instantiating `MoneyDesktopWidgetLoader`. When you're ready to load a widget, call the load method on the instance of `MoneyDesktopWidgetLoader` with the URL. Here’s an example of loading the Accounts Widget on page load, then loading the Transactions Widget when a button is selected. ```html Example theme={null} My Web Page
``` # Integrate the Mini Insights Widget Source: https://docs.mx.com/products/experience/insights/integration-guides/integrate-mini-widget This guide shows you how to integrate the Mini Insights Widget on a [website using an iFrame](#integrate-on-a-website-iframe), on a [website using the Widget Loader](#integrate-on-a-website-widget-loader), or on a [mobile app](#integrate-on-a-mobile-app). For information on widget behavior, reference the [Widget Overview](/products/experience/insights/widget-overviews/insights-widget). **INFO** Before you can integrate the widget, you must have worked with MX to enable your access to insights. For this guide, you'll either use the Platform API or SSO API. The API you use depends on what you have purchased and have enabled. If you have the Nexus API enabled, you'll use the SSO API. ## Integrate on a Website (iFrame) This shows how to integrate the widget on a website using an iFrame. #### Step 1 Create an iFrame. Make sure the width and height use the widget's [supported dimensions](/products/experience/insights/widget-overviews/insights-widget#supported-dimensions-1). ```html Example focus={1-5} theme={null} ``` #### Step 2 In the iFrame's `src`, you'll need to request a widget URL and specify `mini_pulse_carousel_widget` as the `widget_type` using the [Platform API](/api-reference/platform-api/reference/widgets) or [SSO API](/api-reference/sso/v3/reference/widget-urls/get-widget-with-config-options). The URL you'll receive is single-use and expires after 10 minutes. You must request a new URL every time the page is rendered. See [Example API Requests](#example-api-requests) for different configurations. ```html Example focus={1-5} theme={null} ``` #### Step 3 Optionally create listeners for these two application events: * [Widget Load](#widget-load) – triggered when the widget is loaded. * [Widget Ping](#widget-ping) – used to keep the widget session alive. See [Postmessage UI Events](#postmessage-ui-events) for more info. ```html Example focus={6-19} theme={null} ``` #### Step 4 Configure an event listener for the [Mini Insights Widget event](#mini-widget-event). See [Postmessage UI Events](#postmessage-ui-events) for more information. ```html Example focus={19-22} theme={null} ``` **SUCCESS** Congrats! You've integrated the Micro Insights Widget! ## Integrate on a Website (Widget Loader) This shows how to integrate the widget on a website using an iFrame. #### Step 1 Add the widget loader script to the page. Place this file before any other code related to the widgets. This custom script loads the widgets onto the page. You can load the widget loader from the MX production server or download and store it in your local environment. We update the widget loader when needed, so if you're caching it on your server, refresh your cached version monthly. ```html Example focus={4} theme={null} My Web Page
``` #### Step 2 Add a widget placeholder element. Our widget loader will use this placeholder element to embed an iframe containing the widget. The element must have an `id` of `md-widget`. ```html Example focus={14} theme={null} My Web Page
``` #### Step 3 Load the widget into the placeholder element. Create a new instance of the `MoneyDesktopWidgetLoader` class, which is defined in the widget loader script. When you instantiate `MoneyDesktopWidgetLoader`, you must pass in an object with at least the required URL parameter (see step 4), and possibly one or more [optional parameters](#widget-loader-parameters). The widget loader will wait until the page has been loaded, and then load the widget into the placeholder element. Make sure the widget uses its [supported dimensions](/products/experience/insights/widget-overviews/insights-widget#supported-dimensions-1). ```html Example focus={5-11} theme={null} My Web Page
``` #### Step 4 You'll need to request a widget URL through the Platform API or SSO API and set it in the URL parameter. The URL you'll receive is single-use and expires after 10 minutes. You must request a new URL every time the page is rendered. You can request a widget URL for the Insights Widget by specifying `mini_pulse_carousel_widget` as the `widget_type`, using the [Platform API](/api-reference/platform-api/reference/widgets) or [SSO API](/api-reference/sso/v3/reference/widget-urls/get-widget-with-config-options). ```html Example focus={7} theme={null} My Web Page
``` ## Integrate on a Mobile App To integrate the widget on a mobile app: 1. Request `mini_pulse_carousel_widget` as the `widget_type`, using the [Platform API](/api-reference/platform-api/reference/widgets) or [SSO API](/api-reference/sso/v3/reference/widget-urls/get-widget-with-config-options). The URL you'll receive is single-use and expires after 10 minutes. You must request a new URL every time the page is rendered. See [Example API Requests](#example-api-requests) for different configurations. 2. Load the URL received from the previous request into a WebView. 3. See [Events in Mobile WebViews](#events-in-mobile-webviews). 4. Capture and parse a URL for the widget load and widget ping [application events](#application-events). 5. Capture and parse a URL for when the end user interacts with the **View more** CTA inside the widget. You must add a listener for this postMessage UI event to know when to navigate the end user to the Insights Widget. See [Mini Insights Widget event](#mini-widget-event) for more information. **SUCCESS** Congrats! You've integrated the Mini Insights Widget! ## Move Insight to Top of Feed This guide shows you how to move an insight to the top of the feed in the Insights Widget. You'll want to use this if you're also using the Mini or Micro Insights Widget. This is so users can select **View More** above an insight in the Mini Insights Widget, which sends them to the full feed, then see that insight at the top. To request an Insights Widget with a specified insight displayed at the top: 1. Request the Insights Widget with the `insight_guid` configuration, as shown in the examples. Set the value for the `insight_guid` to the vale of the `beat_guid` you received from the Mini Insights Widget postmessage UI event. 2. The response from this Insights Widget request will contain the URL for an Insights Widget that has the specified insight at the top of the feed. ```shell SSO theme={null} curl -i -X POST https://int-sso.moneydesktop.com/{client_id}/users/{id}/urls.json \ -H 'Content-Type: application/vnd.moneydesktop.sso.v3+json' \ -H 'Accept: application/vnd.moneydesktop.sso.v3+json' \ -H 'MD-API-KEY: {api_key}' \ -d '{ "url": { "type": "pulse_widget", "insight_guid": "BET-123" } }' ``` ```shell Platform theme={null} curl -i -X POST 'https://int-api.mx.com/users/{user_id}/widget_urls' \ -u '{client_id}:{api_key}' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -d '{ "widget_url": { "widget_type": "pulse_widget", "insight_guid": "BET-123" } }' ``` ### Common Problems This section covers some common problems with loading a widget URL into a WebView. #### Minimum Size To embed our mobile widgets into a WebView, we require a device width of at least 320 pixels. Depending on the implementation of the WebView, smaller devices may not be provided the full width, leading to display issues. #### WKWebView vs. UIWebView (iOS) In apps that run in iOS 8 and later, MX only supports WKWebView. If you previously implemented UIWebView, update your implementation to use WKWebView. Apple recommends this. For more information, see Apple's developer documentation for [UIWebView](https://developer.apple.com/documentation/uikit/uiwebview) and [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview). #### Default Padding (iOS) iOS adds padding to its WebViews by default, which can cause problems. To fix this: 1. Select the WebView providing the widgets in your application and navigate to the size inspector. 2. Change the layout margins from "Default" to "Explicit". 3. Update the left and right margins to "0". 4. Ensure the Width is at least 320 pixels. #### Default Margin (iOS and Android) Whether using WebViews on Android or iOS, most browsers will have a default margin (set in the user agent stylesheet) on the body element when rendering the HTML page responsible for loading a widget. This margin is deducted from the total available width of the containing element, which will cause a problem. To fix this: 1. Determine the computed width available on the body element. The width available to the iframe can be confirmed by inspecting the iframe injected by MX and typing window\.innerWidth in the javascript console. The width available to the iframe must be at least 320 pixels. 2. Confirm the body and HTML elements have their padding and margin set to "0." #### Viewport (iOS and Android) For mobile widgets to render, the viewport must be set in a meta tag on the HTML page used to load the widget URL. The viewport is the size of the window through which a page is seen. It can be smaller or larger than the actual size of a page or device screen. On most mobile devices, the virtual viewport is larger than the actual screen size; web pages are rendered according to the viewport size, then shrunk down to the actual screen size. This helps when viewing pages that aren't optimized for mobile, but for pages that are optimized for mobile (like the mobile widgets), the viewport meta tag is used to guarantee that the page is rendered properly. Set a meta tag within the `` element as follows. ```html Example theme={null} ``` ## Example API Requests The following examples are for requesting a Mini Insights Widget URL in the Platform API. Request a widget to **embed on a website.** ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "widget_type": "mini_pulse_carousel_widget" } }' ``` Request a widget to **embed on a mobile app through a WebView.** ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "is_mobile_webview": true, "widget_type": "mini_pulse_carousel_widget" } }' ``` **Request the widget in Spanish** by adding the `Accept-Language` header and setting it to `es`. ```curl theme={null} curl -L -X POST 'https://int-api.mx.com/users/{user_guid}/widget_urls' \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.mx.api.v20231004+json' \ -H 'Accept-Language: es' \ -H 'Authorization: Basic BASE_64_ENCODING_OF{client_id:api_key}' \ --data '{ "widget_url": { "widget_type": "mini_pulse_carousel_widget" } }' ``` ## PostMessage UI Events When certain events trigger in our UI, we send you a postMessage UI event. These events have the information you need to take action in your codebase in response to the event. It's your responsibility to add a listener to capture the properties of these triggered events and also handle what happens next. In this example, it would be your responsibility to direct the user to the full insights feed. If integrating on mobile through a WebView, an alternative to standard postMessage UI events is required. See [Events in Mobile WebViews](#events-in-mobile-webviews) for more information. **WARNING** Don't use postMessage UI events for keeping data in sync between platforms. [Webhooks](/resources/webhooks) are a more reliable way of coordinating events between your servers and MX servers. PostMessage UI events from MX have the following properties: * The `mx` field that lets you filter out postMessage UI events coming from MX. * The `type` field that identifies what the event represents at a high level. * The `metadata` object field that has information related to the `type`. The following is an example integration that lets you listen to the events we send. ```js Example theme={null} function handleEvent(event) { if (event.data.mx) { // handle the mx post message using event.data.type and event.data.metadata. } } window.addEventListener('message', handleEvent) ``` ### Application Events #### Widget Load This event triggers when the widget loads. ```json theme={null} { "type": "mx/load", "mx": true } ``` #### Widget Ping This event keeps the widget session alive. ```json theme={null} { "type": "mx/ping", "mx": true, "metadata": { "user_guid": "USR-123", "session_guid": "ANS-123" } } ``` ### Mini Insights Widget Event **INFO** Insights were previously called beats. You’ll see field names and other values that still reference beats. A postMessage UI event is triggered when the end user interacts with the **View more** CTA inside the widget. You must add a listener for this postMessage UI event to know when to navigate the end user to the Insights Widget. ```json Example theme={null} { "type": "mx/pulse/carousel/cta", "mx": true, "metadata": { "beat_guid": "BRT-2345-bcda", "beat_template": "MonthlySpendComparison", "user_guid": "USR-abcd-1234" } } ``` ## Widget Loader Configurations This section is for integrating a widget on desktop using the Widget Loader. It shows the [parameters](#widget-loader-parameters) you'll use to set things like the widget's height and width, [additional configurations](#additional-configurations) that let you set configurations for specific widgets, and also has the following sections to further help your integration: * [Create a Loading Message](#create-a-loading-message) * [Keeping a Session Alive and Logging Out](#keeping-a-session-alive-and-logging-out) * [Loading Multiple Widgets](#loading-multiple-widgets) * [Loading Widgets at Different Times](#loading-widgets-at-different-times) * [Master Widget Deep Linking](#master-widget-deep-linking) ### Widget Loader Parameters When you instantiate MoneyDesktopWidgetLoader, you must pass in an object with at least the required URL parameter, and any of the following optional parameters. | Parameter | Required? | Default Value | Description | | ---------- | --------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `autoload` | No | `true` | Determines if the widget loads automatically. See [Loading Widgets at Different Times](#loading-widgets-at-different-times). | | `config` | No | | This contains an object in which you can set configurations. Some of these configurations are for specific widgets. While setting configurations this way is supported, the most current way of settings these configurations is through the widget URL request. See [Configuration Options](#configuration-options) for more info. | | `height` | No | `600` | The widget's height, in pixels or a percentage. | | `id` | No | `'md-widget'` | Tells the widget loader what element to place the widget in. See [Loading Multiple Widgets](#loading-multiple-widgets). | | `width` | No | `'100%'` | The widget's width, in pixels or a percentage. | | `url` | Yes | | The widget's URL, received through an SSO API or Platform API request. | #### Config Parameter The `config` object, as shown in the following example, contains configurations options. ```html Example theme={null} var myWidget = new MoneyDesktopWidgetLoader({ url: getUrl(url), width: 450, height: 400, config: { mini_pulse_carousel: { ui_message_version: 4 } }, postMessageOrigin: "*" }); ``` You can set the following configuration options. | Configuration Option | Data Type | Description | | --------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `insight_widget_filter_from_date` | Integer | Filters which insights can appear in your widget by date. Insights older than the set date won't appear. The date must be in Unix format. Example: `1686074427`. This option is only supported in the SSO API. | | `insight_widget_filter_templates` | Array | Filters which insights can appear in your widget by template name. Example: `['LargeTransaction', 'UnifiedDeposit']`. See the [Insights Library](/products/experience/insights/library) for all supported values. This option is only supported in the SSO API. | | `is_mobile_webview` | Boolean | Renders the widget in a mobile WebView. Executes URL updates in place of the JavaScript postMessage UI events. | | `language` | String | **Deprecated**. See [Localize Insights Widgets](/products/experience/insights/integration-guides#localize-the-insights-widgets). | | `ui_message_version` | Integer | Use this to specify which version of postMessage UI events are triggered. All new implementations must include this option when getting any widget URL and must set it to version `4`. Prior versions are deprecated and supported only for existing integrations. | ### Create a Loading Message Any HTML placed inside of the widget placeholder element will be replaced once the widget iframe has loaded. This means you can use the placeholder element's inner HTML to display a loading message. Since this is just HTML, it can be text, images, or anything you want. The following example adds some loading text that will appear until the widget has loaded. ```html Example theme={null} My Web Page
Loading...
``` ### Keeping a Session Alive and Logging Out MX provides two important functions for the widget loader: ping and logout. The **ping** function resets the session timer, allowing you to keep the session open as long as needed. The default timeout period is 900 seconds, and ping can be used anywhere in that period to restart the timer. A custom timeout period can be set by contacting MX, but MX recommends using the ping method rather than setting a longer timeout. ```html theme={null} ``` The **logout** function ends the session and redirects to the session timeout URL defined in your client profile. If no URL is defined, there is no redirect. Contact MX if you wish to set a specific session timeout URL. ### Loading Multiple Widgets To load multiple widgets on a single page: 1. Define multiple placeholder elements, each with a unique CSS `id`. 2. In your JavaScript, create an instance of `MoneyDesktopWidgetLoader` for each widget. 3. Connect each loader instance to a placeholder element by setting the `id` property value as the CSS `id`. After the page has loaded, all widgets will load in their respective elements. Here’s an example of loading 3 separate widgets onto a single page. ```html Example theme={null} My Web Page
``` ### Loading Widgets at Different Times By default, widgets load automatically once the web page has loaded. If you'd like to load your widgets manually you can use the autoload option by setting autoload to false when instantiating `MoneyDesktopWidgetLoader`. When you're ready to load a widget, call the load method on the instance of `MoneyDesktopWidgetLoader` with the URL. Here’s an example of loading the Accounts Widget on page load, then loading the Transactions Widget when a button is selected. ```html Example theme={null} My Web Page
``` ## (Optional) Filter Insights By default, the Mini Insights Widget displays up to 5 insight cards, which are the user's most recent insight cards that are mini-carousel enabled. To filter which insight cards can appear in your Mini Insights Widget, you must: 1. Request `mini_pulse_carousel_widget` as the `widget_type`. 2. Append a query string to the widget URL you receive from the previous step. Use the format shown in the [examples](#examples) to add every insight card template name you want to filter for and include in the Mini Insights Widget. For a list insights that are Mini Insights Widget compatible, see the [Insights Library](/products/experience/insights/library). Insight cards display in the order they were originally generated, and not in the order you appended their template names. While you must append a minimum of 1 insight card template name to change the default behavior, there is no maximum number of template names you can append. One insight card template can appear multiple times. Since the carousel displays a maximum of 5 insight cards, this may prevent additional cards from displaying. For example, if you filter the carousel to show the `AmericanFederalBankHolidays`, `FeeDetected`, and `SaveEnoughToLiveOn` templates, the `FeeDetected` template could display in the carousel's first three slides and the `AmericanFederalBankHolidays` could display in the carousel's last two slides. As a result, the `SaveEnoughToLiveOn` wouldn't display in the carousel. If the user doesn't have enough history for an insight card to populate from one of the appended templates, and you appended another card which can populate, the original card will not display. If none of the insight card templates you appended can populate, then two no state cards will appear in the carousel. ### Examples ```html Query theme={null} ?enabled_templates[]={insight_card_template_name}&enabled_templates[]={insight_card_template_name}&enabled_templates[]={insight_card_template_name}&enabled_templates[]={insight_card_template_name}&enabled_templates[]={insight_card_template_name} ``` ```html Full theme={null} https://int-widgets.moneydesktop.com/md/mini_pulse_carousel/ncAg2m36dv4dhb1n1wqghcqqk2Zbv3A8dznvlwvlw2d65bbwqwttpkpxhx2l53vmk4w8hqhvtlthsds4dwktjxbw01127q6blsrnxwlfsx01jc5xzA2vvvAyy3tlsdy06f8gqwt4bn3mm93k8bsxf5j5jfdd37qqdb8q8Arnj1kf9hwc3c64pmrslp36x9cmkphA5y7z5tcxztkzxvdyyckmpnjhh6c227xb7rfvspt6n90rp7Atb3dpytp2kjsjt1jjgdhjbjk91cfj4xAglbhq3034slvwbfA24ftwdkw97yygc4fhn7v9j56snx7zqw12jcqt88yt8jq4mfbc01q16mlqn5cn74rvkv0A/eyJ1aV9tZXNzYWdlX3ZlcnNpb24iOjQsInVpX21lc3NhZ2Vfd2Vidmlld191cmxfc2NoZW1lIjoibXgiLCJsb2NhbGUiOiJlbi1VUyJ9?enabled_templates[]=WeeklyNoSpendDays&enabled_templates[]=AmericanFederalBankHolidays&enabled_templates[]=TaxDeposit&enabled_templates[]=CashBack&enabled_templates[]=CheckDeposit ``` # Borrow Source: https://docs.mx.com/products/experience/insights/library/borrow ## Celebrate Credit Card Payoff Available in Mini Insights Widget This insight celebrates when a user pays off a credit card balance.
Image of the insight
This insight is triggered when an account balance changes to zero for the first time on a given day. The triggered insight must meet the following requirements to generate: * The account balance must change from a non-zero amount to 0. * The current resource must be a credit card account. * The credit card account must not be closed or hidden. * There must be no antecedent insight. * In the 56 days preceding the transaction date, there must be no dates with a historical balance of \$0. This is the default text for this insight. This is all customizable: * title: "Credit card paid off" * description: "On `{date}`, the balance on your `{localized_account_name}` account reached \$0.00. Great job paying your balance in full."
## Credit Utilization Available in Mini Insights Widget This insight notifies users that their credit utilization is high. There are two types of insights that can be generated: a warning and an alert.
Image of the insight
This insight is triggered weekly and must meet the following requirements to generate: * The user has one or more credit card accounts. We limit this insight to only using a maximum of 15 accounts. * A warning is generated when: * The user's balance is at least 20% or greater of their total credit limit. * The user has not had a previous warning or alert credit utilization beat for the current month. * An alert is generated when: * The user's balance is at least 30% or greater of their total credit limit. * The user has not had a previous alert credit utilization beat for the current month. This is the default text for this insight. This is all customizable: * title: * warning: "Credit card use is nearing 30%" * alert: "Credit card use is over 30%" * zero state: "No longer relevant" * description: * warning: * one: "Keeping credit utilization at 30% or less protects your credit score. You’ll reach that limit if you spend `{threshold_amount}` more on your credit card." * other: "Keeping credit utilization at 30% or less protects your credit score. You’ll reach that limit if you spend `{threshold_amount}` more on your `{count}` credit cards." * alert: * one: "Lowering credit utilization to 30% or less will protect your credit score. Consider paying `{threshold_amount}` toward your credit card." * other: "Lowering credit utilization to 30% or less will protect your credit score. Consider paying `{threshold_amount}` toward your `{count}` credit cards." * zero state: "Due to changes in the data, the information here is no longer relevant." * call to action: "Learn more"
## Debt Payment Reminder V3 Available in Mini Insights Widget Notification available This insight notifies users of an upcoming payment for a liability account.
Image of the insight
This insight is triggered when an account is updated and must meet the following requirements to generate: * The account isn't closed. * The account must have a positive balance. * The account supertype must be `LIABILITY`. * The `payment_due_at` date must be in the future. * No existing insights for the account and payment due date. * A payment hasn't been made to the account within the last 30 days. This is the default text for this insight. This is all customizable: * title: "Debt payment reminder" * description: * zero: "You typically have a payment to `{account_describer}` due on `{payment_due_at_date}`. Make sure you've made the full payment to avoid any late fees." * one: "You typically have a payment of `{payment_amount}` to `{account_describer}` due on `{payment_due_at_date}`. Make sure you've made the full payment to avoid any late fees."
## Debt Payoff Strategies Available in Mini Insights Widget This insight is meant to educate users who are carrying debt on multiple accounts, on two common strategies to paying off debt.
Image of the insight
This insight is triggered every 6 months and must meet the following requirements to generate: * A transaction must meet all of the attributes below in order for this insight to be generated: * A user has two or more active (in the last month) accounts that have the supertype of `LIABILITY`. (Active account = payment made to the account in the last 35 days) * This insight includes all accounts of this type except Mortgage accounts and Small Business account subtypes. * This insight only includes accounts that we have an Interest rate attached to it. This is the default text for this insight. This is all customizable: * title: "Debt payoff strategies" * description: "We see you're carrying debt on `{account_count}` accounts. Consider trying one of these common strategies to tackle debt." * call to action: "Learn more"
## Missing Interest Rate This insight asks users to share their interest rate so we can help them to have better money experiences.
Image of the insight
This insight triggers weekly and must meet the following requirements to generate: * The account's supertype must be `LIABILITY`. * The account's `interest_rate` field must not be set. * The account's `apr` field must not be set. Additional things to note: * If a user has multiple liability accounts without an interest rate we will only generate an insight for the first account and proceed to the rest in the next weeks. * An insight for a specific account can only be generated once every 3 months. This is the default text for this insight. This is all customizable: * title: * no interest rate: "Interest rate missing" * with interest rate: "Interest rate added" * description: * no interest rate: "The interest rate on your `{localized_account_name}` account is currently unknown. By providing it, you will help us make even more personalized insights related to this account." * with interest rate: "Thank you for updating the interest rate on your `{localized_account_name}` account. This will help us make even more precise and relevant insights in the future." * call to action: * no interest rate: "Add detail" * with interest rate: "View details"
## Monthly Credit Card Interest Summary Available in Mini Insights Widget This insight shows users how much they are spending on interest on their credit cards over the last 90 days.
Image of the insight
This insight is triggered monthly and must meet the following requirements to generate: * The user must have one or more credit cards. * The user must have been charged some amount in interest on these credit cards in the last 90 days. * There must be an interest charge in the last month. * A transaction is considered an interest charge when all the following attributes are true: * The transaction type must be `DEBIT`. * The transaction category must be `FINANCE CHARGE`. * The transaction must include "interest" or "finance charge" in the feed description; the case does not matter. * This insight must not already exist for the previous month. This is the default text for this insight. This is all customizable: * title: "Interest charges summary" * description: "From `{start_date}` to `{end_date}`, you have paid `{total}` in interest on your `{localized_account_name}`." * call to action: "Learn how to save"
## Monthly Debt To Income Comparison V2 Available in Mini Insights Widget This insight provides a comparison of income to debt spend for the previous four months.
Image of the insight
This insight is triggered monthly and the user must meet the following requirements to generate: * Have at least one checking, checking line of credit, or savings account. * Have transactions in their checking, checking line of credit, or savings account for the previous month. * Have transactions in their checking, checking line of credit, or savings account for at least two out of the four previous months. * Have at least one income transaction that is greater than \$0 for the previous month. * Have at least one debt transaction that is greater than \$0 for the previous month. This is the default text for this insight. This is all customizable: * title: "Debt vs. income" * description: * zero state: "Due to changes in the data, the information here is no longer relevant." * below: "In `{last_month}`, you spent `{income_to_debt_percentage}` of your income on debt. Great job keeping your monthly debt payments under 30%!" * above: "In `{last_month}`, you spent `{income_to_debt_percentage}` of your income on debt. Try to keep your monthly debt payments under 30%." * call to action: "View transactions"
## Payroll Advance This insight notifies users of a payroll advance transaction in one of their accounts. This insight is triggered when a transaction is created which meets the following requirements or a `PENDING` transaction which meets the defined requirements is updated to a status of `POSTED`. * A transaction must meet all of the attributes below in order for a Payroll Advance beat to be generated: * The transaction status must be `POSTED`. * The `is_payroll_advance` flag on the transaction is set to `true`. * This insight is limited to five occurrences each week. This is the default text for this insight. This is all customizable: * title: "Payroll advance" * description: * zero: "You took a payroll advance of `{transaction_amount}`." * one: "You took a payroll advance of `{transaction_amount}` from `{merchant_name}`." # Insights Library Source: https://docs.mx.com/products/experience/insights/library/index For each of the following insights we offer, you can find overviews, images, default copy, details on how the insight generates, and more. ## Available Insights | Insight Name | Mini Insights Widget Available | Micro Insights Widget Available | Notification Available | Transaction Inline Available | | :--------------------------------------------------------------------------------------------------------------------------------- | :----------------------------: | :-----------------------------: | :--------------------: | :--------------------------: | | [Account Discoverability Change](/products/experience/insights/library/spend#account-discoverability-change) | | ✓ | | | | [American Federal Bank Holidays](/products/experience/insights/library/plan#american-federal-bank-holidays) | ✓ | ✓ | | | | [American Upcoming Tax Deadline Alert](/products/experience/insights/library/plan#american-upcoming-tax-deadline-alert) | ✓ | ✓ | | | | [Bill Amount Not Standard](/products/experience/insights/library/spend#bill-amount-not-standard) | ✓ | ✓ | ✓ | ✓ | | [Canadian Federal Bank Holidays](/products/experience/insights/library/plan#canadian-federal-bank-holidays) | ✓ | ✓ | | | | [Canadian Upcoming Tax Deadline Alert](/products/experience/insights/library/plan#canadian-upcoming-tax-deadline-alert) | ✓ | ✓ | | | | [Cash Back](/products/experience/insights/library/spend#cash-back) | ✓ | ✓ | | | | [Category Budget](/products/experience/insights/library/spend#category-budget) | ✓ | ✓ | | | | [Category Spending V2](/products/experience/insights/library/spend#category-spending-v2) | ✓ | ✓ | ✓ | | | [Celebrate Credit Card Payoff](/products/experience/insights/library/borrow#celebrate-credit-card-payoff) | ✓ | ✓ | | | | [Charge Dispute Refund](/products/experience/insights/library/spend#charge-dispute-refund) | ✓ | ✓ | | | | [Check Deposit](/products/experience/insights/library/spend#check-deposit) | ✓ | ✓ | | | | [Cost of Living To Income](/products/experience/insights/library/spend#cost-of-living-to-income) | ✓ | ✓ | | | | [Credit Card Close To Limit](/products/experience/insights/library/spend#credit-card-close-to-limit) | ✓ | ✓ | ✓ | | | [Credit Utilization](/products/experience/insights/library/borrow#credit-utilization) | ✓ | ✓ | | | | [Debt Payment Reminder V3](/products/experience/insights/library/borrow#debt-payment-reminder-v3) | ✓ | ✓ | ✓ | | | [Debt Payoff Strategies](/products/experience/insights/library/borrow#debt-payoff-strategies) | ✓ | ✓ | | | | [Deposit 529](/products/experience/insights/library/save#deposit-529) | ✓ | ✓ | | | | [Designate Emergency Savings Account](/products/experience/insights/library/save#designate-emergency-savings-account) | | ✓ | | | | [Discovered Accounts](/products/experience/insights/library/spend#discovered-accounts) | ✓ | ✓ | ✓ | ✓ | | [Duplicate Payment V2](/products/experience/insights/library/spend#duplicate-payment-v2) | ✓ | ✓ | ✓ | ✓ | | [Emergency Fund Withdrawal](/products/experience/insights/library/save#emergency-fund-withdrawal) | ✓ | ✓ | | | | [Emergency Savings Milestone Reached](/products/experience/insights/library/save#emergency-savings-milestone-reached) | ✓ | ✓ | | | | [Fee Detected](/products/experience/insights/library/spend#fee-detected) | ✓ | ✓ | ✓ | ✓ | | [Government Deposit](/products/experience/insights/library/spend#government-deposit) | ✓ | ✓ | | | | [Green Gas Purchases Summary](/products/experience/insights/library/spend#green-gas-purchases-summary) | ✓ | ✓ | | | | [Green Statement Fee](/products/experience/insights/library/spend#green-statement-fee) | ✓ | ✓ | | | | [HSA Deposit](/products/experience/insights/library/save#hsa-deposit) | ✓ | ✓ | | | | [HSA Withdrawal](/products/experience/insights/library/save#hsa-withdrawal) | ✓ | ✓ | | | | [Introduce Insights](/products/experience/insights/library/plan#introduce-insights) | ✓ | ✓ | | | | [Large Deposit](/products/experience/insights/library/spend#large-deposit) | ✓ | ✓ | ✓ | | | [Large Transaction](/products/experience/insights/library/spend#large-transaction) | ✓ | ✓ | ✓ | ✓ | | [Low Account Balance](/products/experience/insights/library/spend#low-account-balance) | ✓ | ✓ | ✓ | | | [Merchant Budget](/products/experience/insights/library/spend#merchant-budget) | ✓ | ✓ | | | | [Merchant Credit Received](/products/experience/insights/library/spend#merchant-credit-received) | | ✓ | | | | [Microdeposits](/products/experience/insights/library/spend#microdeposits) | ✓ | ✓ | | | | [Missing Interest Rate](/products/experience/insights/library/borrow#missing-interest-rate) | | ✓ | | | | [Monthly Credit Card Interest Summary](/products/experience/insights/library/borrow#monthly-credit-card-interest-summary) | ✓ | ✓ | | | | [Monthly Debt To Income Comparison V2](/products/experience/insights/library/borrow#monthly-debt-to-income-comparison-v2) | ✓ | ✓ | | | | [Monthly Deposit Summary V2](/products/experience/insights/library/spend#monthly-deposit-summary-v2) | ✓ | ✓ | | | | [Monthly Emergency Fund Review](/products/experience/insights/library/save#monthly-emergency-fund-review) | ✓ | ✓ | | | | [Monthly Emergency Savings Reminder](/products/experience/insights/library/save#monthly-emergency-savings-reminder) | ✓ | ✓ | | | | [Monthly Non-Essential Category Summary V2](/products/experience/insights/library/spend#monthly-non-essential-category-summary-v2) | ✓ | ✓ | | | | [Monthly Obligations Status](/products/experience/insights/library/spend#monthly-obligations-status) | ✓ | ✓ | | | | [Monthly Savings To Income Comparison](/products/experience/insights/library/save#monthly-savings-to-income-comparison) | ✓ | ✓ | | | | [Monthly Spend Comparison V2](/products/experience/insights/library/spend#monthly-spend-comparison-v2) | ✓ | ✓ | ✓ | | | [Monthly Spend To Income Comparison V2](/products/experience/insights/library/spend#monthly-spend-to-income-comparison-v2) | ✓ | ✓ | ✓ | | | [Monthly Subscription Aggregate V2](/products/experience/insights/library/spend#monthly-subscription-aggregate-v2) | ✓ | ✓ | ✓ | | | [Monthly Top Merchant Spending V3](/products/experience/insights/library/spend#monthly-top-merchant-spending-v3) | ✓ | ✓ | ✓ | | | [Monthly Top Transacted Merchant](/products/experience/insights/library/spend#monthly-top-transacted-merchant) | | ✓ | | | | [New Merchant](/products/experience/insights/library/spend#new-merchant) | ✓ | ✓ | | | | [Payroll Advance](/products/experience/insights/library/borrow#payroll-advance) | | ✓ | | | | [Payroll Deposit](/products/experience/insights/library/spend#payroll-deposit) | ✓ | ✓ | | | | [Peer-To-Peer Categorization](/products/experience/insights/library/spend#peer-to-peer-categorization) | ✓ | ✓ | | | | [Quarterly Summary](/products/experience/insights/library/spend#quarterly-summary) | ✓ | ✓ | | | | [Replenish Savings](/products/experience/insights/library/save#replenish-savings) | ✓ | ✓ | | | | [Save An Extra \$100](/products/experience/insights/library/save#save-an-extra-100) | ✓ | ✓ | ✓ | | | [Save Enough To Live On](/products/experience/insights/library/save#save-enough-to-live-on) | ✓ | ✓ | | | | [Savings Account Balances Summary](/products/experience/insights/library/save#savings-account-balances-summary) | ✓ | ✓ | | | | [Savings Account Deposit](/products/experience/insights/library/save#savings-account-deposit) | ✓ | ✓ | | | | [Savings Milestone Emergency Fund](/products/experience/insights/library/save#savings-milestone-emergency-fund) | ✓ | ✓ | | | | [Savings Opportunity V2](/products/experience/insights/library/save#savings-opportunity-v2) | ✓ | ✓ | ✓ | | | [Set Up Direct Deposit](/products/experience/insights/library/spend#set-up-direct-deposit) | ✓ | ✓ | ✓ | | | [Spending Plan Category Spending](/products/experience/insights/library/spend#spending-plan-category-spending) | | ✓ | | | | [Spending Plan Created](/products/experience/insights/library/plan#spending-plan-created) | | ✓ | | | | [Spending Plan Talk With Someone](/products/experience/insights/library/spend#spending-plan-talk-with-someone) | | ✓ | | | | [Subscription Detected](/products/experience/insights/library/spend#subscription-detected) | ✓ | ✓ | | | | [Subscription Price Increase](/products/experience/insights/library/spend#subscription-price-increase) | ✓ | ✓ | | ✓ | | [Switch Direct Deposit](/products/experience/insights/library/spend#switch-direct-deposit) | ✓ | ✓ | ✓ | ✓ | | [Transparent Overdraft](/products/experience/insights/library/spend#transparent-overdraft) | ✓ | ✓ | | | | [Uncategorized Transactions V2](/products/experience/insights/library/spend#uncategorized-transactions-v2) | ✓ | ✓ | ✓ | | | [Unexpected Subscription Payment](/products/experience/insights/library/spend#unexpected-subscription-payment) | ✓ | ✓ | | | | [Unified Deposit](/products/experience/insights/library/spend#unified-deposit) | ✓ | ✓ | ✓ | | | [Unified Deposit Emergency Fund](/products/experience/insights/library/save#unified-deposit-emergency-fund) | | ✓ | | | | [Upcoming Bill](/products/experience/insights/library/spend#upcoming-bill) | ✓ | ✓ | ✓ | | | [Upcoming Subscription](/products/experience/insights/library/spend#upcoming-subscription) | ✓ | ✓ | | | | [User Feedback](/products/experience/insights/library/plan#user-feedback) | | ✓ | | | | [Weekend Spending Summary V2](/products/experience/insights/library/spend#weekend-spending-summary-v2) | ✓ | ✓ | ✓ | | | [Weekly New Merchants V2](/products/experience/insights/library/spend#weekly-new-merchants-v2) | ✓ | ✓ | ✓ | | | [Weekly No Spend Days](/products/experience/insights/library/spend#weekly-no-spend-days) | ✓ | ✓ | | | | [Weekly Small Purchases Summary](/products/experience/insights/library/spend#weekly-small-purchases-summary) | ✓ | ✓ | | | | [Weekly Spending Plan Summary](/products/experience/insights/library/spend#weekly-spending-plan-summary) | | ✓ | | | | [Withdrawal 529](/products/experience/insights/library/save#withdrawal-529) | | ✓ | | | **INFO** Insights that have transaction inline availability appear in the Transactions section of the [Mobile Banking Dashboard](/products/experience/mobile/features/dashboard#transactions). ## Deprecated Insights When we make a change to an insight that requires backend changes beyond what the insight was originally intended to do, we create a new version of the insight. An example of this is the `WeekendSpendingSummary` and `WeekendSpendingSummaryV2` insight templates. We suggest you use the latest version for each insight. The following insights have newer versions. | Deprecated Insight | New Insight | | :--------------------------------------------- | :---------------------------------------- | | Category Spending | Category Spending v2 | | Debt Payment Reminder | Debt Payment Reminder v2 | | Deposit Aggregate | Monthly Deposit Summary v2 | | Duplicate Payment | Duplicate Payment v2 | | Monthly Debt To Income Comparison | Monthly Debt To Income Comparison v2 | | Monthly Deposit Summary | Monthly Deposit Summary v2 | | Monthly Non Essential Category Summary | Monthly Non Essential Category Summary v2 | | Monthly Savings (Formerly Savings Opportunity) | Savings Account Balances Summary | | Monthly Savings Summary | Savings Account Balances Summary | | Monthly Spend Comparison | Monthly Spend Comparison v2 | | Monthly Spend To Income Comparison | Monthly Spend To Income Comparison v2 | | Monthly Subscription Aggregate | Monthly Subscription Aggregate v2 | | Monthly Top Merchant Spending | Monthly Top Merchant Spending v3 | | Monthly Top Merchant Spending v2 | Monthly Top Merchant Spending v3 | | Overdraft Warning | Transparent Overdraft | | Overdraft Warning v2 | Transparent Overdraft | | Quarterly Top Merchant Spending | Quarterly Summary | | Savings Opportunity | Savings Opportunity v2 | | Subscription Aggregate v2 | Monthly Subscription Aggregate | | Uncategorized Transactions | Uncategorized Transactions v2 | | Weekend Spending Summary | Weekend Spending Summary v2 | | Weekly New Merchants | Weekly New Merchants v2 | ## Dependencies The following insights depend on specific PFM Widgets to function as intended. Requires the [Goals Widget](/products/experience/pfm/widget-overviews/goals-widget): * [Emergency Fund Withdrawal](/products/experience/insights/library/save#emergency-fund-withdrawal) * The "emergency\_fund\_supported" scenario of [Savings Account Deposit](/products/experience/insights/library/save#savings-account-deposit) * [Unified Deposit Emergency Fund](/products/experience/insights/library/save#unified-deposit-emergency-fund) Requires the [Spending Plan Widget](/products/experience/pfm/legacy-widget-overviews/spending-plan): * [Spending Plan Category Spending](/products/experience/insights/library/spend#spending-plan-category-spending) * [Spending Plan Created](/products/experience/insights/library/plan#spending-plan-created) * [Spending Plan Talk With Someone](/products/experience/insights/library/spend#spending-plan-talk-with-someone) * [Weekly Spending Plan Summary](/products/experience/insights/library/spend#weekly-spending-plan-summary) # Plan Source: https://docs.mx.com/products/experience/insights/library/plan ## American Federal Bank Holidays Available in Mini Insights Widget This insight informs users about upcoming federal bank holidays. There's also a related insight for Canadian federal bank holidays.
Image of the insight
This insight is triggered quarterly. An upcoming holiday will generate a day before the holiday's date and the holiday needs to be between the current time and the next six months. These are the holidays used for this insight: * New Years Day * Fourth of July * Christmas Day * Martin Luther King Jr. Day * Columbus Day * Veteran's Day * Thanksgiving * Labor Day * President's Day * Memorial Day * Juneteenth This is the default text for this insight. This is all customizable: * title: "Federal bank holiday" * description: "In observance of `{holiday_translation_key}`, our offices may have closures on or around `{month_name}` `{day}`. Please check with your preferred location before visiting. Thank you for your understanding."
## American Upcoming Tax Deadline Alert Available in Mini Insights Widget This insight notifies users about important upcoming American tax deadlines. It warns users two months, one month, and one week before the upcoming personal tax deadline to protect users from any federal penalties for not submitting their taxes on time.
Image of the insight
This insight is triggered quarterly. This insight appears for every trigger date (two months, one month, and one week before the upcoming personal tax deadline). The timing of this insight is based on logic that factors in tax deadlines for U.S., depending on the user's location. This is the default text for this insight. This is all customizable: * title: "File your taxes!" * description for different scenarios: * two months until deadline: "You have 2 months until the United States' tax filing deadline, `{month_name}` `{day}`. Way to go if you've already filed!" * one month until deadline: "You have 1 month until the United States' tax filing deadline, `{month_name}` `{day}`. Way to go if you've already filed!" * one week deadline: "You have 1 week until the United States' tax filing deadline, `{month_name}` `{day}`. Remember to file for an extension if you need more time."
## Canadian Federal Bank Holidays Available in Mini Insights Widget This insight informs users about upcoming federal bank holidays. There's also a related insight for American federal bank holidays.
Image of the insight
This insight is triggered quarterly. An upcoming holiday will show up on the feed a day before the holiday's date and the holiday needs to be between the current time and the next six months. These are the holidays used for this insight: * New Years Day * Christmas Day * Thanksgiving * Good Friday * Canada Day * Remembrance Day * Boxing Day * Civic Holiday * Labour Day * Victoria Day * National Day for Truth and Reconciliation This is the default text for this insight. This is all customizable: * title: "Federal bank holiday" * description: "In observance of `{holiday_translation_key}`, our offices may have closures on or around `{month_name}` `{day}`. Please check with your preferred location before visiting. Thank you for your understanding."
## Canadian Upcoming Tax Deadline Alert Available in Mini Insights Widget This insight notifies users about important upcoming Canadian tax deadlines. It warns users two months, one month, and one week before the upcoming personal tax deadline to protect users from any federal penalties for not submitting their taxes on time.
Image of the insight
This insight is triggered quarterly. This insight appears for every trigger date (two months, one month, and one week before the upcoming personal tax deadline). The timing of this insight is based on logic that factors in tax deadlines for Canada, depending on the user's location. This is the default text for this insight. This is all customizable: * title: "File your taxes!" * description for different scenarios: * two months until deadline: "You have 2 months until Canada's tax filing deadline, `{month_name}` `{day}`. Way to go if you've already filed!" * one month until deadline: "You have 1 month until Canada's tax filing deadline, `{month_name}` `{day}`. Way to go if you've already filed!" * one week deadline: "You have 1 week until Canada's tax filing deadline, `{month_name}` `{day}`. Remember to file for an extension if you need more time."
## Introduce Insights Available in Mini Insights Widget Introduces new users to insights.
Image of the insight
This insight is generated and shown when new users first open an insights widget. This is the default text for this insight. This is all customizable: * title: "Introduce Insights" * description: "Insights is a new breed of banking service that puts your needs first." * call to action: "Learn more"
## Spending Plan Created This insight celebrates users that have created a [Spending Plan](/products/experience/pfm/legacy-widget-overviews/spending-plan) and continues to generate monthly.
Image of the insight
This insight requires the PFM or Mobile product. It's triggered when a Spending Plan is created and there's no antecedent for the same Spending Plan. This is the default text for this insight. This is all customizable: * First time a spending plan is created: * title: "Spending plan created" * description: "Keep going! Consistency will help you achieve your financial goals." * call to action: "Visit spending plan" * Monthly spending plan celebration: * initial: * title: "Monthly celebration" * description: "Keep going! Start using Spending Plan today to help you achieve your financial goals." * call to action: "Start Spending Plan" * initial with spending plan: * title: "Monthly celebration" * description: "Keep going! Consistency will help you achieve your financial goals." * call to action: "Visit Spending Plan" * initial with spending plan spent less: * title: "Monthly celebration" * description: "In `{last_month}`, you spent `{income_to_spending_difference}` less than what you made. Way to go! Consistency will help you achieve your financial goals." * call to action: "Visit Spending Plan" * recurring with spending plan: * title: "Monthly celebration" * description: "Keep going! Consistency will help you achieve your financial goals." * call to action: "Visit Spending Plan" * recurring with spending plan spent less: * title: "Monthly celebration" * description: "In `{last_month}`, you spent `{income_to_spending_difference}` less than what you made. Way to go! Consistency will help you achieve your financial goals." call to action: "Visit Spending Plan"
## User Feedback This insight lets users provide feedback on their insights. This insight triggers weekly and has the following requirements: * At least fifteen different undismissed insights have been created since the last user feedback insight was created. If a user feedback doesn't exist yet, then just fifteen undismissed insights need to be generated first. * The previous user feedback insight needs to be at least 14 days old if one exists. This is the default text for this insight. This is all customizable: * title: "Your feedback matters" * description: " * This Insights product is easy to use. (1–5 rating scale) * This Insights product meets my needs." (1–5 rating scale) * Do you have any other feedback? (open-ended response)" # Save Source: https://docs.mx.com/products/experience/insights/library/save ## Deposit 529 Available in Mini Insights Widget This insight celebrates contributions to a user's 529 savings account and reminds them that 529 is a great way to get tax-free investment growth and withdrawals for qualified education expenses.
Image of the insight
This insight will not generate if one of the following insights has already generated for the relevant transaction: * Tax Deposit * Government Deposit * Deposit529 * HSA Deposit * Payroll Deposit * Check Deposit * Large Deposit * Savings Account Deposit This insight triggers whenever a deposit is made into the 529 account and the following requirements are met: * Transaction type is `CREDIT`. * `account_type_id` must be `11` (Plan 529). * If 529 accounts are to be included from the other subtypes (accounts that don't have their `account_type_id` set at `11`), the account name must be filtered by the following expressions: * `\s529\s `OR * `Plan` AND `529` OR * `\(529\)` OR * `\b529-\d\b` * Account name can't contain `PREPAID`. * Deposit amount is greater than \$10. This is the default text for this insight. This is all customizable: * title: "529 deposit received" * description: * one: "On `{date}`, your `{account_name}` account received a `{amount}` deposit. That's great! Keep doing this every month to contribute `{projected_amount}` in a year." * other: "On `{date}`, your `{account_name}` account received a `{amount}` deposit. That's great! Keep doing this every month to contribute `{projected_amount}` in `{count}` years." * call to action: "View transaction"
## Withdrawal 529 This insight notifies users when that they have made a debit transaction on a 529 account.
Image of the insight
This insight triggers when a user withdraws from their 529 account and the following requirements are met: * Transaction type is `DEBIT`. * `account_type_id` must be `11` (Plan 529) * If 529 accounts are to be included from the other subtypes (accounts that don't have their `account_type_id` set at `11`), the account name must be filtered by the following expressions: * `\s529\s` OR * `Plan` AND `529` OR * `\(529\)` OR * `\b529-\d\b` * Account name can't contain `PREPAID`. * This insight is triggered if the withdrawal has happened within the year. This is the default text for this insight. This is all customizable: * title: "529 withdrawal detected" * description: "On `{date}`, you withdrew `{transaction_amount}` from your `{localized_account_name}`. Remember to spend that money on qualified educational expenses before the end of the year. Contact your plan provider with questions about how to properly use 529 funds." * call to action: "View transaction"
## Designate Emergency Savings Account This insight allows users to choose, change, or open their emergency savings account.
Image of the insight
This insight triggers: * Once a month if there is no emergency savings designated. * Every 6 months if an emergency savings is designated. If dismissed, we will not show this insight for 6 months, regardless if there is a designated savings account or not. This is the default text for this insight. This is all customizable: * not sampled: * title: "Be ready for a rainy day" * sampled: * choose account: * title: "Be ready for a rainy day" * description: "Would you like to choose an account for emergency savings? We can help you add to it!" * call to action: "Save" * open account: * title: "Be ready for a rainy day" * description: "Would you like to open an account for emergency savings? We can help you add to it!" * call to action: "Open Savings Account" * change account: * title: "Be ready for a rainy day" * description: "Your emergency savings are in `{localized_account_name}`. Would you like to choose a different account? If not, no action is needed." * call to action: "Save"
## Emergency Fund Withdrawal Available in Mini Insights Widget This insight notifies users when they've made a withdrawal from an emergency fund account in a potentially unqualified category, which may incur a fee. This insight requires the [Goals Widget](/products/experience/pfm/widget-overviews/goals-widget).
Image of the insight
This insight triggers when the following requirements are met: * The account associated with the transaction is associated to an active emergency fund goal. * The transaction is `DEBIT`. * The user has an active emergency fund goal. * The emergency fund goal isn't completed. * There are 5 or less Emergency Fund Withdrawal insights for this user within the current week. This is the default text for this insight. This is all customizable: * If transfers for funds are enabled: * title: "Emergency fund withdrawal" * description: "You've made a withdrawal from your emergency fund, and that's okay! Would you like to create a transfer to your fund to support its ongoing growth?" * call to action: "Create transfer" * supporting action: "View transaction" * If transfers for funds are disabled: * title: "Emergency fund withdrawal" * description: "You've made a withdrawal from your emergency fund, and that's okay! When you can, we suggest transferring some money back to your fund to support its ongoing growth." * call to action: "View my emergency savings" * supporting action: "View transaction" * Zero state: * title: "Emergency fund withdrawal" * description: "Due to changes in the data, the information here is no longer relevant."
## Unified Deposit Emergency Fund This insight notifies users who have created an Emergency Fund goal within the [Goals Widget](/products/experience/pfm/widget-overviews/goals-widget) when there is a deposit made to their account. It is available for the following categories: * Tax deposit * Government deposit * Payroll deposit * Check deposit * Large deposit This insight will exist in one of the above states, depending on the underlying transaction. This is a sampled insight, so it will reflect changes in the underlying transactions. If the underlying transaction changes such that it no longer matches any of the above-listed criteria, it will revert to a "zero state" as further described below.
Image of the insight
This insight will only generate if a user has created an Emergency Fund savings goal within the Goals Widget. This insight triggers when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * A transaction must meet all of the following conditions below to trigger this insight: * The transaction status must be `POSTED`. * The transaction type must be `CREDIT`. * The transaction must be held in an account with type `CHECKING` or `SAVINGS`. In addition, a transaction must match any one of the following set of criteria (in order of preference): * To match the Tax Deposit criteria: * The transaction must be have a top-level category of `TAXES`. * To match the Government Deposit criteria: * The transaction classifications must include `is_government_deposit`. * If there's a value set for the threshold: * The deposit amount must be equal to or above the threshold value. * If there isn't a value set for the threshold: * The deposit amount must be equal to or above the default threshold value of \$500. * To match the Payroll Deposit criteria: * The transaction must be have a category of `PAYROLL`. * To match the Check Deposit criteria: * The transaction must be in the INCOME category. * The transaction must include "check deposit" or "mobile deposit" in the feed description (the case of the feed description text does not matter). * To match the Large Deposit criteria: * The transaction must have an amount greater or equal to a dynamically adjusted threshold (client-configurable default: \$500) * The amount threshold is adjusted dynamically based on the amount of the most recent Unified Deposit Emergency Fund insight within the damping period, but ignoring insights having amounts below the default threshold: ``` # exponential decay lambda = - damping_decay_factor/damping_period threshold = (last_beat_amount - default_threshold) * Math.exp(lambda * days_since_last_beat) + default_threshold damping_decay_factor = 5.0; default_threshold = 500; damping_period = 30 ``` * A user is limited to receiving up to 5 Unified Deposit insights per day or up to 15 Unified Deposit insights per week. This is the default text for this insight. This is all customizable: * check deposit: * title: "Check deposit" * description: * zero: "On `{transaction_date}`, a `{transaction_amount}` check deposit was received in your `{localized_account_name}` account. This could be a great time to **start an emergency fund** to be prepared and protect yourself from the unexpected." * one: "On `{transaction_date}`, a `{transaction_amount}` check deposit was received in your `{localized_account_name}` account. This could be a great time to **add to your emergency fund** to be prepared and protect yourself from the unexpected. Would you like to transfer funds to your savings?" * other: "On `{transaction_date}`, a `{transaction_amount}` check deposit was received in your `{localized_account_name}` account. This could be a great time to **add to your emergency fund** to be prepared and protect yourself from the unexpected." * call to action: * zero: "Start saving for emergencies" * one: "Transfer funds" * other: "View my emergency savings" * supporting action: "View deposit" * government deposit: * title: "Government deposit received" * description: * zero: "On `{transaction_date}`, a `{transaction_amount}` government deposit was received in your `{localized_account_name}` account. This could be a great time to **start an emergency fund** to be prepared and protect yourself from the unexpected." * one: "On `{transaction_date}`, a `{transaction_amount}` government deposit was received in your `{localized_account_name}` account. This could be a great time to **add to your emergency fund** to be prepared and protect yourself from the unexpected. Would you like to transfer funds to your savings?" * other: "On `{transaction_date}`, a `{transaction_amount}`government deposit was received in your `{localized_account_name}` account. This could be a great time to **add to your emergency fund** to be prepared and protect yourself from the unexpected." * call to action: * zero: "Start saving for emergencies" * one: "Transfer funds" * other: "View my emergency savings" * supporting action: "View deposit" * large deposit: * title: "`{transaction_amount}` deposit received" * description: * zero: "On `{transaction_date}`, a deposit was received in your `{localized_account_name}` account. This could be a great time to **start an emergency fund** to be prepared and protect yourself from the unexpected." * one: "On `{transaction_date}`, a `{transaction_amount}` deposit was received in your `{localized_account_name}` account. This could be a great time to **add to your emergency fund** to be prepared and protect yourself from the unexpected. Would you like to transfer funds to your savings?" * other: "On `{transaction_date}`, a `{transaction_amount}` deposit was received in your `{localized_account_name}` account. This could be a great time to **add to your emergency fund** to be prepared and protect yourself from the unexpected." * call to action: * zero: "Start saving for emergencies" * one: "Transfer funds" * other: "View my emergency savings" * supporting action: "View deposit" * payroll deposit: * title: "Payroll deposited" * description: * zero: "On `{transaction_date}`, a `{transaction_amount}` payroll deposit was received in your `{localized_account_name}` account. This could be a great time to **start an emergency fund** to be prepared and protect yourself from the unexpected." * one: "On `{transaction_date}`, a `{transaction_amount}` payroll deposit was received in your `{localized_account_name}` account. This could be a great time to **add to your emergency fund** to be prepared and protect yourself from the unexpected. Would you like to transfer funds to your savings?" * other: "On `{transaction_date}`, a `{transaction_amount}` payroll deposit was received in your `{localized_account_name}` account." * call to action: * zero: "Start saving for emergencies" * one: "Transfer funds" * other: "View my emergency savings" * supporting action: "View deposit" * tax deposit: * title: "Tax deposit" * description: * zero: "On `{transaction_date}`, a `{transaction_amount}` tax deposit was received in your `{localized_account_name}` account. This could be a great time to **start an emergency fund** to be prepared and protect yourself from the unexpected." * one: "On `{transaction_date}`, a `{transaction_amount}` tax deposit was received in your `{localized_account_name}` account. This could be a great time to **add to your emergency fund** to be prepared and protect yourself from the unexpected. Would you like to transfer funds to your savings?" * other: "On `{transaction_date}`, a `{transaction_amount}` tax deposit was received in your `{localized_account_name}` account. This could be a great time to **add to your emergency fund** to be prepared and protect yourself from the unexpected." * call to action: * zero: "Start saving for emergencies" * one: "Transfer funds" * other: "View my emergency savings" * supporting action: "View deposit" * zero state: * title: "Deposit received" * description: "A deposit was previously received, but because of changes no further information is available."
## Emergency Savings Milestone Reached Available in Mini Insights Widget This insight congratulates users as they pass milestones with their emergency savings balance.
Image of the insight
This insight triggers whenever any of the following occur: * A user's total savings balance goes from less than `$100`, to greater than or equal to `$100` * A user's total savings balance goes from less than `$500`, to greater than or equal to `$500` * A user's total savings balance goes from less than `$1,000`, to greater than or equal to `$1,000` This is the default text for this insight. This is all customizable: * title: "Savings milestone reached" * description: * At 100: "On `{date}`, you passed \$100 in total savings. Keep up the good work!" * At 500: "On `{date}`, you passed \$500 in total savings. You’re more than halfway there. Great job!" * At 1000: "On `{date}`, you passed \$1,000 in total savings! You now have a good amount of money saved for unexpected expenses. Way to go!"
## Savings Milestone Emergency Fund Available in Mini Insights Widget This insight congratulates the user when they cross a milestone in their progress toward their emergency savings goal.
Image of the insight
This insight will only generate if a user has created an Emergency Fund savings goal within the Goals Widget. This insight is triggered when a goal meets the following requirements: * The user has an emergency fund. * The emergency fund goal is changed and crosses a threshold. * The previous goal state must be below a threshold. * The current goal state must be above a threshold. * The thresholds are: * 25% * 50% * 75% * 100% This is the default text for this insight. This is all customizable: * not completed * title: "Savings milestone reached!" * description: "On `{date}`, you saved `{amount}` in your `{localized_account_name}` account and you’ve successfully reached `{crossed_threshold}` of your savings goal. Keep up the good work!" * call to action: "View my emergency savings" * completed * title: "Savings milestone reached!" * description: "On `{date}`, you saved `{amount}` in your `{localized_account_name}` account and achieved your savings goal! You've now saved enough for unexpected emergencies. Way to go!" * call to action: "View my emergency savings"
## Monthly Emergency Fund Review Available in Mini Insights Widget This insight shows the user a monthly summary of their emergency goal progress.
Image of the insight
This insight is triggered once per month after users start saving for a goal and must meet the following requirements to generate: * The user has an active emergency fund goal, which is defined as: * `goal_type == SAVE_AMOUNT` * `track_type == SAVINGS_TRACK` * `meta_type == EMERGENCY_FUND` * The insight can't already exist for the previous month. This is the default text for this insight. This is all customizable: * No data: * title: "No longer relevant" * description: "Due to changes in the data, the spending information here is no longer relevant." * Non positive progress and transfer are enabled: * title: "Monthly savings progress review" * description: "Even a small deposit every month can empower you navigate through life's uncertainties with confidence. Would you like to create a transfer to continue building your financial safety net?" * call to action: "Create transfer" * supporting action: "View my emergency savings" * Non positive progress and transfers are disabled: * title: "Monthly savings progress review" * description: "Even a small deposit every month can empower you navigate through life's uncertainties with confidence. We encourage you to automate your transfers to help you achieve your goal." * call to action: "View my emergency savings" * Positive progress: * title: "Monthly savings progress review" * description: "Building a financial safety net will empower you to navigate through life’s uncertainties with confidence." * call to action: "View my emergency savings" * Completed goal: * title: "Monthly savings progress review" * description: "Good job! You’ve built a financial safety net and now have a plan for unexpected emergencies! Would you like to take your savings to the next level and create a new savings goal?" * call to action: "Create new goal" * supporting action: "View my emergency savings"
## Monthly Emergency Savings Reminder Available in Mini Insights Widget This insight reminds users to move money into their emergency savings account.
Image of the insight
This insight only generates once a month after all three milestones are achieved and these requirements are met: * User does not have an Emergency Savings Account GUID set (via the Designate Emergency Savings Account insight). * Savings account has a balance lower than \$1,000. This is the default text for this insight. This is all customizable: * Start saving first goal: * title: "Build emergency savings" * description: "It’s crucial to be able to cover large, unexpected expenses. If you saved `{contribution_needed_to_reach_goal}` per week, you’d have \$100 saved within 1 month." * call to action: "View more" * Amount remaining to reach first goal: * title: "Build emergency savings" * description: "It’s crucial to be able to cover large, unexpected expenses. You are so close to completing step one! Only `{amount_remaining_to_reach_goal}` more to go to reach \$100 saved." * call to action: "View more" * Start saving second goal: * title: "Build emergency savings" * description: "It’s crucial to be able to cover large, unexpected expenses. If you saved `{contribution_needed_to_reach_goal}` per month, you’d have \$500 saved within 3 months." * call to action: "View more" * Amount remaining to reach second goal: * title: "Build emergency savings" * description: "It’s crucial to be able to cover large, unexpected expenses. You are so close to completing step two! Only `{amount_remaining_to_reach_goal}` more to go to reach \$500 saved." * call to action: "View more" * Start saving third goal: * title: "Build emergency savings" * description: "It’s crucial to be able to cover large, unexpected expenses. If you saved `{contribution_needed_to_reach_goal}` per month, you’d have \$1,000 saved within 3 months." * call to action: "View more" * Amount remaining to reach third goal: * title: "Build emergency savings" * description: "It’s crucial to be able to cover large, unexpected expenses. You are so close to the finish line! Only `{amount_remaining_to_reach_goal}` per month more to go to reach \$1,000 saved." * call to action: "View more"
## HSA Deposit Available in Mini Insights Widget This insight alerts users who already have an HSA account how much money has been deposited.
Image of the insight
This insight will not generate if one of the following insights has already generated for the relevant transaction: * Tax Deposit * Government Deposit * Deposit529 * HSA Deposit * Payroll Deposit * Check Deposit * Large Deposit * Savings Account Deposit This insight triggers when an HSA deposit is credited to a user's account and the following requirements are met: * The account associated with the transaction must either have the subtype `HSA`, `HSA_CHECKING`, `HSA_SAVINGS`, or have "HSA", "Health Saving" or "Health Checking" in its name. * The transaction must be `CREDIT`. * The transaction must not be in the `DIVIDEND_AND_CAP_GAINS`, or `INTEREST_INCOME` categories. * The transaction must be equal to or greater than the `HSA_Deposit_Threshold` on the CIP (the default value is \$10). * The transaction must be the first daily deposit in its account. This is the default text for this insight. This is all customizable: * title: "HSA Deposit" * description: * zero: "Due to changes in the data, the information here is no longer relevant." * one: "On `{date}`, your `{localized_account_name}` account received a `{summed_deposit}` deposit. That's great! Keep doing this every month to contribute `{annual_projection}` in 12 months." * other: "On `{date}`, your `{localized_account_name}` account received `{count}` deposits for a total of `{summed_deposit}`. That's great! Keep doing this every month to contribute `{annual_projection}` in 12 months." * call to action: * zero: N/A * one: "View transaction" * other: "View transactions"
## HSA Withdrawal Available in Mini Insights Widget This insight alerts users who already have an HSA account how much money has been withdrawn.
Image of the insight
This insight triggers when money is withdrawn from a user's HSA account and the following requirements are met: * Transaction type must be `Debit`. * Consider accounts with subtype: `HSA` or `HSA Savings` or `HSA Checking`. * `ELSE` consider accounts with account name pattern: `HSA|(Health Savin)|(Health Check)`. * Insight should be triggered if the category name isn't `Dentist`, `Doctor`, `Pharmacy` OR `top_level_category_name` is `Investment`. This is the default text for this insight. This is all customizable: * title: "HSA Withdrawal" * description: "On `{date}` you withdrew `{transaction_amount}` from your `{localized_account_name}`. This is a friendly reminder that HSA funds can be used only for qualified medical expenses. Contact your account provider with any questions." * call to action: "View transaction"
## Monthly Savings To Income Comparison Available in Mini Insights Widget This insight informs users how much money they have saved compared to how much money they have earned from month to month.
Image of the insight
This insight triggers monthly and must meet the following requirements: * Savings deposits into the `Savings` account type are calculated for this insight. * Income calculated for this insight comes from the top level category of `Income`. Any transaction with a category that is a child of `Income` is an income transaction and will not be considered income. This is the default text for this insight. This is all customizable: * title: * zero state: "Savings vs. income" * zero savings: "Savings vs. income" * lower savings: "Savings vs. income" * higher savings: "Savings vs. income" * description: * zero state: "Due to changes in the data, the information here is no longer relevant." * zero savings: "Although you weren't able to add to your savings in `{last_month}`, if you deposit `{recommended_savings_percentage}` of your income to savings next month, that's `{recommended_savings}`. Every little bit counts!" * lower savings: "In `{last_month}`, you deposited `{savings}` to savings, which is `{savings_to_income_percentage}` of your income. Nice work! See if you can bump it up next month by depositing `{recommended_savings}`, or `{recommended_savings_percentage}` of your income." * higher savings: "In `{last_month}`, you deposited `{savings}` to savings, which is `{savings_to_income_percentage}` of your income. Excellent work! Keep it up next month to continue your strong saving habit. * call to action: "View more"
## Replenish Savings Available in Mini Insights Widget This insight prompts users, one week after they withdraw from their savings account, to replenish some of the amount withdrawn.
Image of the insight
This is insight is triggered one week after the initial transaction was withdrawn, and the same amount or more has not been added back to the account, and the following requirements are met: * Account Type = `Savings`. * Transaction Type = `Debit`. * Activated once a withdrawal occurs then after 7 days from that withdrawal. If more than one withdrawal occurs during that period, then the total amount withdrawn is considered. * Only triggered if the withdrawn amount is not replenished after a 7 day period. This is the default text for this insight. This is all customizable: * title: * one account one transaction: "Savings withdrawal" * one account multiple transactions: "Savings withdrawal" * multiple accounts: "Savings withdrawal" * description: * one account one transaction: "On `{date}`, you withdrew `{total_amount}` from your `{account_name}` account. That's what savings is for! Are you ready to replenish some of it now?" * one account multiple transactions: "Last week, you withdrew `{transactions_count}` times from your `{account_name}` account, for a total of `{total_amount}`. That’s what savings are for! Are you ready to replenish some of it now?" * multiple accounts: "Last week, you withdrew `{transactions_count}` times from `{accounts_count}` of your savings accounts, for a total of `{total_amount}`. That’s what savings are for! Are you ready to replenish some of it now?" * call to action: * one account one transaction: "Create transfer" * one account multiple transactions: "Create transfer" * multiple accounts: "Create transfer" * supporting action: * one account one transaction: "View transactions" * one account multiple transactions: "View transactions" * multiple accounts: "View transactions"
## Save An Extra \$100 Available in Mini Insights Widget Notification available This insight suggests that users save \$100 on payday. Planned expenses that are expected to occur over the next two days (time frame between current date and payday) will be accounted for when estimating the remaining balance. Planned expenses include scheduled payments for cash accounts set to occur over the next two days. Any recurring transactions not already associated with scheduled payments will also be included, if they are expected to recurr in the next two days.
Image of the insight
This insight is triggered when a transaction is created with the "paycheck" category for a user in one of their cash accounts and must meet the following requirements to generate: * The user has one of the following: a checking, savings, or cash account. * The user has at least \$200 total balance remaining across their applicable accounts on payday. * The insight must generate 2 days before upcoming payday. This is the default text for this insight. This is all customizable: * title: "Save an extra \$100" * description: "Based on your spending rate, you'll be able to save an extra \$100 on payday!" * call to action: "Make A Transfer" * supporting action: "Learn more"
## Save Enough To Live On Available in Mini Insights Widget This insight encourages users to have emergency savings beyond an initial \$1000. It suggests how much users need to save in order to cover one, two, or three months of their expenses.
Image of the insight
This insight is triggered quarterly and uses the following calculations: * `total_balance` = `Savings` + `Checking` accounts balances. * Calculate `ninety_day_spend`. * `average_daily_spend` = `ninety_day_spend` / 90. * Days to live on = `total_balance` / `average_daily_spend`. * Spend average is calculated based on the 90 days prior to the day the insight is created. * Available funds is based on the savings/checking balances as they were on the day the insight was created. This is the default text for this insight. This is all customizable: * title: * sampled: "`{duration}`" * zero state: "No longer relevant" * description: * sampled: "As of `{date}`, this is your ability to cover expenses if you lost your income and average spending continued." * zero state: "Due to changes in the data, the information here is no longer relevant." * call to action: * sampled: "View details" * zero state: N/A
## Savings Account Balances Summary Available in Mini Insights Widget This insight summarizes a user's savings account balances and shows how much they saved in the previous months.
Image of the insight
This insight is triggered monthly and must meet the following requirements to generate: * The user must have at least 1 savings account. * There must be enough transaction data to calculate the amount of savings the user had for the previous two months. * The insight cannot already exist for the previous month. This is the default text for this insight. This is all customizable: * title: "Savings account balances summary" * description: * not saved: "It looks like you were not able to add to your savings in `{date}`. It's tough to save money some months, but you can get back on track this month! Review where you saved in previous months." * saved higher: "In `{date}`, you saved `{previous_month_amount_saved}`. That is `{previous_month_difference}` more than you saved in `{previous_month}` and brings your total savings balance to `{current_balance}`. Keep it up!" * saved lower: "In `{date}`, you saved `{previous_month_amount_saved}`. That is `{previous_month_difference}` less than you saved in `{previous_month}` but still brings your total savings balance to `{current_balance}`. Keep it up!" * saved same: "In `{date}`, you saved `{previous_month_amount_saved}`, the same amount you saved in `{previous_month}`. This brings your total savings balance to `{current_balance}`. Keep it up!" * call to action: "View more"
## Savings Account Deposit Available in Mini Insights Widget This insight praises users when they save money and lets them know that a little savings can make a big difference. This insight celebrates users when they save. If the Goals Widget is active, this insight encourages users to setup an emergency fund or continue contributing to their emergency fund.
Image of the insight
This insight will not generate if one of the following insights has already generated for the relevant transaction: * Tax Deposit * Government Deposit * Deposit529 * HSA Deposit * Payroll Deposit * Check Deposit * Large Deposit * Savings Account Deposit This insight is triggered when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * The transaction status must be `POSTED`. * The transaction must have a category of `TRANSFER`. * The transaction must be a credit. * The transaction must be in a savings account. * The transaction must not be a micro-deposit. * The transaction must not originate from a savings account. * This insight hasn't generated more than 5 times (this limit is configurable). This is the default text for this insight. This is all customizable: * title: * with projected amount: "Savings deposit received" * without projected amount: "Savings deposit received" * emergency fund supported: "Savings deposit received" * emergency fund created: "Savings deposit received" * emergency fund deposited: "Emergency savings deposit received" * description: * with projected amount: "You deposited `{deposit_amount}` in your `{localized_account_name}` account. Way to go! If you did this every month, you would save `{projected_savings_amount}` in 12 months. * without projected amount: "You deposited `{deposit_amount}` in your `{localized_account_name}` account. Way to go!" * emergency fund supported: "You deposited `{deposit_amount}` in your `{localized_account_name}` account. Way to go! If you haven't already, start an emergency fund to be prepared and protect yourself from the unexpected." * emergency fund created: "You deposited `{deposit_amount}` in your `{localized_account_name}` account. Way to go! To continue building a financial safety net, remember to contribute to your emergency savings as well." * emergency fund deposited: "You deposited `{deposit_amount}` in your `{localized_account_name}` account. Way to go! You're building a financial safety net that will empower you to navigate through life's uncertainties with confidence." * call to action: * with projected amount: "View deposit" * without projected amount: "View deposit" * emergency fund supported: "Start saving for emergencies" * emergency fund created: "View my emergency savings" * emergency fund deposited: "View my emergency savings" * supporting action: * with projected amount: N/A * without projected amount: N/A * mergency fund supported: "View deposit" * emergency fund created: "View deposit" * emergency fund deposited: "View deposit"
## Savings Opportunity V2 Available in Mini Insights Widget Notification available This insight tests a user's projected cash position on a monthly basis and notifies the user when extra cash may be available for savings.
Image of the insight
This insight triggers weekly and must meet the following requirements to generate: * The user has one or more checking accounts. * Account balance data is available for one or more checking accounts as of the day before the insight is generated and for the same date in the prior month. * There hasn't been a savings deposit/transfer within `savings_deposit_lookback_days` in the client insight profile. That value defaults to 30 days but is customizable at the client level. This excludes interest income. * No previous Savings Opportunity insight has been created within the "cooldown period", which is determined by `savings_opportunity_cooldown_days` in the Client Insight Profile. That value defaults to 14 days but is customizable at the client level. * There is spending transaction history for each of the previous 3 months. * The amount available for saving is positive. This is the default text for this insight. This is all customizable: * title: "Safe to save" * description: * savings absent: "Good news! We noticed you had `{suggested_savings_amount}` extra dollars in your `{primary_checking_account}` account that can be transferred into a savings account. Would you like to open a savings account?" * savings absent no minimum checking account balance: "Good news! We noticed you had `{suggested_savings_amount}` extra dollars in your `{primary_checking_account}` account that can be transferred into a savings account. Let's get started." * specific: "Good news! We noticed you had `{suggested_savings_amount}` extra dollars in your `{primary_checking_account}` account that can be transferred into a savings account. Would you like to create this transfer?" * specific no minimum checking account balance: "Good news! We noticed you had `{suggested_savings_amount}` extra dollars in your `{primary_checking_account}` account that can be transferred into a savings account. Let's get started." * generic: "Good news! We noticed you had `{suggested_savings_amount}` extra dollars in your `{primary_checking_account}` account that can be transferred into a savings account. Would you like to create this transfer?" * generic no minimum checking account balance: "Good news! We noticed you had `{suggested_savings_amount}` extra dollars in your `{primary_checking_account}` account that can be transferred into a savings account. Let's get started." * zero state: "Due to changes in the data, the savings information here is no longer relevant." * call to action: * savings absent: "Open savings account" * savings absent no minimum checking account balance: "Get started" * specific: "Transfer funds" * specific no minimum checking account balance: "Get started" * generic: "Transfer funds" * generic no minimum checking account balance: "Get started" * zero state: N/A
# Spend Source: https://docs.mx.com/products/experience/insights/library/spend ## Upcoming Bill Available in Mini Insights Widget Notification available This insight alerts a user that in 3 days they have a bill payment due that is not a credit card and is not a subscription.
Image of the insight
This insight triggers when a user's scheduled payment(s) is created/updated and meets the following requirements: * This insight must not already exist for the scheduled payment. * The scheduled payment `occurs_on` date must be in the future. * The scheduled payment must be for a bill. * The scheduled payment must not be from the same merchant, on the same day, and for the same amount. This is the default text for this insight. This is all customizable: * title: "Projected bill payment" * description: "We think your `{merchant_name}` bill will be `{amount}`, due around `{date}`. This is based on trends and past transactions." * call to action: "View bill history"
## Bill Amount Not Standard Available in Mini Insights Widget Notification available This insight notifies users of a bill payment that's higher or lower than usual. The bars in the graph are dynamic and can contain 3 – 6 bars.
Image of the insight
This insight is triggered when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * For a transaction to be considered a bill transaction, it must meet all of the following requirements: * It must have a status of `POSTED`. * It must be a `DEBIT` transaction. * It must be associated with a merchant. * It must be in one of the following categories: * Bills & Utilities * Internet * Mobile Phone * Utilities * The user must have at least one historical debit transaction that is for the same merchant and in the same category as the transaction that is triggering this insight. * The user must have at least 3 transactions in the last 4 months from the same merchant with the same category. This is the default text for this insight. This is all customizable: * title: * higher: "Bill higher than usual" * lower: "Bill lower than usual" * description: * higher: "It looks like your most recent bill from `{merchant_name}` was higher than it normally is. You paid `{current_amount}`, which is `{percentage_change}` higher than your recent average payment of `{average_amount}`." * lower: "It looks like your most recent bill from `{merchant_name}` was lower than it normally is. You paid `{current_amount}`, which is `{percentage_change}` lower than your recent average payment of `{average_amount}`." * call to action: "View transactions"
## Upcoming Subscription Available in Mini Insights Widget This insight shows a user their upcoming subscription three days before payment occurs.
Image of the insight
This insight triggers when a user's scheduled payment(s) is created/updated and meets the following requirements: * Insight must not already exist for the scheduled payment. * Scheduled payment `occurs_on` date must be in the future. * Scheduled payment must be for a subscription. * Scheduled payment must not be from the same merchant, on the same day, and for the same amount. This is the default text for this insight. This is all customizable: * title: "Upcoming subscription" * description: "You have what looks like an upcoming subscription payment of `{amount}` due `{date}` to `{merchant_name}`." * call to action: N/A * supporting action: "View transactions"
## Monthly Obligations Status Available in Mini Insights Widget This insight informs users if they are on track/off track to pay off their monthly obligations.
Image of the insight
This insight is updated twice a month: on the 15th and one week before the end of the month. It must meet the following requirements: * The insight must not already exist for the previous month. * The user must have a checking, savings, or cash account. * Upcoming expenses should be a positive number. This is the default text for this insight. This is all customizable: * title: * On track: "You're on track!" * Off track: "You're off track!" * description: * On track: "You will have `{calculated amount}` left over with your current estimated income and expenses planned for this month are paid." * Off track: "You will have `{calculated amount}` left over after paying your planned expenses this month. Consider making a transfer." * call to action: * On track: "View details" * Off track: "Make a transfer" * supporting action: "View details"
## Subscription Detected Available in Mini Insights Widget This insight notifies users of a subscription in one of their accounts that has not been identified before for this user.
Image of the insight
This insight triggers when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * The transaction status must be `POSTED`. * The transaction is associated with a scheduled payment. * The transaction is a debit. * The transaction is associated with a merchant. * The scheduled payment has `scheduled_payment_type` set to 1. * We are unable to find a previously created transaction for the same scheduled payment. We look as far as 13 months ago for a matching transaction. This is the default text for this insight. This is all customizable: * title: "Subscription detected" * description: * with annual amount: "We found what we think is a new subscription to `{merchant_name}` for `{annual_subscription_amount_sum}` per year." * without annual amount: "We found what we think is a new subscription that we haven't seen before. It's from `{merchant_name}`." * call to action: "Does that look right?" This is not customizable. * supporting action: "View details"
## Subscription Price Increase Available in Mini Insights Widget This insight notifies users that a subscription has increased.
Image of the insight
This insight triggers when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * Two transactions are required in order for a Subscription Price Increase insight to be generated: * The first transaction is the transaction that is being created. * The second transaction is the previous transaction associated with the subscription. The search range for this transaction starts one second before the date time of the first transaction and goes back 13 months. * Both of these transactions must be: * Assigned to the same merchant (`merchant_guid`). * Assigned to the same scheduled payment (`scheduled_payment_guid`) * The difference in the amount of the two transactions must be over 50 cents (\$0.50). * The type of the assigned scheduled payment must be `SUBSCRIPTION`. This is the default text for this insight. This is all customizable: * title: "Price increase" * description: "`{merchant_name}` charged you `{increase_amount}` more this month than normal. Did you upgrade your service?"
## Unexpected Subscription Payment Available in Mini Insights Widget This insight notifies users when a transaction is created that contradicts the user feedback on an associated scheduled payment.
Image of the insight
This insight triggers when a transaction is created that meets the following requirements: * Transaction must be `DEBIT`. * Transaction must have an associated scheduled payment. * No insight must exist for the account and scheduled payment associated with the Transaction. * The associated scheduled payment must have a user response of `NEVER_SUBSCRIBED`, `CANCELLED` or `ONE_TIME_PURCHASE`. * The transaction must have a `merchant_guid`. * The transaction must match the `merchant_guid`, and `account_guid` of the associated scheduled payment. * The transaction amount and the scheduled payment amount must fall within the following threshold of each other: `(scheduled_payments.amount) = ABS(transaction.amount) +- ABS(scheduled_payments.amount) * 0.2`. This is the default text for this insight. This is all customizable: * user response: * never subscribed: "never subscribed" * cancelled: "cancelled" * one time purchase: "one time purchase" * title: "Unexpected charge" * description: "On `{date}`, `{merchant_name}` charged you `{amount}` for a subscription that you marked as `{user_response}` on `{user_response_set_at}`. We recommend you check your `{merchant_name}` subscription status, and then confirm it here." * call to action: "Update subscription status" * supporting action: "View transaction"
## Monthly Subscription Aggregate V2 Available in Mini Insights Widget Notification available This insight identifies all subscriptions paid by a user in the prior month.
Image of the insight
This insight is triggered monthly. A transaction must meet the following requirements to generate: * A scheduled payment is considered a subscription when the `scheduled_payment_type` field is set to 1. * A transaction is considered a subscription transaction when it is associated to a subscription scheduled payment. * This insight aggregates all of a user's subscription scheduled payments and then finds all visible transactions associated to the scheduled payments for the previous month. This is the default text for this insight. This is all customizable: * not sampled: * title: "Subscriptions summary for `{date}`" * description: N/A * call to action: N/A * supporting action: N/A * sampled: * title: "Subscriptions summary for `{date}`" * description: * zero: "Due to changes in the date, the information here is no longer relevant." * one: "In `{date}`, you paid for subscriptions from one merchant, which cost `{amount_sum}`. Make sure to cancel any unwanted subscriptions." * other: "In `{date}`, you paid for subscriptions from `{count}` merchants, totaling `{amount_sum}`. Make sure to cancel any unwanted subscriptions." * call to action: * zero: N/A * one: "View subscription" * other: "View all subscriptions"
## Account Discoverability Change This insight informs users when new accounts are connected or unhidden, as well as when existing accounts are disconnected and hidden.
Image of the insight
This insight triggers when a user: * Connects, disconnects, or restores a connection an account. * Hides or unhides an account. This is the default text for this insight. This is all customizable: * connecting: * title: * one: "Account connected" * other: "Accounts connected" * description: * one: "Going forward, your `{account_names}` account will now be used in the creation of your insights." * other: "Going forward, your `{account_names}` accounts will now be used in the creation of your insights." * disconnecting: * title: * one: "Account disconnected" * other: "Accounts disconnected" * description: * one: "Going forward, your `{account_names}` account will no longer be used in the creation of your insights." * other: "Going forward, your `{account_names}` accounts will no longer be used in the creation of your insights."
## Discovered Accounts Available in Mini Insights Widget Notification available This insight identifies discovered accounts from the user’s held account data and suggests they connect the discovered account.
Image of the insight
This insight is only available if you're using our PFM or Mobile product. This insight must meet the following requirements to generate: * The transaction category is Credit Card Payment. * No accounts from the discovered institution have already been aggregated. * No insight exists for the discovered institution. This is the default text for this insight. This is all customizable: * accounts available * title: "Connect all your accounts" * description: "We found account(s) at `{discovered_institution_name}`, that you can connect to get a complete view of your finances." * call to action: "Connect accounts" * supporting action: "Learn more" * short title: "Connect all accounts" * mini title: "Connect all your accounts" * mini description: "We found account(s) at `{discovered_institution_name}`, that you can connect to get a complete view of your finances." * mini call to action: "Learn more" * micro title: "Connect all your accounts" * micro description: "Connect `{discovered_institution_name}` to get a complete view of your finances." * micro call to action: "Learn more" * aggregation complete * title: "Connect all your accounts" * description: "You have successfully connected your institution `{discovered_institution_name}`." * call to action: "Add another connection" * supporting action: "I don't have any" * mini title: "Connect all your accounts" * mini description: "You have successfully connected your institution `{discovered_institution_name}`." * mini call to action: "Learn more" * micro title: "Connect all your accounts" * micro description: "You have successfully connected your institution`{discovered_institution_name}`." * micro call to action: "Learn more" * zero state * title: "Connect all your accounts" * description: "Connect accounts outside of `{held_institution_name}` to easily track spending and savings across all your accounts." * call to action: "Connect accounts" * supporting action: "I don't have any" * mini title: "Connect all your accounts" * mini description: "Connect accounts outside of `{held_institution_name}` to easily track spending and savings across all your accounts." * mini call to action: "Learn more" * micro description: "Link all your financial accounts to monitor and track spending and savings." * micro call to action: "Learn more"
## Cash Back Available in Mini Insights Widget This insight notifies users that MX has identified this transaction on one of their accounts.
Image of the insight
This insight triggers when a transaction is created that: * Has the `CREDIT` transaction type. * Has the `BONUS` transaction category. This is the default text for this insight. This is all customizable: * title: "You got some money!" * description: "A reward of `{amount}` was deposited to your `{localized_account_name}` account." * call to action: "View transaction"
## Charge Dispute Refund Available in Mini Insights Widget This insight notifies users that they've received a credit related to a charge dispute.
Image of the insight
This insight triggers when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * The transaction status must be `POSTED.` * The transaction must be a `CREDIT`. * The `system_transaction_rule_guid` is set to one of the following: * Final dispute * Permanent dispute * Permanent credit on dispute * The transaction must be held in an account with type `CHECKING`, `SAVINGS`, or `CREDIT_CARD`. This is the default text for this insight. This is all customizable: * title: "Disputed charge refunded" * description: "On `{date}`, your `{localized_account_name}` account was credited `{transaction_amount}` for a transaction that was disputed recently." * call to action: "View transaction"
## Check Deposit Available in Mini Insights Widget This insight notifies users that MX has identified a check deposit transaction in one of their accounts. Only enable this insight if you aren't using the [Unified Deposit](/products/experience/insights/library#unified-deposit) insight. Enabling both will generate duplicate insights.
Image of the insight
This insight will not generate if one of the following insights has already generated for the relevant transaction: * Tax Deposit * Government Deposit * Deposit529 * HSA Deposit * Payroll Deposit * Check Deposit * Large Deposit * Savings Account Deposit This insight is triggered when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * The transaction status must be `POSTED`. * The transaction type must be `CREDIT`. * The transaction must be in the `INCOME` category. * The transaction must include "check deposit" or "mobile deposit" in the feed description; the case does not matter. * The transaction must be held in either a checking or savings account. This is the default text for this insight. This is all customizable: * title: "Check deposit" * description: "You received a check deposit in the amount of `{transaction_amount}`."
## Government Deposit Available in Mini Insights Widget This insight notifies users of a deposit classified as government income. Only enable this insight if you aren't using the [Unified Deposit](/products/experience/insights/library#unified-deposit) insight. Enabling both will generate duplicate insights.
Image of the insight
This insight will not generate if one of the following insights has already generated for the relevant transaction: * Tax Deposit * Government Deposit * Deposit529 * HSA Deposit * Payroll Deposit * Check Deposit * Large Deposit * Savings Account Deposit This insight is triggered when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * A transaction must meet all the following conditions for a Government Deposit insight to generate: * The transaction status must be `POSTED`. * The transaction classifications include `is_government_deposit`. * The deposit amount is equal to or above the default threshold value of \$500. * The transaction must be held in an account with type `CHECKING` or `SAVINGS`. * Limited to five insights each week. This is the default text for this insight. This is all customizable: * title: "Government deposit received" * description: "A government deposit of `{transaction_amount}` was received into your `{localized_account_name}` account."
## Large Deposit Available in Mini Insights Widget Notification available This insight notifies users that MX has identified a large deposit in one of their accounts. Only enable this insight if you aren't using the [Unified Deposit](/products/experience/insights/library#unified-deposit) insight. Enabling both will generate duplicate insights.
Image of the insight
This insight will not generate if one of the following insights has already generated for the relevant transaction: * Tax Deposit * Government Deposit * Deposit529 * HSA Deposit * Payroll Deposit * Check Deposit * Large Deposit * Savings Account Deposit This insight is triggered when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * The transaction status must be `POSTED`. * The transaction type must be `CREDIT`. * The transaction category must not be `Transfer`. * The transaction must have an amount greater or equal to a dynamically adjusted threshold (client-configurable default: \$500) * The transaction must be held in an account with type `CHECKING` or `SAVINGS`. This is the default text for this insight. This is all customizable: * title: "`{transaction_amount}` deposit received" * description: "A deposit of `{transaction_amount}` was received into your `{localized_account_name}` account."
## Merchant Credit Received This insight notifies users when a merchant credit reaches their account. Only enable this insight if you aren't using the [Unified Deposit](/products/experience/insights/library#unified-deposit) insight. Enabling both will generate duplicate insights.
Image of the insight
This insight will not generate if one of the following insights has already generated for the relevant transaction: * Tax Deposit * Government Deposit * Deposit529 * HSA Deposit * Payroll Deposit * Check Deposit * Large Deposit * Savings Account Deposit This insight is triggered when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * There's a credit transaction with a valid merchant. * The merchant must be present and not a known financial institution. * Is in a spending top-level category or a purchase return. * The category isn't for insurance: * Auto Insurance * Health Insurance * Home Insurance * Life Insurance * unless the `feed_description` is one of the following: * Auto Ins Refund * Auto Insurance Refund * Credit Voucher * Payment Refund * Pmt Refund * `is_gig_income` is false. * Is not classified as a fee. This is the default text for this insight. This is all customizable: * title: "Large transaction" * description: * no merchant: "We detected a large transaction for `{amount}` in your `{localized_account_name}` account on `{date}`." * with merchant: "We detected a large transaction from `{merchant_name}` for `{amount}` in your `{localized_account_name}` account on `{date}`." * call to action: "View transaction"
## Payroll Deposit Available in Mini Insights Widget This insight notifies users of a deposit classified as a paycheck/payroll. Only enable this insight if you aren't using the [Unified Deposit](/products/experience/insights/library#unified-deposit) insight. Enabling both will generate duplicate insights.
Image of the insight
This insight will not generate if one of the following insights has already generated for the relevant transaction: * Tax Deposit * Government Deposit * Deposit529 * HSA Deposit * Payroll Deposit * Check Deposit * Large Deposit * Savings Account Deposit This insight is triggered when a transaction is created which meets the following requirements, or a `PENDING` transaction which meets the following requirements is updated to a status of `POSTED`: * A transaction must meet all of the following conditions to be generate: * The transaction status must be `POSTED`. * The transaction category must be "Paycheck". * The transaction type must be "Credit". * The deposit account type must be Checking or Savings. * Limited to five insights each week. This is the default text for this insight. This is all customizable: * title: "Payroll deposited" * description: "It looks like you received a payroll deposit of `{amount}` on `{date}`."
## Unified Deposit Available in Mini Insights Widget Notification available This insight notifies users of deposits that fall into any one of the following categories: * Tax deposit * Government deposit * Payroll advance * Payroll deposit * Check deposit * Credit received from a merchant * Large deposit The insight adapts automatically if the deposit type changes (for example, reclassified from a vendor credit to payroll), or disappears if the deposit no longer qualifies.
Image of the insight
The insight is generated when there is a transaction with a `posted` status and `credit` type in a `CHECKING` or `SAVINGS` account. The insight copy changes based on the transaction category. Transactions are categorized based on the following criteria: | Category | Transaction Requirements | | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Tax deposit | Must have a top-level category of `taxes` | | Government deposit | Classifications must include `is_government_deposit` and the deposit must be equal to or above the client-configurable threshold value of \$500 | | Payroll advance | Must be classified as `is_payroll_advance` | | Payroll deposit | Category must be `payroll` | | Check deposit | Category must be `income` and the feed description must include "check deposit" or "mobile deposit" | | Merchant credit received | Must be matched to a valid merchant and be in a spending or purchase return category. Must **not** be from a known financial institution, classified as `is_gig_income` or `fee`, or for insurance (unless the `feed_description` is "Auto Ins Refund," "Auto Insurance Refund," "Credit Voucher," "Payment Refund," or "Pmt Refund") | | Large deposit | Amount is greater or equal to a dynamically adjusted threshold (client-configurable default: \$500). Must **not** be classified as `transfer` | This is the default text for this insight. This is all customizable: * Not sampled: * title: "Deposit received" * description: N/A * call to action: N/A * Check deposit: * title: "Check deposit" * description: "On `{transaction_date}`, a `{transaction_amount}` check deposit was received in your `{localized_account_name}` account." * call to action: "View details" * Government deposit: * title: "Government deposit received" * description: "On `{transaction_date}`, a `{transaction_amount}` government deposit was received in your `{localized_account_name}` account." * call to action: "View details" * Large deposit: * title: "`{transaction_amount}` deposit received" * description: "On `{transaction_date}`, a `{transaction_amount}` deposit was received in your `{localized_account_name}` account." * call to action: "View details" * Merchant credit received: * title: "Merchant credit received" * description: "A credit of `{amount}` from `{merchant_name}` has been added to your `{localized_account_name}`." * call to action: "View details" * Payroll advance: * title: "Payroll advance" * description: "On `{transaction_date}`, a `{transaction_amount}` payroll advance was received in your `{localized_account_name}` account." * call to action: "View details" * Payroll deposit: * title: "Payroll deposited" * description: "On `{transaction_date}`, a `{transaction_amount}` payroll deposit was received in your `{localized_account_name}` account." * call to action: "View details" * Tax deposit: * title: "Tax deposit" * description: "On `{transaction_date}`, a `{transaction_amount}` tax deposit was received in your `{localized_account_name}` account." * call to action: "View details" * Zero state: * title: "Deposit received" * description: "A deposit was previously received, but because of changes no further information is available." * call to action: N/A
## Monthly Deposit Summary V2 Available in Mini Insights Widget This insight tracks all credits coming into a user's accounts and provides a breakdown of what is regular income and other income.
Image of the insight
This insight triggers monthly and must meet the following requirements: * A credit transaction is considered income if the top level category is set to `Income`. * This insight must not already exist for the previous month. * The user must have at least one or more accounts the previous month. The account(s) must be a savings or checking account. * The user must have at least one or more transactions the previous month. * Transactions must be of type credit. * Transactions must not be any of the following top level categories: * Fees & Charges * Financial * Investments * Transfer * Uncategorized This is the default text for this insight. This is all customizable: * title: "`{prior_month}`'s deposits" * description: * zero deposits: "In `{prior_month}`, you had no deposits." * one deposit: "In `{prior_month}`, you deposited `{total_amount}` into your `{account_name}` account. Nice work!" * other: "In `{prior_month}`, you deposited `{total_amount}` into `{count}` accounts. Nice work!" * call to action: * zero deposits: N/A * one deposit: "View deposits" * other: "View deposits"
## Credit Card Close to Limit Available in Mini Insights Widget Notification available This insight notifies users that they have reached 75%, or a custom percentage, of their credit card spending limit.
Image of the insight
This insight triggers whenever an account is updated that meets the following requirements: * The user has one or more credit card accounts. * One or more accounts has hit or passed a user configurable percentage (defaults to 75%). This is the default text for this insight. This is all customizable: * title: "Nearing credit limit" * description: "You are `{amount_remaining}` away from reaching your `{localized_account_name}` credit limit. If possible, pay down your balance or avoid using this card." * call to action: "View more"
## Duplicate Payment V2 Available in Mini Insights Widget Notification available This insight alerts users when a possible duplicate payment is detected. When there's a new transaction, we check for transactions that have the same date, amount, and merchant.
Image of the insight
This insight generates if at least two transactions have either: * The same amount and `merchant_guid`. * The same amount and description but no `merchant_guid`. Also, the transactions must be debit transactions posted under the same account and have dates (transacted or posted dates) that are no more than 15 minutes apart. Account type should be either `CHECKING` or `CREDIT_CARD`. This is the default text for this insight. This is all customizable: * title: "Duplicate payment detected" * description: * with merchant: "It looks like you may have a duplicate charge of `{amount}` to `{merchant_name}` on `{date}`." * without merchant: "It looks like you may have a duplicate charge of `{amount}` on `{date}`." * call to action: "View transactions"
## Fee Detected Available in Mini Insights Widget Notification available An insight to help users identify fees that are charged to their account.
Image of the insight
This insight triggers when a transaction is created which meets the following requirements: * Transaction is `DEBIT` * Occurs in one of the following categories: * Fees & Charges * ATM Fee * Bank Fee * Finance Charge * Late Fee * Service Fee * Limit to 5 insights each week This is the default text for this insight. This is all customizable: * title: "New fee detected" * description: * with merchant: "`{merchant_name}` charged you `{amount}`. It’s a good idea to ensure charges are correct and, if needed, make adjustments to avoid fees." * no merchant: "You were charged `{amount}` for `{localized_description}`. It’s a good idea to ensure charges are correct and, if needed, make adjustments to avoid fees." * call to action: "View charge"
## Green Statement Fee Available in Mini Insights Widget This insight shows a recent paper statement fee and reminds users that they can save money—and the planet—by opting out of paper statements.
Image of the insight
This insight is triggered every time a transaction with the following attributes occurs, until the limit of 5 per week is met: * Transaction has the `DEBIT` type. * Category must have `top_level_category_name : Fees & Charges`. This is the default text for this insight. This is all customizable: * Internal account: * title: "Paper statement fee" * description: "On `{date}`, your `{account_name}` account was charged `{amount}` for a paper statement. Consider switching to paperless to save on this fee." * call to action: "Switch to paperless" * supporting action: "View transaction" * External account: * title: "Paper statement fee" * description: "On `{date}`, your `{account_name}` account was charged `{amount}` for a paper statement. Consider switching to paperless to save on this fee." * call to action: "View transaction" * supporting action: N/A * Zero state: * title: "No longer relevant" * description: "Due to changes in the data, the information here is no longer relevant." * call to action: N/A * supporting action: N/A
## Large Transaction Available in Mini Insights Widget Notification available This insight notifies the user of larger-than-normal transactions.
Image of the insight
This insight is triggered when a transaction is created which meets the following requirements: * The amount is greater than a default threshold of \$500, or by a configured amount. * Debit only transactions. * Only spend account types (Checking, Savings, Credit Card). * Occurs in one of the following categories: * Auto & Transport (not auto payments or auto insurance) * Bills & Utilities * Business Services * Education (not student loans) * Entertainment * Food & Dining * Health & Fitness * Home (not mortgage or home insurance) * Kids * Personal Care * Pets * Shopping * Travel * Uncategorized * Transaction hasn't been triggered in another insight already. This is the default text for this insight. This is all customizable: * title: "Large transaction" * description: * no merchant: "We detected a large transaction for `{amount}` in your `{localized_account_name}` account on `{date}`." * with merchant: "We detected a large transaction from `{merchant_name}` for `{amount}` in your `{localized_account_name}` account on `{date}`." * call to action: "View transaction"
## Transparent Overdraft Available in Mini Insights Widget This insight warn users of a possible overdraft projected within the next seven days.
Image of the insight
This insight is triggered when the following requirements are met: * The user has at least one checking account. * Account balance information is available for the account in question for the current date and each day for one month prior. * An Overdraft Prediction must exist with a prediction value of true. * The user can't already have a transparent overdraft warning insight for a given account that was active within the last 7 days. This is the default text for this insight. This is all customizable: * title: "Overdraft warning" * description: "You are projected to overdraft your `{localized_account_name}` account by `{projected_overdraft_amount}` in the next seven days, but there's still time to move money around." * call to action: "Transfer funds" * supporting action: "Learn more"
## Low Account Balance Available in Mini Insights Widget Notification available This insight notifies users when an account balance falls below a certain threshold. Users can change the threshold within the insight, transfer funds, and view transactions related to the account.
Image of the insight
This insight is triggered when an account balance falls below a default threshold of \$100 (configurable) and the account has not triggered a previous Low Account Balance insight within 15 days. This is the default text for this insight. This is all customizable: * title: "Low balance alert" * description: "On `{date}`, your `{localized_account_name}` account balance fell below `{threshold}`." * description call to action: "View transactions" * call to action: "Transfer funds" * supporting action: "Edit alert settings"
## Microdeposits Available in Mini Insights Widget This insight alerts users when microdeposits have reached their account. Microdeposits are usually less than \$1 and are made to verify that accounts receiving the transaction are actually the accounts the sender intended to reach.
Image of the insight
This insight triggers when: * There are two transactions that: * Have the `is_micro_deposit` classifier. * Have the same `merchant_guid`. * Have the same description. * Are in a deposit account. * The transactions must be credit transactions posted under the same account and must have occurred within 24 hours of each other. Account type should be either `CHECKING` or `SAVINGS`. This is the default text for this insight. This is all customizable: * title: "Micro-deposits detected" * description: "On `{date}` we noticed 2 small amounts added to `{localized_account_name}` that look like micro-deposits. This may be connected to an action you took to verify your account, so check that you recognize the sender." * call to action: "View deposits"
## New Merchant Available in Mini Insights Widget This insight informs users when they have new transactions with a merchant that they haven't shopped with for at least a year.
Image of the insight
This insight triggers when the following requirements are met: * The user does not have a transaction from the merchant within the last 15 months. * The user has at least 30 transactions within the last 130 days. * The transaction amount is greater or equal to 50.00. * The transaction is not older than 5 days. * The transaction is from an account that was created more than 1 day ago. * The transaction is a debit. * The merchant is not “Venmo”. * The transaction top level category is one of the following categories: * Auto & Transport * Business Services * Entertainment * Education * Food & Dining * Gifts & Donations * Health & Fitness * Home * Kids * Personal Care * Pets * Shopping * Travel * Uncategorized This is the default text for this insight. This is all customizable: * title: "Purchase for review" * description: "We noticed that you have never shopped here or haven't shopped here for at least a year. If you don't recognize this purchase, it may be fraudulent, and we recommend reaching out to the associated financial institution right away." * call to action: "View transaction"
## Uncategorized Transactions V2 Available in Mini Insights Widget Notification available This insight identifies all transactions which have been assigned `Uncategorized` as the transaction category within the last 30 days.
Image of the insight
This insight triggers weekly and must meet the following requirements to generate: * The user must have at least one transaction that is uncategorized within the last 30 days. * No previous Uncategorized Transactions V2 insight has been created within the last 15 days (this number of days is configurable). This is the default text for this insight. This is all customizable: * title: "Uncategorized transactions" * description: * zero: "You categorized all your recent transactions. Nice job!" * one: "Let's categorize this transaction. Doing so will help us provide you with more accurate and holistic insights on your finances." * other: "Let's categorize these transactions. Doing so will help us provide you with more accurate and holistic insights on your finances." * call to action: * zero: N/A * one: "View transaction" * other: "View transactions"
## Green Gas Purchases Summary Available in Mini Insights Widget This insight informs users of how often they're visiting the gas pump.
Image of the insight
This insight is triggered monthly and requires a user to have at least 8 spending transactions in the last 7 months in the gas category, 2 transactions in the described month, and 6 transactions in the prior 6 months. This is the default text for this insight. This is all customizable: * higher than normal: * title: "Your visits to the pump" * description: "In `{month_name}`, you spent `{total_debt_for_fill_up_visits_in_prev_month}` on `{total_fill_up_visits}` visits to the gas pump, which is more frequent than usual. Check out these tips to help you use less gas." * call to action: "View history" * supporting action: "Tips on how to save" * lower than normal: * title: "Your visits to the pump" * description: "In `{month_name}`, you spent `{total_debt_for_fill_up_visits_in_prev_month}` on `{total_fill_up_visits}` visits to the gas pump, which is less frequent than usual." * call to action: "View history" * supporting action: "Tips on how to save" * no change: * title: "Your visits to the pump" * description: "In `{month_name}`, you spent `{total_debt_for_fill_up_visits_in_prev_month}` on `{total_fill_up_visits}` visits to the gas pump, which is normal for you" * call to action: "View history" * supporting action: "Tips on how to save" * zero state: * title: "Your visits to the pump" * description: "Due to changes in the data, the information here is no longer relevant." * call to action: N/A * supporting action: N/A
## Weekend Spending Summary V2 Available in Mini Insights Widget Notification available This insight provides users with a summary of total non-essential expenses from the previous weekend, grouped by category with total amount spent.
Image of the insight
This insight triggers weekly and must meet the following requirements to generate: * Some Checking/Credit Card non-essential spending transaction data must be available for the most recent completed weekend. If the insight is generated on a weekend (Saturday or Sunday), then the previous weekend will be used. * The insight must not have been generated for the prior weekend. A transaction is considered non-essential spending where one of the following conditions are met: * Condition 1: * Top level category is one of the following: * Entertainment * Food And Dining * Gifts And Donations * Home * Personal Care * Shopping * Travel * And category is not one of the following: * Groceries * Mortgage And Rent * Home Insurance * Laundry * Condition 2: * Category is one of the following: * Kids Activities * Pet Grooming * Sports * Television * Toys * Transfer For Cash Spending * Condition 3: Transaction is uncategorized. This is the default text for this insight. This is all customizable: * title: "Weekend spending summary" * description: * zero: "Due to changes in the data, the spending information here is no longer relevant." * one: "You spent `{total_spending}` last weekend in these non-essential categories." * other: "You spent `{total_spending}` last weekend in these non-essential categories." * call to action: * zero: N/A * one: "View weekend information" * other: "View weekend information" * supporting action: "Learn more"
## Weekly New Merchants V2 Available in Mini Insights Widget Notification available This insight notifies users that MX has identified one or more new merchants they have previously not interacted with during the previous week.
Image of the insight
This insight triggers weekly and must meet the following requirements to generate: * A merchant is considered a new merchant when all of the following are true: * The user does not have a transaction from the merchant within the last fifteen months. * The transaction is a debit. * The transaction occurred within the previous week. A week starts on Monday and ends on Sunday. * The merchant is not "Venmo." * The transaction is from an account that was created more than one day ago. * The transaction top level category is one of the following categories: * Auto & Transport * Business Services * Entertainment * Education * Food & Dining * Gifts & Donations * Health & Fitness * Home * Kids * Personal Care * Pets * Shopping * Travel * Uncategorized * The transaction category is not one of the following: * Auto Payment * Student Loan * Health Insurance * Mortgage & Rent * Cash * Check * If there is only one new merchant transaction and a New Merchant insight has already been generated for it, the Weekly New Merchants insight will not be generated. This is the default text for this insight. This is all customizable: * title: * one: "Purchase for review" * other: "Purchases for review" * description: * one: "You had 1 transaction last week at a business we haven't seen you shop at for the last year. If you don't recognize this purchase, reach out to the associated financial institution right away." * other: "You had `{count}` transactions last week at businesses we haven't seen you shop at for the last year. If you don't recognize these purchases, reach out to the associated financial institutions right away." * call to action: * one: "View transaction" * other: "View transactions" * zero state: * title: "Purchases for review" * description: "Due to changes in the data, the information here is no longer relevant."
## Weekly No Spend Days Available in Mini Insights Widget This insight informs users of the days in the past week where they had \$0 in non-essential spending to positively reinforce that behavior.
Image of the insight
This insight triggers when one or more no spend days are detected in a week. "Spending Days" are defined by two scenarios: * A transaction has a top level category of Entertainment, Food & Dining, Gifts & Donations, Home, Personal Care, Shopping, or Travel, and its category does not include Groceries, Mortgage & Rent, Home Insurance, or Laundry. * A transaction has a category of Allowance, Domain Names, Financial Advisor, Fraud Protection, Gym, Hosting, Kids Activities, Pet Grooming, Sports, Television, Toys, or Transfer for Cash Spending. This is the default text for this insight. This is all customizable: * title: "No spend days" * description: * zero state scenario: "We currently show there were no days without spending, last week." * first scenario: "Last week, you had 7 days with no purchases! That is a rare accomplishment. Nicely done!" * second scenario: "Last week, you had `{total_no_spend_days}` days with no purchases! That is a rare accomplishment. Nicely done!" * third scenario: "Last week, you had `{total_no_spend_days}` days with no purchases! Way to go!" * fourth scenario: "Last week, you had 1 day with no purchases! See if you can bump that up to two days, this week." * second scenario spending plan enabled: "Last week, you had `{total_no_spend_days}` days with no purchases! That is a rare accomplishment. Nicely done!" * third scenario spending plan enabled: "Last week, you had `{total_no_spend_days}` days with no purchases! Way to go!" * fourth scenario spending plan enabled: "Last week, you had 1 day with no purchases! See if you can bump that up to two days, this week." * call to action: * zero state scenario: "View more" * first scenario: N/A * second scenario: "View more" * third scenario: "View more" * fourth scenario: "View more" * second scenario spending plan enabled: "Visit Spending Plan" * third scenario spending plan enabled: "Visit Spending Plan" * fourth scenario spending plan enabled: "Visit Spending Plan"
## Weekly Small Purchases Summary Available in Mini Insights Widget This insight notifies users that they've made a large number of small purchases within the previous week.
Image of the insight
This insight triggers weekly and must meet the following requirements: * Total of small purchase amounts from the previous week must be at least as high as the Small Purchases Total Threshold set on the client's insight profile (default value is \$30). * A transaction is considered a small purchase when: * The amount is less than the Small Purchase Ceiling Amount configured by the client (default value is \$10). * It's a Debit transaction. * It comes from a Savings, Checking or Credit Card account. * The top level category is one of the following: * Auto & Transport * Bills & Utilities * Business Services * Education * Entertainment * Fees & Charges * Financial * Food & Dining * Gifts & Donations * Health & Fitness * Home * Kids * Personal Care * Pets * Shopping * Travel * Uncategorized * The category is not one of the following: * Auto Insurance * Auto Payment * Babysitter & Daycare * Baby Supplies * Child Support * Doctor * Groceries * Health Insurance * Mortgage & Rent * Utilities This is the default text for this insight. This is all customizable: * title: "Small purchases" * description: * above threshold: "Last week, you had `{count}` transactions that were less than `{small_purchase_ceiling_amount}`, for a total of `{total_amount}`. Small purchases add up quickly!" * below threshold: * zero: "You had no purchases under `{small_purchase_ceiling_amount}` last week." * one: "You had one purchase under `{small_purchase_ceiling_amount}` last week." * other: "You had `{count}` purchases under `{small_purchase_ceiling_amount}` last week." * call to action: * above threshold: "View small purchases" * below threshold: * zero: N/A * one: "View small purchase" * other: "View small purchases"
## Weekly Spending Plan Summary This insight gives users a weekly summary of their [spending plan](/products/experience/pfm/legacy-widget-overviews/spending-plan). It informs them of the percentage of their total spending for a given plan, the number of days remaining in the spending plan period, and how much budgeted spending they have remaining.
Image of the insight
This insight triggers weekly and must meet the following requirements: * The user has no Weekly Spending Plan Summary insights in the last week. * The user has a spending plan iteration that matches the following criteria: * It has non-nil values for `start_on` and `end_on`. * It has a positive number of days remaining. * The spending plan has at least one iteration item that match the following criteria. * `planned_amount` is present. * `actual_amount` is present * `item_type` is `PLANNED_EXPENSE`. * The sum of the `planned_amount` of each iteration item is positive. This is the default text for this insight. This is all customizable: * Zero state: * title: "No longer relevant" * description: "Due to changes in the data, the information here is no longer relevant." * micro title: "Your total spending budget" * micro description: "Due to changes in the data, the information here is no longer relevant." * micro call to action: "Learn more" * Budget exceeded: * title: "Review your budgets" * description: "You are `{budget_overage}` over the `{total_budgeted}` budgeted for the month." * micro title: "Your total spending budget" * micro description: "You are `{budget_overage}` over the `{total_budgeted}` overall spending budget for the month." * micro call to action: "Learn more" * call to action: "View budgets" * Budget not exceeded: * title: "Review your budgets" * description: "You have spent `{percentage_spent}` of your budgets. You have `{remaining_budget_amount}` left with `{days_remaining_in_iteration}` days remaining in the month." * micro title: "Your total spending budget" * micro description: "You’ve spent `{percentage_spent}` of your overall spending budget with `{days_remaining_in_iteration}` days left in the month." * micro call to action: "Learn more" * call to action: "View budgets"
## Monthly Non-Essential Category Summary V2 Available in Mini Insights Widget This insight tracks all credits coming into a user's accounts and provides a break down of what is regular income and other income.
Image of the insight
This insight triggers monthly and must meet the following requirements: * Insight must not already exist for the previous month. * User must have at least one spending transaction for the previous month. * Total amount spent must be greater than 0. * Both non-essential and essential amounts spent can't be negative. This is the default text for this insight. This is all customizable: * high: * title: "Non-essential category summary" * description: "Out of `{total_amount}` you spent in `{prior_month}`, `{non_essential_percentage}` was spent on non-essential items. Try spending 30% or less on non-essentials." * call to action: "View transactions" * low: * title: "Non-essential category summary" * description: "Out of `{total_amount}` you spent in `{prior_month}`, only `{non_essential_percentage}` was spent on non-essential items, good job!" * call to action: "View transactions" * zero state: * without data: * title: "No longer relevant" * description: "Due to changes in the data, the spending information here is no longer relevant." * with data: * title: "Non-essential category summary" * description: "It looks like you don't have any non-essential spending this month. You may want to double check how these transactions are categorized." * call to action: "View transactions"
## Monthly Spend Comparison V2 Available in Mini Insights Widget Notification available This insight provides users with a summary of total expenses in the previous month, together with a comparison of those total expenses against the average for prior months.
Image of the insight
This insight triggers monthly and needs historical transaction data to be available for at least the two previous months. This is the default text for this insight. This is all customizable: * not sampled: * title: "Monthly spend comparison" * description: N/A * call to action: N/A * higher: * title: "Monthly spend comparison" * description: "You spent `{amount_sum}` in `{prior_month}`, which was `{absolute_difference}` higher than your recent average." * call to action: "View transactions" * lower: * title: "Monthly spend comparison" * description: "You spent `{amount_sum}` in `{prior_month}`, which was `{absolute_difference}` lower than your recent average." * call to action: "View transactions" * same: * title: "Monthly spend comparison" * description: "You spent `{amount_sum}` in `{prior_month}`, which was about the same as your recent average." * call to action: "View transactions"
## Monthly Spend To Income Comparison V2 Available in Mini Insights Widget Notification available This insight shows a user their income to spend comparison for the last four months.
Image of the insight
This insight triggers monthly and must meet the following requirements to generate: * This insight must not already exist for the previous month. * The user must have at least 1 Checkings or Savings account. * The user must have at least 2 months in the previous 4 months with transactions in Checkings or Savings account(s). * The user must have transactions for the previous month in Checkings or Savings account(s). This is the default text for this insight. This is all customizable: * title: "Spend vs. income" * description: * positive: "In `{last_month}`, you spent `{income_to_spending_percentage}` of your income, or `{income_to_spending_difference}` less than you made. Way to go!" * negative: "In `{last_month}`, you spent `{income_to_spending_percentage}` of your income or `{income_to_spending_difference}` more than you made. Try to spend less than you make each month." * zero state: "Due to changes in the data, the information here is no longer relevant." * call to action: * positive: "View transactions" * negative: "View transactions" * zero state: N/A
## Monthly Top Merchant Spending V3 Available in Mini Insights Widget Notification available This insight shows users what merchants they spent the most non-essential money on in the previous month.
Image of the insight
This insight triggers monthly and must meet the following requirements to generate: * This insight must not already exist for the previous month. * The user must have at least one merchant with a positive net total of non-essential spending transactions in the previous month. In the event that a merchant is not available for a transaction, we assume the description is the merchant name. A transaction is considered non-essential spending where one of the following conditions are met: * Condition 1: * Top level category is one of the following: * Entertainment * Food And Dining * Gifts And Donations * Home * Personal Care * hopping * Travel * And category is not one of the following: * Groceries * Mortgage And Rent * Home Insurance * Laundry * Condition 2: * Category is one of the following: * Allowance * Domain Names * Financial Advisor * Fraud Protection * Gym * Hosting * Kids Activities * Pet Grooming * Sports * Television * Toys * Transfer For Cash Spending This is the default text for this insight. This is all customizable: * title: * zero: "`{prior_month}`'s top merchant" * one: "`{prior_month}`'s top merchant" * other: "`{prior_month}`'s top merchants" * description: * zero: "Due to changes in the data, the information here is no longer relevant." * one: "This was your top merchant in `{prior_month}`, where you spent `{total}`. You can create a budget for well-known merchants to help track your spending." * other: "These were your top merchants in `{prior_month}`, where you spent `{total}`. You can create a budget for well-known merchants to help track your spending." * call to action: * zero: N/A * one: "View transactions" * other: "View transactions"
## Monthly Top Transacted Merchant This insight lets users know what merchants they use the most.
Image of the insight
This insight triggers monthly and must meet the following requirements to generate: * Must have 3 months of data minimum, 6 months to show trend data. * Transaction types must be `DEBIT`. This is the default text for this insight. This is all customizable: * title: * quiz: "Do you know your most visited merchant?" * results: "Your most visited merchants" * zero state: "Your most visited merchants" * description: * quiz: "In `{prior_month}`, you had `{transaction_count}` spending transactions. Do you know which merchant you had the most transactions with?" * results: * one: "Your most visited merchant in `{prior_month}` was `{top_transacted_merchant_name}` for a total of `{top_transacted_merchant_transaction_count}` transactions." * other: "`{top_transacted_merchant_name}` was one of your most visited merchants in `{prior_month}` with a total of `{top_transacted_merchant_transaction_count}` transactions." * zero state: "Due to changes in the data, the information here is no longer relevant." * call to action: * quiz: "Check answer" * results: N/A * supporting action: * quiz: "Skip to the results" * results: N/A
## Quarterly Summary Available in Mini Insights Widget This insight redirects users to a summary of information about the their spending and saving habits in the previous quarter.
Image of the insight
This insight is triggered when a monthly user snapshot is created for the user and must meet the following requirements: * The user must have a monthly user snapshot available for all three months found in the previous quarter. * The user must not already have a Quarterly Summary insight for the previous quarter. This is the default text for this insight. This is all customizable: * title: "Let's break down the last three months" * description: "Your most visited merchants, total transactions, and more."
## Cost of Living To Income Available in Mini Insights Widget This insight notifies users that MX has identified that their spending in one of 5 category types is high compared to their income. An insight can be created for each of these categories: housing, groceries, healthcare, transportation, utilities.
Image of the insight
This insight triggers monthly and must meet the following requirements to generate: * The user has at least one income transaction for the previous month. * The user has at least one expense transaction for the previous month in at least one of the following category types: * Mortgage and Rent * Mortgage Payment * Groceries * Auto Payment * Auto Insurance * Public Transportation * Health Insurance * Doctor * Utilities * The percentage of expense to income is above the threshold defined for each category type: * Housing - 30% * Groceries - 15% * Healthcare - 10% * Transportation - 10% * Utilities - 10% This is the default text for this insight. This is all customizable: * sampled: * zero state: * title: N/A * description: "Due to changes in the data, the spending information here is no longer relevant." * call to action: N/A * housing: * title: "Housing vs. Income" * description: "In `{prior_month}`, you spent `{percentage}` of your monthly income on Housing. We recommend you keep this below `{suggested_percentage}` of your income, if possible." * call to action: "View more" * groceries: * title: "Groceries vs. Income" * description: "In `{prior_month}`, you spent `{percentage}` of your monthly income on Groceries. We recommend you keep this below `{suggested_percentage}` of your income, if possible." * call to action: "View more" * healthcare: * title: "Healthcare vs. Income" * description: "In `{prior_month}`, you spent `{percentage}` of your monthly income on Healthcare. We recommend you keep this below `{suggested_percentage}` of your income, if possible." * call to action: "View more" * transportation: * title: "Auto & Transport vs. Income" * description: "In `{prior_month}`, you spent `{percentage}` of your monthly income on Auto & Transport. We recommend you keep this below `{suggested_percentage}` of your income, if possible." * call to action: "View more" * utilities: * title: "Utilities vs. Income" * description: "In `{prior_month}`, you spent `{percentage}` of your monthly income on Utilities. We recommend you keep this below `{suggested_percentage}` of your income, if possible." * call to action: "View more"
## Peer-To-Peer Categorization Available in Mini Insights Widget This insight identifies all transactions which are person to person within the last 30 days.
Image of the insight
This insight triggers weekly and must meet the following requirements: * The user must have at least one transaction that's P2P within the last 30 days. * The transaction type is `DEBIT`. * The transaction(s) must be from one of the following merchants OR category: * PayPal * Apple Pay * Square * Zelle * Venmo * Google Pay * Cash App * Cash * No previous Peer-To-Peer categorization insight has been created within the last 15 days. This is the default text for this insight. This is all customizable: * title: * zero: "Recategorize your transfers" * one: "Recategorize your transfer" * other: "Recategorize your transfers" * description: * zero: "You recategorized all your recent transactions. Nice job!" * one: "To keep your insights accurate, please take a moment to recategorize this transfer." * other: "To keep your insights accurate, please take a moment to recategorize these `{count}` transfers." * call to action: * zero: N/A * one: "View transfer" * other: "View transfers"
## Merchant Budget Available in Mini Insights Widget This insight notifies users about their merchant budget status.
Image of the insight
This insight is triggered when a merchant budget is created or updated and meets the following requirements: * Budget's usage must be over 25%. * There must not be a Category Budget insight already created for the current usage tier: * 25%-49% * 50%-74% * 75%-100% * more than 100% * Budget's usage must be over the current day of month threshold. This is the default text for this insight. This is all customizable: * title: "`{merchant_name}`" * description: "You have spent `{budget_tier_percent}` or more of your `{merchant_name}` budget." * call to action: "View budget"
## Set Up Direct Deposit Available in Mini Insights Widget Notification available This insight tells users that we've detected a held account that doesn't have a direct deposit coming in and prompts them to set it up.
Image of the insight
This insight is triggered when a held account is created at MX and meets the following requirements: * The account is not closed. * The account must be a held account and either savings or checking. * There are no existing insights for the current year-month. * MX has been provided an account number corresponding to the account. * There are no existing direct deposits detected for the account. This is the default text for this insight. This is all customizable: * title: "Set up direct deposit" * description: "It appears that you haven't set up direct deposit for your new `{held_account_without_direct_deposit}` account. Activate direct deposit today to simplify your finances. * call to action: "Set up direct deposit"
## Switch Direct Deposit Available in Mini Insights Widget Notification available This insight tells users that we've detected a direct deposit that doesn't route to their held account and prompts them to switch the deposit to the held account.
Image of the insight
This insight is triggered in two scenarios: * **Scenario 1**: Direct Deposit detected in one of the user's aggregated accounts and not in their held account. * The user has one or more checking accounts with the held bank. * MX detects transactions in one or more of the user’s checking accounts at the held bank in the last 90 days. * If the user has multiple checking accounts with transactions detected, show the most used checking account as the suggested direct deposit account. * No direct deposit is detected in the user’s held accounts in the last 90 days. * A direct deposit is detected at one of the users aggregated bank accounts in the last 90 days. * **Scenario 2**: Direct Deposit is not detected in a new held account. * The user has a newly opened checking account in the last 30 days and MX detects activity. * No payroll/direct deposit is detected in the newly opened held checking account in the last 30 days. * A payroll/direct deposit is detected at one of the users aggregated bank accounts in the last 90 days. This is the default text for this insight. This is all customizable: * title: "Switch direct deposit" * description: "Switch your direct deposit from `{external_account_name}` to `{held_account_name}` account today to help manage everything in one account." * call to action: "Switch direct deposit"
## Spending Plan Category Spending This insight prompts the user to create a spending limit when spending in a category is disproportionately growing.
Image of the insight
This insight is triggered weekly and has the following requirements to generate: * The user has a [spending plan](/products/experience/pfm/legacy-widget-overviews/spending-plan). * A minimum of three months of historical data is available for the user. * When generated in the first 10 days of the month, the insight looks at up to six months of data ending on the previous month. When generated on the 11th day of the month and later, the insight looks at up to six months of data ending on the current month. In either case, the most recent month is referred to as the "subject month." The subject month's spending for each category is then compared to historical weighted averages. The historical weighted average for each category must be `$10` or more (as well as `-$10` or fewer). * At least one category has at least a 10% increase. Categories are limited to top-level expense categories (all top-level categories excluding `INCOME`, `INVESTMENTS`, `TAXES`, `TRANSFER`, and `UNCATEGORIZED`). * The number of these insights generated for a user is limited to 3 unless the client specifies to MX otherwise. This is the default text for this insight. This is all customizable: * title: "Category spending" * description: * high absolute: "Spending in the `{category_translation_key}` category is higher than usual. To help track your spending, would you like to add or edit a budget?" * high absolute with budget: "Spending in the `{category_translation_key}` category is higher than usual. To help track your spending, would you like to add or edit a budget?" * normal absolute: "Spending in the `{category_translation_key}` category looks about normal." * normal absolute with budget: "Spending in the `{category_translation_key}` category looks about normal." * low absolute: "Spending in the `{category_translation_key}` category is lower than usual." * low absolute with budget: "Spending in the `{category_translation_key}` category is lower than usual." * high on track: "You have spent `{current_month_total}` on `{category_translation_key}` in `{date}`. With `{days_remaining_in_month}` days left in the month, you're on track to spend more than usual in this category." * high on track with budget: "You have spent `{current_month_total}` on `{category_translation_key}` in `{date}`. With `{days_remaining_in_month}` days left in the month, you're on track to spend more than usual in this category." * normal on track: "You have spent `{current_month_total}` on `{category_translation_key}` in `{date}`. With `{days_remaining_in_month}` days left in the month, you're on track to spend about what you typically do in this category." * normal on track with budget: "You have spent `{current_month_total}` on `{category_translation_key}` in `{date}`. With `{days_remaining_in_month}` days left in the month, you're on track to spend about what you typically do in this category." * low on track: "You have spent `{current_month_total}` on `{category_translation_key}` in `{date}`. With `{days_remaining_in_month}` days left in the month, you're on track to spend less than usual in this category." * low on track with budget: "You have spent `{current_month_total}` on `{category_translation_key}` in `{date}`. With `{days_remaining_in_month}` days left in the month, you're on track to spend less than usual in this category." * no data: "No data to display at this time." * not sampled: N/A * call to action: * high absolute: "Create budget" * high absolute with budget: "Edit budget" * normal absolute: "Create budget" * normal absolute with budget: "Edit budget" * low absolute: "Create budget" * low absolute with budget: "Edit budget" * high on track: "Create budget" * high on track with budget: "Edit budget" * normal on track: "Create budget" * normal on track with budget: "Edit budget" * low on track: "Create budget" * low on track with budget: "Edit budget" * no data: N/A * not sampled: N/A * supporting action: "View transactions"
## Spending Plan Talk With Someone This insight suggests to [Spending Plan](/products/experience/pfm/legacy-widget-overviews/spending-plan) users that they should discuss their plan with someone they trust. While this insight triggers upon Spending Plan creation, a monthly version of this insight will remind users to discuss their plan with someone.
Image of the insight
This insight is triggered when a Spending Plan is created and there's no antecedent for the same Spending Plan. It is then triggered once per month and will generate if there's no antecedent for the same Spending Plan. This is the default text for this insight. This is all customizable: * First time a spending plan is created: * title: "Talk about your plan" * description: "Talk with someone you trust about your Spending Plan. Ask them to keep you on track with your financial goals." * call to action: "View spending plan" * Monthly: * Generic: * title: "Talk about your plan" * description: "Talk with someone you trust about your Spending Plan. Ask them to keep you on track with your financial goals." * call to action: "View spending plan" * Reminder: * title: "Talk about your plan" * description: "Reminder to check in with your partner and talk about how your Spending Plan is helping you to achieve your goals." * call to action: "View spending plan"
## Category Budget Notification available This insight notifies users about their budget status.
Image of the insight
This insight triggers when a budget is created or updated and meets the following requirements: * Budget's usage must be over 25%. * There must not be a Category Budget insight already created for the current usage tier: * 25%-49% * 50%-74% * 75%-100% * more than 100% * Budget's usage must be over the current day of month threshold. * Budget category isn't `INCOME`. This is the default text for this insight. This is all customizable: * title: "`{category_translation_key}`" * description: You have spent `{budget_tier_percent}` or more of your `{category_translation_key}` budget." * call to action: "View budget"
## Category Spending V2 Available in Mini Insights Widget Notification available This insight prompts a user to create a spending limit when spending in a category is growing significantly.
Image of the insight
This insight is triggered monthly and requires a transaction that meets the following requirements to generate: * A minimum of three months of historical data is available for the user. * For each category, the system calculates the weighted average of monthly spending. Categories with no spending are ignored. * When generated in the first 10 days of the month, the insight looks at up to six months of data ending on the previous month. When generated on the 11th day of the month and later, the insight looks at up to six months of data ending on the current month. In either case, the most recent month is referred to below as the "subject month." * The subject month's spending for each category is compared to historical weighted averages. * Insights are generated for users that have at least one category with at least a 10 percent increase. * Categories are limited to top-level expense categories (all top-level categories excluding `INCOME`, `INVESTMENTS`, `TAXES`, `TRANSFER`, and `UNCATEGORIZED`). This is the default text for this insight. This is all customizable: * title: "Category spending" * description (the description for this insight cards varies depending on the type of spending that has occurred): * high absolute: "Spending in the `{category_translation_key}` category is higher than usual. To help track your spending, would you like to add or edit a budget?" * normal absolute: "Spending in the `{category_translation_key}` category looks about normal." * low absolute: "Spending in the `{category_translation_key}` category is lower than usual." * high on track: "You have spent `{current_month_total}` on `{category_translation_key}` in `{date}`. With `{days_remaining_in_month}` days left in the month, you're on track to spend more than usual in this category." * normal on track: "You have spent `{current_month_total}` on `{category_translation_key}` in `{date}`. With `{days_remaining_in_month}` days left in the month, you're on track to spend about what you typically do in this category." * low on track: "You have spent `{current_month_total}` on `{category_translation_key}` in `{date}`. With `{days_remaining_in_month}` days left in the month, you're on track to spend less than usual in this category." * no data: "No data to display at this time." * not sampled: N/A * call to action: "Create budget" * supporting action: "View transactions"
# Insights Widgets Source: https://docs.mx.com/products/experience/insights/widget-overviews/index Financial Insights can display in three different widgets. Learn more about each one to determine the best solution for your use case. The full Insights Widget experience. Personalized financial insights in a more compact view. Our smallest Financial Insights view. # Insights Widget Source: https://docs.mx.com/products/experience/insights/widget-overviews/insights-widget The Insights Widget provides a feed of all a user's insights. Insights display in chronological order with the most recent at the top. Unless hidden by the user, insights stay in the feed for up to 90 days. image of the insights widget **INFO** To integrate the widget, you'll send an API request and receive a widget URL that can be embedded wherever you want. See [Integrate the Insights Widget](/products/experience/insights/integration-guides/integrate-insights-widget) for more info. For a list of all insights that can display in the widget, see the [Insights Library](/products/experience/insights/library). ## Calls to Action (CTAs) Some insights have a CTA button that takes the user to an activity like transferring to savings or setting up a budget. Some CTAs users may see in their insights include: * Create a budget * View all subscriptions * View budget * View transaction CTA buttons can send users to different locations. For example, one CTA button may open a drawer, while another may send the user to a transfers page. If the CTA sends a user somewhere outside of the widget, you'll need to prepare to handle these events during integration. For instructions on how to do this and a complete list of all insights that require this additional integration, see our [Developer Integration Guide](/products/experience/insights/integration-guides/integrate-insights-widget#insights-widget-events). ## Configurations & Customizations You can change the language used in the widget when sending the API request for the widget. You must contact MX to: * Change which insights are enabled for you. * When an insight is disabled, existing insights of that type in the Insights Widget won't go away. They will still be in the user's feed until the user hides them, or six months passes. * For a list of all insights, see the [Insights Library](/products/experience/insights/library). * You can request MX enable different insights to display in your Insights Widget, Mini Insights Widget, and Micro Insights Widget. * Customize the widget's brand color. If you want to change this, provide MX with a hex code for your brand's primary color. Changing this will affect the brand color used other PFM and insights widgets too. * For each insight in the Insights Widget, you can request MX to change the following copy (see the [Insights Library](/products/experience/insights/library) for all default copy): * Title * Description, including an optional selectable link * Call-to-action button (not every insight uses this) * Supporting action (not every insight uses this) * Customize the [thresholds](/products/experience/insights#insight-thresholds) used to trigger some insights. * Set your widget to display in dark mode. We can set the widgets to either: * Display in light or dark mode for all users, or * Follow each end user's system preferences ## Hiding an Insight Users can hide a specific insight once or hide it permanently so that type of insight will never show in their feed again. To hide an insight, users must: 1. Select the options menu icon within the insight. 2. Select **Hide this insight**. 3. Choose **Once** or **Always**. 4. Leave feedback (optional). A new card that says the insight has been hidden will take the hidden insight's place. To unhide a hidden insight, select the settings menu in the top-right corner and select "Manage hidden insights." ## Insight Details Two things can display beneath an insight in the Insights Widget: * The date: This shows when the insight was generated, not necessarily when it was first displayed. For some insights, this could also represent the date of a primary transaction or the date of a bank-observed holiday. * If the insight contains the transaction data of one account, it will display the account's name beneath the insight. If the insight contains transaction data from multiple accounts, then the number of related accounts will display beneath the insight. ## Supported Dimensions The Insights Widget supports a minimum height of 550px and a minimum width of 320px. ## User Feedback Users can provide feedback on insights through the Insight Widget's UI by: 1. Selecting the options menu icon on an insight. 2. Selecting **This is helpful** or **This is not helpful**. Selecting either feedback options shows a **Feedback sent** message that lets the user optionally provide more information on their feedback. Users can select a predefined option on a list or enter a comment. ## Widget Load Failure Message When the widget fails to load, a message with the following title and body copy displays: * Title: **Oops! Something went wrong.** * Body: **We've notified support and we're looking into the issue. Please try again later.** # Micro Insights Widget Overview Source: https://docs.mx.com/products/experience/insights/widget-overviews/micro-widget The Micro Insights Widget offers a carousel of insights that users can swipe through. The insights in this widget can include icons, but not images or charts. All insights can appear in the Micro Insights Widget. **INFO** To integrate the widget, see [Integrate the Micro Insights Widget](/products/experience/insights/integration-guides/integrate-micro-widget). By default, the widget includes: * A header that says **Insights**. * A **View all >** CTA. * A carousel of a user's insights. Each insight includes a **Learn more** CTA. This carousel contains up to five insight cards and has an additional card at the end of the carousel that directs users to the Insights Widget. The following image shows the Micro Insights Widget with all configurations enabled. image of the Micro Insights Widget ## Configurations & Customizations The callouts in the following image will be referenced in this section. image of the Micro Insights Widget configurations You can change the following yourself during integration: * Change the [language](/products/experience/insights/integration-guides#localize-insights-widgets) used in the widget. * Filter which insights appear by date. Insights older than the set date won't appear. (SSO API only) * Filter which insights appear by template name. (SSO API only) Contact MX to: * Change [which insights](/products/experience/insights/library) are enabled for you. You can request that MX enable different insights to display in your Micro Insights Widget, Insights Widget, and Mini Insights Widget. * Customize any insight's title or body copy. See the [Insights Library](/products/experience/insights/library) for all default copy. * Customize the **Insights** header copy and the **View all >** CTA copy. * Customize the [thresholds](/products/experience/insights#insight-thresholds) used to trigger some insights. * Customize the widget's [brand color](#example-brand-color). This color affects various elements, like CTA text colors. If you want to change this, provide MX with a hex code for your brand's primary color. Changing this setting will affect the brand color used in all other PFM and insights widgets. * Disable the widget's header. This turns off both the **Insights** title and the **View all >** CTA. You can't disable just one. * Disable all icons. * Disable the card border from displaying. * Disable the default 32px margin outside of the left and right of each card's border. * Have the **Read more** CTA appear directly below the body copy instead of at the bottom of the card. * Set your widget to display in dark mode. We can set insights widgets to either: * Display in light or dark mode for all users. * Or follow each end user's system preferences. ### Example Brand Color The following image shows what the Micro Insights Widget looks like with a different brand color. image of the Micro Insights Widget with a different brand color ## More Insights Available Card The **More insights available** card is the last in the carousel if the widget is in a non-zero state. This card directs the user to the insights feed (the Insights Widget). It has the following copy: * Default title copy: **More insights available** * Default body copy: **Discover all real-time financial insights made for you.** image of the more insights available card ## Recommended Dimensions We recommend a width-to-height ratio of 3:2. The minimum width we suggest is 200px. Optimal width x height is 320px x 224px. If dynamic text within an insight becomes too long and is unable to fit within the card, then the text will truncate with an ellipsis. ## Supported Character Count If you decide to change the default copy in an insight, keep in mind the maximum character count we support and recommend: * We **support** a maximum of 34 characters for the title copy and a maximum of 82 characters for the body copy. * We **recommend** a maximum 28 characters for the title copy and a maximum of 65 characters for the body copy. ## Zero State The widget has two zero states: * One for new users who don't have any insights. image of one zero state in the Micro Insights Widget * And another for users who have no relevant insights that generate in that specific instance of the Micro Insights Widget. image of a second zero state in the Micro Insights Widget The default copy for the two zero states are as follows. | Default Title Copy | Default Body Copy | CTA Copy | | :------------------------ | :------------------------------------------------------------------------------ | :----------- | | **No available insights** | **We'll have more insights for you once your accounts have more transactions.** | N/A | | **No relevant insights** | **Visit the insights feed to see all of your insights.** | **View all** | # Mini Insights Widget Overview Source: https://docs.mx.com/products/experience/insights/widget-overviews/mini-widget The Mini Insights Widget lets you embed a smaller and more lightweight experience on a mobile app or website. It shows end users a carousel of up to five insight cards that have shorter copy than the same versions of those insights that appear in the full feed (Insights Widget). The same insights display as the ones in the Insights Widget, and in the same chronological order. image of the mini insights widget It also has a single call-to-action, the **View more** button, that can send users to the full insights feed (Insights Widget). When viewing the first card in the widget, the left arrow is disabled. When viewing the last card, the right arrow is disabled. The dots between the right and left arrows are selectable and will navigate the user to the insight in that specific position. If an insight's text becomes too long and is unable to fit within the card, then the text will truncate with "..." **INFO** To integrate the widget, you'll send an API request and receive a widget URL that can be embedded wherever you want. See [Integrate the Mini Insights Widget](/products/experience/insights/integration-guides/integrate-mini-widget) for more info. For a list of all insights that can display in the widget, see the [Insights Library](/products/experience/insights/library). ## Configurations & Customizations You can change the following yourself during integration: * Filter which insights appear by date. Insights older than the set date won't appear. * Filter which insights appear by template name. * Change the [language](/products/experience/insights/integration-guides#localize-insights-widgets) used in the widget. Contact MX to: * Change which insights are enabled for you. * For a list of all insights, see the [Insights Library](/products/experience/insights/library). * You can request MX enable different insights to display in your Mini Insights Widget, Insights Widget, and Micro Insights Widget. * Customize the widget's brand color. This color affects the **View all >** CTA, and other elements. If you want to change this, provide MX with a hex code for your brand's primary color. Changing this will affect the brand color used other PFM and insights widgets too. * Customize any insight's title or body copy. See the [Insights Library](/products/experience/insights/library) for all default copy. * Customize the **View more >** CTA copy. * Customize the [thresholds](/products/experience/insights#insight-thresholds) used to trigger some insights. * Enable or disable the **View more >** CTA. * Set your widget to display in dark mode. We can set the widgets to either: * Display in light or dark mode for all users or * Follow each end user's system preferences. ## Insight Details The date above an insight in the Mini Insights Widget shows when the insight was generated, not necessarily when it was first displayed. For some insights, this could also represent the date of a primary transaction or the date of a bank-observed holiday. ## Which Insights Display In the Mini Insights Widget, the introduction insight appears as one of the earliest insights generated and moves down the feed naturally, just like other insights. The widget loads the five most recent insights and sees how many of those insights are Mini Insights Widget compatible. This process continues until the Mini Insights Widget displays up to five cards or has requested 20 cards. Insights will stay in the widget until they're replaced by newer insights. A **New insight** button will appear if a new insight is available to display in the Mini Insights Widget and there are fewer than five insights in the carousel. ## Supported Dimensions The Mini Insights Widget supports a width of 320px to 450px and a minimum height of 400px. ## Zero State When there's not enough user data or client-activated insights to display, users may have no insights to display. In that case, they'll see two zero state cards. If they have one insight to display, they'll also see one zero state card. If they have three to five insights to display, they'll see those insights and won't see any zero state cards. If one card is available to display, the "Check back later" zero state will display with it. # Accounts Source: https://docs.mx.com/products/experience/mobile/features/accounts The Accounts feature displays connected account information, balances, and transactions across multiple views within the app. Your users can view account details, access recent transactions, and perform account-specific actions based on account eligibility. Accounts appear in four elements: * Account Summary Card * Account Type Group * Account Details * Account Row ``` Create a backend endpoint that calls the Platform API to generate a [widget URL](/api-reference/platform-api/reference/request-widget-url). Set the `widget_type` to your desired widget; reference the list of [widget types](/api-reference/platform-api/reference/widgets#widget-types) for the acceptable values. ```html Line focusing example focus={1-5} theme={null} ``` Create listeners for the [widget events](#widget-events). Depending on the widget you're integrating, you may have to create additional event listeners: * If integrating the Money Dashboard Widget, you must create listeners for all the [Money Dashboard Widget events](#money-dashboard-widget-events), which includes all the Connect Widget's widget events. * If integrating the Connections Widget, you must create listeners for all the [Connections Widget events](#connections-widget-events), which includes all the Connect Widget's events. * If integrating the Mini Finstrong Widget, you must create listeners for all the [Mini Finstrong Widget's events](#mini-finstrong-widget-events). ```html Line focusing example focus={6-20} theme={null} ``` ### Money Dashboard Deep Linking Configure the Money Dashboard Widget to deep link other embedded mini widgets to their full views. For example, selecting the **View All** button on the Mini Spending Widget should redirect the user to the full Spending Widget within the Money Dashboard. Similarly, clicking the call-to-action (CTA) button on any embedded mini widget should take the user to its corresponding full view. To create a deep link, use the Platform API's [request widget URL](/api-reference/platform-api/reference/request-widget-url) endpoint and follow these steps: 1. Set the `widget_type` field to `money_dashboard_widget`. 2. Set the `widget` field to your desired mini widget. 3. Create the necessary event listeners for the [Money Dashboard Widget events](#money-dashboard-widget-events). ## Integrate on a Mobile App To integrate the widget on a mobile app: 1. Create a backend endpoint that calls the Platform API to generate a [widget URL](/api-reference/platform-api/reference/request-widget-url). Set the `widget_type` to your desired widget; reference the list of [widget types](/api-reference/platform-api/reference/widgets#widget-types) for the acceptable values. Include the `is_mobile_webview` field with a value of `true`. 2. Load the URL received from the previous request into a WebView. 3. Capture and parse URLs delivered via `window.location = "someurl"` calls for the [application events](#application-events). See [Events in Mobile WebViews](#events-in-mobile-webviews) for more details. 4. If you're integrating the Connections Widget or Mini Finstrong Widget, you'll need to capture and parse URLs for additional events. For more information, see the list of [widget events](#widget-events). ### Common Problems This section covers some common problems with loading a widget URL into a WebView. To embed our mobile widgets into a WebView, we require a device width of at least 320 pixels. Depending on the implementation of the WebView, smaller devices may not be provided the full width, leading to display issues. In order to have the benefit of the full responsive nature of our application, please don't restrict the available browser width by adding margins or padding. In apps that run in iOS 8 and later, MX only supports WKWebView. If you previously implemented UIWebView, update your implementation to use WKWebView. Apple recommends this. For more information, see Apple's developer documentation for [UIWebView](https://developer.apple.com/documentation/uikit/uiwebview) and [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview). By default, iOS adds additional padding to its WebViews, which sometimes causes problems. To fix this: 1. Select the WebView providing the widgets in your application and navigate to the size inspector. 2. Change the layout margins from `"Default"` to `"Explicit"`. 3. Update the left and right margins to `0`. 4. Ensure the width is at least 320 pixels. Whether using WebViews on Android or iOS, most browsers will have a default margin (set in the user agent stylesheet) on the body element when rendering the HTML page responsible for loading a widget. This margin is deducted from the total available width of the containing element, which will cause a problem. To fix this: 1. Determine the computed width available on the body element. The width available to the `iframe` can be confirmed by inspecting the `iframe` injected by MX and typing window\.innerWidth in the JavaScript console. The width available to the `iframe` must be at least 320 pixels. 2. Confirm the body and HTML elements have their padding and margin set to `0`. For mobile widgets to render correctly, the viewport must be set in a meta tag on the HTML page used to load the widget URL. The viewport is the size of the window through which a page is seen. It can be smaller or larger than the actual size of a page or device screen. On most mobile devices, the virtual viewport is larger than the actual screen size; web pages are rendered according to the viewport size, then shrunk down to the actual screen size. This helps when viewing pages that aren't optimized for mobile, but for pages that are optimized for mobile (like the mobile widgets), the viewport meta tag is used to guarantee that the page is rendered properly. Set a meta tag within the `` element as follows: ```html Example theme={null} ``` ## Widget Events When certain events are triggered in our UI, we send you a widget event. These events have the information you need to take action in your codebase in response to the event. If integrating on mobile through a WebView, an alternative to standard `postMessage` widget events is required. See [Events in Mobile WebViews](#events-in-mobile-webviews) for more information. Don't use widget events for keeping data in sync between platforms. [Webhooks](/resources/webhooks) are a more reliable way of coordinating events between your servers and MX servers. Widget events from MX have the following properties: * The `mx` field that lets you filter out widget events coming from MX. * The `type` field that identifies what the event represents at a high level. * The `metadata` object field that has information related to the `type`. The following is an example integration that lets you listen to the events we send: ```js Example Integration theme={null} function handleEvent(event) { if (event.data.mx) { // handle the mx post message using event.data.type and event.data.metadata. } } window.addEventListener('message', handleEvent) ``` ### Events in Mobile WebViews This section only applies if you are embedding the widget in a WebView. Because of the technical limitations of WebView-based widget integrations, an alternative to standard `postMessage` widget events is required if embedding the widget into a WebView. When requesting widget URLs using the Platform API or SSO API, you must include the `is_mobile_webview` field with a value of `true` in your request to access WebView event messages. In WebView integrations, you must capture the URLs delivered via `window.location = "someurl"` calls within the `iframe` and use the information provided in those calls to build the necessary logic for coordinating events. All MX URL message events will have the `mx://` prefix as well as the following format: `mx:///?metadata=`. The following is an example URL message: `mx://account/created?metadata="{'guid':'ACT-1'}"`. You must capture the URL, parse out the path and query string, then JSON-decode the `metadata` field. ### Application Events You must create listeners for our `postMessage` UI application events. #### Widget Load This event is triggered when the widget is loaded. ```json theme={null} { "type": "mx/load", "mx": true } ``` #### Widget Ping This event is used to keep the widget session alive. ```json theme={null} { "type": "mx/ping", "mx": true, "metadata": { "user_guid": "USR-123", "session_guid": "ANS-123" } } ``` #### Widget focusTrap This event is triggered when popover content which traps the focus onto a particular element is opened or closed, but only in the case that no other popover content is already open. This event is triggered by some drawers, menu buttons, and modals. ```json theme={null} { "type": "mx/focusTrap", "mx": true, "metadata": { "trapped": "true" } } ``` ### Money Dashboard Widget Events All Connect Widget events also apply to the Money Dashboard Widget. The following events are for the Money Dashboard Widget. #### Mini Widget Selected This event is triggered when a user selects a primary CTA, like **View Details**. ```json Example theme={null} { "type": "mx/moneyDashboard/miniWidgetClicked", "mx": true, "metadata": { "user_guid": "USR-123", "session_guid": "ANS-123", "member_guid": "MBR-123" } } ``` #### Mini Widget Call to Action Selected This event is triggered when a user selects a secondary CTA. ```json Example theme={null} { "type": "mx/moneyDashboard/miniWidgetSecondaryClicked", "mx": true, "metadata": { "user_guid": "USR-123", "session_guid": "ANS-123", "member_guid": "MBR-123" } } ``` ### Connections Widget Events You must create a listener for one event specific to the Connections Widget: the Member Deleted event. All [widget events](/connect/widget-events) that apply to the Connect Widget also apply to the Connections Widget. #### Member Deleted This event is triggered when a member has been deleted in the widget. ```json Example theme={null} { "type": "mx/connections/memberDeleted", "mx": true, "metadata": { "user_guid": "USR-123", "session_guid": "ANS-123", "member_guid": "MBR-123" } } ``` ### Mini Finstrong Widget Events The following events are for the Finstrong Mini Widget. #### Sufficient Data, Primary Action Selected This event is triggered when the user has enough data to generate a Finstrong health score and the primary action is selected. ```json Example theme={null} { "type": "mx/miniFinstrong/sufficientData/primaryAction", "mx": true, "metadata": { "user_guid": "USR-123", "session_guid": "ANS-123" } } ``` #### Insufficient Data, Primary Action Selected This event is triggered when the user doesn't have enough data to generate a Finstrong health score and the primary action is selected. ```json Example theme={null} { "type": "mx/miniFinstrong/insufficientData/primaryAction", "mx": true, "metadata": { "user_guid": "USR-123", "session_guid": "ANS-123" } } ``` # Create Custom Transaction Categories Source: https://docs.mx.com/products/experience/pfm/integration-guides/personalization/custom-categories While MX provides more than 100 default categories and subcategories, you can also create custom categories. For instance, someone with multiple pets could create a category for Rover, Spot, and Scooby. You can also break your hobbies into custom subcategories like music, woodworking, and disc golf. There are several things to keep in mind, however: * All custom categories must be subcategories of some existing parent category. **You can't create new parent categories**. In other words, custom categories must be nested under one of the default categories whose `is_default` field is `true`. * You can't create subcategories of subcategories; the parent of a custom category must be at the top level. In other words, its `parent_guid` field is `null`. * To list the custom categories for a user, you must use the [list all categories](/api-reference/platform-api/reference/categories) endpoint, which includes both default categories and custom categories. For custom categories, the `is_default` field will be `false`. Before creating a custom category, the end user will need to decide which parent category they want to use; the parent category must be both default (`is_default`: `true`) and top-level (`parent_guid`: `null`). They'll also need to provide a `name` for the custom category. You can also include the optional `metadata` and `skip_webhook` parameters; `metadata` allows you to store any information you choose about the new category (MX recommends structured data like JSON). The `skip_webhook` parameter prevents MX from sending an associated webhook if it has been configured. The MX Platform API doesn't offer webhooks related to custom categories. In the following example, you'll use `Shopping` (CAT-aad51b46-d6f7-3da5-fd6e-492328b3023f) as the parent for the new `Online Shopping` category. `Endpoint: POST /user/{user_guid}/categories` ```shell Request theme={null} curl -i -X POST 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/categories' \ -u 'client_id:api_key' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -d '{ "category": { "metadata": "Some metadata.", "name": "Online Shopping", "parent_guid": "CAT-aad51b46-d6f7-3da5-fd6e-492328b3023f" } }' ``` ```json Response theme={null} { "category": { "created_at": "2020-08-26T20:31:41Z", "guid": "CAT-3684d909-4b77-481c-99bf-8d87c6aa2c62", "is_default": false, "is_income": null, "metadata": "Super cool extra info.", "name": "Online Shopping", "parent_guid": "CAT-aad51b46-d6f7-3da5-fd6e-492328b3023f", "updated_at": "2020-08-26T20:31:41Z" } } ``` To use the new custom category, you can recategorize a single transaction or create a **transaction rule**. Transaction rules empower end users to automatically assign similar transactions to a specific category — in this case, a custom category. Every past and future transaction that meets the criteria set out in the rule will be put in the category you specify. For instance, you could create a rule that assigns every transaction from Amazon to the custom `Online shopping` category. Rules override MX's data enhancement. See our [separate guide that explains transaction rules in detail](/products/experience/pfm/integration-guides/personalization/transaction-rules). There will certainly be times when either you or the end user need to change the name of a category. In these cases, you'll want to use the [update custom category](/api-reference/platform-api/reference/categories) endpoint. If the custom category is associated with a transaction rule and then you change the `name`, **all the transactions associated with that rule will be updated with the new category name as well**. You can update the fields shown in the example. The one thing you **can't** change is the `parent_guid`. Provide at least one of the following parameters. If no parameters are supplied, a 400 Bad Request error will be returned. | Parameter | Required? | | :--------- | :-------- | | `metadata` | No | | `name` | No | `Endpoint: PUT /user/{user_guid}/categories` ```shell Request theme={null} curl -i -X PUT 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/categories/CAT-3684d909-4b77-481c-99bf-8d87c6aa2c62' \ -u 'client_id:api_key' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -d '{ "category": { "name": "Web shopping" } }' ``` ```json Response theme={null} { "category": { "created_at": "2020-08-26T20:31:41Z", "guid": "CAT-3684d909-4b77-481c-99bf-8d87c6aa2c62", "is_default": false, "is_income": null, "metadata": null, "name": "Web shopping", "parent_guid": "CAT-aad51b46-d6f7-3da5-fd6e-492328b3023f", "updated_at": "2020-08-26T22:29:03Z" } } ``` You can delete custom categories, but if you do, note it will influence some related transaction rule behavior. If the deleted category was associated with a rule, any transactions related to that rule will have their `category` field set to the **parent** of the deleted category. For example, if you had a rule that set all Amazon transactions to `Online Shopping`, but then deleted the `Online Shopping` category, all Amazon transactions would be set to the parent `Shopping`. `Endpoint: DELETE /users/{user_guid}/categories/{category_guid}` ```shell Request theme={null} curl -i -X DELETE 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/categories/CAT-3684d909-4b77-481c-99bf-8d87c6aa2c62' \ -u 'client_id:api_key' \ -H 'Accept: application/vnd.mx.api.v1+json' ``` # Custom Tags and Taggings for Transaction Personalization Source: https://docs.mx.com/products/experience/pfm/integration-guides/personalization/index Tags and taggings are two resources in the MX Platform API that, when used together, give end users more control over organizing their transactions. Tags are basically custom labels. Taggings are when you actually apply those labels to specific transactions. Together, they're a powerful tool for personalization, customization, and money management. This guide shows the process of creating a `tag` and applying it to a specific transaction with a `tagging` resource. It shows a somewhat simplified process to demonstrate the principle behind these two resources. With this information, create a flow that works well for your product. **INFO** All MX users have one default tag that doesn't need to be created: `Business`. First, start by creating a tag. A tag is a label that can be applied to a transaction. This doesn't actually attach this label to a transaction, it just creates the tag. To achieve true personalization, set up your app so that the end user provides the `name` included in the body of the request as shown in the following example. Note the tag's `guid` returned in the response. You'll need this for the next step. `Endpoint: POST /users/{user_guid}/tags` ```shell Request theme={null} curl -i -X POST 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/tags' \ -u 'client_id:api_key' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -d '{ "tag": { "name": "MY TAG" } }' ``` ```json Response theme={null} { "tag": { "guid": "TAG-aef36e72-6294-4c38-844d-e573e80aed52", "name": "MY TAG", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } } ``` After you create a tag, use it for tagging. This means you should actually apply the tag to a particular transaction. Using a `transaction_guid` and a `tag_guid`, create a `tagging` by making a simple request. As shown in this example, use the `tag_guid` from the last step and chose an arbitrary `transaction_guid`. In practice, you may not go straight from creating a `tag` to creating a `tagging`. You may need to use the [list tags](/api-reference/platform-api/reference/tags) endpoint to find the desired `tag_guid`, and one of the [list transactions](/api-reference/platform-api/reference/transactions) endpoint to find the desired `transaction_guid`. `Endpoint: POST /users/{user_guid}/taggings` ```shell Request theme={null} curl -i -X POST 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/taggings' \ -u 'client_id:api_key' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -H 'Content-Type: application/json' \ -d '{ "tagging": { "tag_guid": "TAG-aef36e72-6294-4c38-844d-e573e80aed52", "transaction_guid": "TRN-810828b0-5210-4878-9bd3-f4ce514f90c4" } }' ``` ```json Response theme={null} { "tagging": { "guid": "TGN-007f5486-17e1-45fc-8b87-8f03984430fe", "member_is_managed_by_user": true, "tag_guid": "TAG-aef36e72-6294-4c38-844d-e573e80aed52", "transaction_guid": "TRN-810828b0-5210-4878-9bd3-f4ce514f90c4", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } } ``` You've now created a tag and applied that tag to a transaction with a tagging. After you or the end user has done this many times, you might want to see a list of the user's taggings across all tags and transactions. You can do this with the list taggings endpoint, shown in the following example. `Endpoint: GET /users/{user_guid}/taggings` ```shell Request theme={null} curl -i 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/taggings/' \ -u 'client_id:api_key' \ -H 'Accept: application/vnd.mx.api.v1+json' ``` ```json Response theme={null} { "taggings": [ { "guid": "TGN-007f5486-17e1-45fc-8b87-8f03984430fe", "member_is_managed_by_user": true, "tag_guid": "TAG-aef36e72-6294-4c38-844d-e573e80aed52", "transaction_guid": "TRN-810828b0-5210-4878-9bd3-f4ce514f90c4", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 1, "total_pages": 1 } } ``` You and your end users will almost certainly want to see a list of all transactions associated with a particular tag. To do this, make a request to the [list tag transactions](/api-reference/platform-api/reference/transactions) endpoint. `Endpoint: GET /users/{user_guid}/tags/{tag_guid}/transactions` ```shell Request theme={null} curl -i 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/tags/TAG-40faf068-abb4-405c-8f6a-e883ed541fff/transactions' \ -u 'client_id:api_key' \ -H 'Accept: application/vnd.mx.api.v2+json' \ ``` ```json Response theme={null} { "transactions": [ { "category": "Mobile Phone", "category_guid": "CAT-b4789667-6acc-a112-975e-15746003ed61", "created_at": "2021-04-06T21:03:07Z", "date": "2021-04-06", "posted_at": "2021-04-07T12:00:00Z", "status": "POSTED", "top_level_category": "Bills & Utilities", "transacted_at": "2021-04-06T12:00:00Z", "type": "DEBIT", "updated_at": "2021-04-06T22:35:47Z", "account_guid": "ACT-82ac32b4-06e6-48a9-8440-17e49bb3d720", "amount": 70.62, "check_number_string": null, "currency_code": "USD", "description": "Verizon", "guid": "TRN-a9f17e04-d19a-4d63-943d-e0d8d8eedb49", "is_bill_pay": false, "is_direct_deposit": false, "is_expense": true, "is_fee": false, "is_income": false, "is_international": null, "is_overdraft_fee": false, "is_payroll_advance": false, "is_recurring": null, "is_subscription": null, "latitude": null, "localized_description": null, "localized_memo": null, "longitude": null, "member_guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa", "memo": null, "merchant_category_code": 0, "merchant_guid": "MCH-8324c248-85a9-7071-a29b-1a5b36b4697e", "original_description": "Verizon Wireless", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" }, { "category": "Financial", "category_guid": "CAT-6c7de3f8-de6c-7061-1dd2-b093044014bf", "created_at": "2021-04-06T21:03:08Z", "date": "2021-04-06", "posted_at": "2021-04-07T12:00:00Z", "status": "POSTED", "top_level_category": "Financial", "transacted_at": "2021-04-06T12:00:00Z", "type": "CREDIT", "updated_at": "2021-04-06T22:37:02Z", "account_guid": "ACT-4d6b39c7-c130-4279-b70b-e5c18d8a6cf2", "amount": 31.59, "check_number_string": null, "currency_code": "USD", "description": "Loan Payment", "guid": "TRN-9617ba2d-f4cb-491b-90c4-b2fd1369cd03", "is_bill_pay": false, "is_direct_deposit": false, "is_expense": true, "is_fee": false, "is_income": false, "is_international": null, "is_overdraft_fee": false, "is_payroll_advance": false, "is_recurring": null, "is_subscription": null, "latitude": null, "localized_description": null, "localized_memo": null, "longitude": null, "member_guid": "MBR-84ca0882-ad6c-4f10-817f-c8c0de7424fa", "memo": null, "merchant_category_code": 0, "merchant_guid": null, "original_description": "Loan Payment", "user_guid": "USR-11141024-90b3-1bce-cac9-c06ced52ab4c" } ], "pagination": { "current_page": 1, "per_page": 25, "total_entries": 2, "total_pages": 1 } } ``` Tags and taggings can also be updated or deleted. Check out the links given here for more details. For instance, if an end user wants to [rename a tag](/api-reference/platform-api/reference/tags), they can do so while still preserving all the tagging relationships they've created. Or they can [update a tagging](/api-reference/platform-api/reference/taggings) to assign a different tag to a transaction. [Deleting a tag](/api-reference/platform-api/reference/tags) will also delete every tagging which references it. [Deleting a tagging](/api-reference/platform-api/reference/taggings) only removes that specific application of the tag to a transaction. # Using Transaction Rules for Automatic Categorization Source: https://docs.mx.com/products/experience/pfm/integration-guides/personalization/transaction-rules Transaction rules empower end users to automatically assign a chosen category to all transactions that match a specific description — even if that category differs from the one assigned by MX's data enhancement. Every past and future transaction which matches the pattern will automatically be assigned to that category. Rules have a string used to find matching transactions (`match_description`), a category that the transactions will be put into (`category_guid`), and an optional `description` that overwrites the transaction's original description. This guide will take you through the process of creating, updating, and deleting a transaction rule. ## 1. Create a Rule First, you'll need to create a new transaction rule — but keep a few things in mind: * When an end user creates a rule, the MX Platform will find all past and future transactions that match the `match_description` you provide. The category and description of **all** matching transactions will then change to those provided by the end user. * The end user will decide on the category and optional description. The category can be either a default MX category (accessible through the [list default categories](/api-reference/platform-api/reference/categories) endpoint) or a custom category created by the end user (accessible through the [list all categories](/api-reference/platform-api/reference/categories) endpoint). You must determine the best `match_description`. * Matching is always performed between the `match_description` and the **current transaction description**. If a transaction's description has been changed, it's the current transaction description that will be compared, not any previous or original description. If a rule updates the description of a transaction, and then you create another rule that matches the updated transaction description, that transaction will be associated with the **newer** rule — including updating to whatever the new rule's description specifies. * If you try to create a rule that has the same `match_description` as an existing rule on the same `user` object, a `409 Conflict` error will be returned. `Endpoint: POST /users/{user_guid}/transaction_rules` ```shell Request theme={null} curl -i -X POST 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/transaction_rules' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -u 'client_id:api_key' \ -H 'Content-Type: application/json' \ -d '{ "transaction_rule": { "category_guid": "CAT-b1de2a04-db08-b6ed-f6fe-ca2f5b11c2d0", "description": "Wal-mart food storage", "match_description": "Wal-mart" } }' ``` ```json Response theme={null} { "transaction_rule": { "category_guid": "CAT-b1de2a04-db08-b6ed-f6fe-ca2f5b11c2d0", "created_at": "2018-10-02T22:00:50Z", "description": "Wal-mart food storage", "guid": "UTR-a080e0f9-a2d4-4d6f-9e03-672cc357a4d3", "match_description": "Wal-mart", "updated_at": "2018-10-02T23:54:40Z", "user_guid": "USR-22fc3203-b3e6-8340-43db-8e50b2f56995" } } ``` ## Automatic Creation The MX system automatically creates rules under certain conditions. An automatic rule won't be created if the transaction is already associated with an existing rule. * If the end user changes either the category or description of similar transactions **three times**, a rule will be created with the following attributes: * `match_description` will be set to the original transaction description. * `category_guid` will be the category set by the end user. * `description` will be the one set by the end user, if applicable. ## 2. Update a Rule End users may want to change something about their rule, such as the category or description. The [update transaction rule](/api-reference/platform-api/reference/transaction-rules) endpoint accomplishes this. When updating a rule: * When the `category_guid` or `description` is updated, **all** transactions associated with the rule (past and future) will have the change applied. * However, updating the `match_description` has no effect on existing associated transactions; instead, the rule will be applied to **future** transactions according to the new `match_description`. `Endpoint: PUT /users/{user_guid}/transaction_rules/{transaction_rule_guid}` ```shell Request theme={null} curl -i -X PUT 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/transaction_rules/UTR-a080e0f9-a2d4-4d6f-9e03-672cc357a4d3' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -u 'client_id:api_key' \ -H 'Content-Type: application/json' \ -d '{ "transaction_rule": { "category_guid": "CAT-b1de2a04-db08-b6ed-f6fe-ca2f5b11c2d0", "description": "Wal-mart food storage", "match_description": "Wal-mart" } }' ``` ```json Response theme={null} { "transaction_rule": { "category_guid": "CAT-b1de2a04-db08-b6ed-f6fe-ca2f5b11c2d0", "created_at": "2018-10-02T22:00:50Z", "description": "Walmart", "guid": "UTR-a080e0f9-a2d4-4d6f-9e03-672cc357a4d3", "match_description": "Wal-mart", "updated_at": "2018-10-02T23:54:40Z", "user_guid": "USR-22fc3203-b3e6-8340-43db-8e50b2f56995" } } ``` ## 3. Delete a Rule To delete a transaction rule, use the [delete transaction rule](/api-reference/platform-api/reference/transaction-rules) endpoint. `Endpoint: DELETE /users/{user_guid}/transaction_rules/{transaction_rule_guid}` ```shell Request theme={null} curl -i -X DELETE 'https://int-api.mx.com/users/USR-11141024-90b3-1bce-cac9-c06ced52ab4c/transaction_rules/UTR-a080e0f9-a2d4-4d6f-9e03-672cc357a4d3' \ -H 'Accept: application/vnd.mx.api.v1+json' \ -u 'client_id:api_key' ``` # Notifications Source: https://docs.mx.com/products/experience/pfm/notifications When using our Personal Finance Management widgets, users can receive a variety of different notifications related to their account activity. The following information explains each notification, the supported delivery channels, and notification timing. There are two types of notifications: * **System** notifications. These allow the user to interact with the system. Examples of this are the Email Verification and Password Reset notifications. * **Alert** notifications. These inform the user when their data enters an uncommon state. Examples of this are the Low Account Balance and Large Expense notifications. **INFO** If you're looking to create your own notifications, see [Webhooks](/resources/webhooks/notifications). Our notifications can use one or more of the following delivery channels: * Email * SMS * In-app * Push Some notifications don't use every delivery channel. ## How To Configure Delivery Channels **Clients** can contact MX to opt out of delivery channels (email, SMS, in-app) or specific notifications for all of their users. **Users** can, if using the Master Widget, select **Settings** > **Notifications** to: * Opt out of a notification. * Opt out of a delivery channel for all notifications. * Opt out of a delivery channel for a single notification. For example, a user may only want to receive the Large Account Deposit notification on SMS and not on email. * Toggle the accounts used within the Payment Reminder, Low Account Balance, Large Deposit, Large Expense, and Fee Charge notifications. For example, a user may only want to receive the Low Account Balance notification for one of their connected accounts. * Edit thresholds within some notifications. These thresholds are specified in [Alert Notifications](#alert-notifications). ## Alert Notifications These notifications are available through all delivery channels. The user can disable these notifications and customize the delivery channels they're sent through. | Notification Name | Description | Copy | Channel(s) | | :------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------- | | Exceeded Budget | Notifies the user that they've exceeded a budget. | "You've exceeded your `category_name` budget by `budget_exceeded_amount`" | email, SMS, push, in-app | | Fee Charged | A fee was charged on an account. Shows the account the fee was charged to and the fee amount. Users can choose which accounts trigger this notification. If sent as an email, contains a **Log In To Account** CTA. | "You have been charged a `transaction_amount` fee `truncated_description` to your `truncated_account_name` account." | email, SMS, push, in-app | | Goal Progress | Notifies the user when they have contributed to or reached a milestone (25%, 50%, 75%, 100%) within a goal they set. | Varies based on the conditions. See [Goal Progress table](/products/experience/pfm/notifications#goal-progress). | email, SMS, push, in-app | | International Transaction | An international transaction was detected. Shows the transaction amount, which account was charged, and the transaction date. If sent as an email, contains a **Log In To Account** CTA. | "Your `truncated_account_name` account was charged `transaction_amount` by an international merchant `truncated_transaction_description` on `shortened_transaction_date`." | email, SMS, push, in-app | | Large Deposit | A deposit exceeded a configurable threshold. Shows the account the deposit was made to and the amount. Users can choose which accounts trigger this notification and customize the threshold for each account. If sent as an email, contains a **Log In To Account** CTA. Triggers when MX receives the transaction, regardless of status. | Varies based on the conditions. See the [Large Deposit Notification table](/products/experience/pfm/notifications#large-deposit). | email, SMS, push, in-app | | Large Deposit (posted) | Same as **Large Deposit**, but only triggers when the transaction status is POSTED. | Varies based on the conditions. See the [Large Deposit Notification table](/products/experience/pfm/notifications#large-deposit). | email, SMS, push, in-app | | Large Expense | An expense exceeded a set threshold. Shows the account the expense was made from and the expense amount. Users can choose which accounts trigger this notification and customize the threshold for each account. If sent as an email, contains a **Log In To Account** CTA. | Varies based on the conditions. See the [Large Expense Notification table](/products/experience/pfm/notifications#large-expense). | email, SMS, push, in-app | | Low Account Balance | The balance of an account has dropped below a threshold. Users can choose which accounts trigger this notification and customize the threshold for each account. This notification won't trigger again until the account exceeds the threshold again. | "Your account balance is getting low on `X number` accounts." | email, SMS, push, in-app | | Payment Reminder | Notifies the user of the amount, related account, and date that a payment is due. Users can choose which accounts trigger this notification and customize the payment's due date for each account. | Varies based on the conditions. See the [Payment Reminder table](/products/experience/pfm/notifications#payment-reminder). | email, SMS, push, in-app | | Projected to Exceed Budget | Notifies the user that they're projected to exceed a budget. | "You're projected to spend `budget_overage_projection` more than you've budgeted for `category_name`. You've already spent `budget_spent` of `budget_amount`." | email, SMS, push, in-app | ### Goal Progress | Header Text | Body Text | Conditions | | :------------------------- | :-------------------------------------------------------------------------------------------------------- | :------------------------- | | "GOOOOAAAAL!" | "You rock! You achieved your `goal_name` goal. Feels pretty good, right?" | When the goal is met | | "Just around the corner!" | "You're at 75% of your `goal_name` goal. At this rate, you'll be done in no time!" | When the goal is 75% met | | "Halfway there!" | "You're at 50% of your `goal_name` goal. Keep going and you'll be finished before you know it!" | When the goal is 50% met | | "You're well on your way!" | "You're 25% of the way to achieving your `goal_name` goal. Keep up the good work!" | When the goal is 25% met | | | "Good work on that `contribution_amount` contribution to your `goal_name` goal. Every little bit counts!" | When the goal is any % met | ### Large Deposit | Text | Conditions | | :---------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------- | | "There is a pending payment of `transaction_amount` `truncated_description` for your `truncated_account_name` account." | If a pending transaction exists in a payment account | | "There is a pending deposit of `transaction_amount` `truncated_description` in your `truncated_account_name` account." | If a pending transaction exists in a non-payment account | | "A payment of `transaction_amount` `truncated_description` was made to your `truncated_account_name` account." | If a posted transaction exists in a payment account | | "`transaction_amount` `truncated_description` was deposited into your `truncated_account_name` account." | If a posted transaction exists in a non-payment account | ### Large Expense | Text | Conditions | | :-------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------- | | "There is a pending transaction for `transaction_amount` `truncated_transaction_description` in your `truncated_account_name` account." | If a pending transaction exists in the account | | "`transaction_amount` `truncated_transaction_description` was spent from your `truncated_account_name` account." | If a posted transaction exists in the account | ### Payment Reminder | Text | Conditions | | :---------------------------------------------------------------------------------------------------------- | :-------------------------------------------------- | | "A `formatted_minimum_payment` payment for `truncated_account_name ` is due on `shortened_payment_due_at`." | If an account has a minimum payment and due date | | "A `formatted_minimum_payment` payment for `truncated_account_name ` is due soon." | If an account has a minimum payment but no date | | "A payment for `truncated_account_name ` is due on `shortened_payment_due_at`." | If an account has no minimum payment but a due date | | "A payment for `truncated_account_name` is due soon." | If an account has no minimum payment or due date | ## System Notifications The user **can't** disable these notifications or customize the delivery channels they're sent through. | Notification Name | Description | Copy | Channel(s) | | :-------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------- | | Device Created | Sent when the user links a mobile device to their account. | "Device Created" | email | | Device Deleted | Sent when the user unlinks a mobile device from their account. | "A device was deleted from your account: `device.name` `device.make` `device.model`" | email, in-app | | Email Verification | Sent when a user's account is created. | "Press the button below to verify your email address with `client_product_name`. Once verified, you'll start to receive email notifications based on your preferences." | email, in-app | | Email Verified | Sent after the user has verified their email through the Email Verification notification. | "Email Verified" | email, in-app | | Password Changed | Sent when the user confirms a new password and selects Save Password. | "Your password was recently changed." | email, in-app | | Password Reset Token | Sent when the user requests to reset their password. This notification contains a reset token the user must use to log in. This token lasts for an hour. | "Your `client_product_name` reset token is: `password_reset_token`." | email, SMS, in-app | | SMS Verification | Sent when the user links a mobile device. Contains a verification code. | "Your `client_product_name` device registration code is: `registration_code`" | SMS, in-app | | SMS Welcome Message | Informs the user that they'll receive periodic updates about their accounts. Allows users to text HELP for help or STOP to unsubscribe. Sent when the user verifies their phone number. | "Welcome to `client_product_name`! You'll receive periodic updates about your accounts, message and data rates may apply. Text HELP for help or STOP to unsubscribe." | SMS | | Verification Confirmation Message | Lets the user confirm enrollment to future SMS messages by replying YES. | "For your protection, `client_product_name` will only send you notifications regarding your finances when you confirm your enrollment by replying YES to this message." | SMS | | Welcome New User | Sent when the user verifies their email. | "`user_name` - `client_name` Welcomes You!" | email, in-app | ## Insight Notifications Users can now get timely [notifications](/products/experience/insights/#insight-notifications) from our Financial Insights for over twenty insights. Notifications are delivered through any of our available channels (in-app, SMS, push notifications, or email). See the [insights documentation](/products/experience/insights/#insight-notifications) for the list of available insights and work with your MX representative to turn them on. ## Notification Timing The following notifications are sent on any delivery channel without delay: * Device Created * Email Verification * Email Verified * Password Changed * Password Reset Token * SMS Verification * SMS Welcome Message * Welcome New User All other notifications, for email and SMS, are timed in intervals. Every five minutes, these notifications are grouped by notification type and then sent to the user. For example, a user may receive three fee charges. After five minutes have passed since the last batch of notifications were sent, the notifications reflecting the fee charges are grouped together and delivered to the user as one notification. # Accounts Widget Overview Source: https://docs.mx.com/products/experience/pfm/widget-overviews/accounts-widget The Accounts Widget shows account balances, recent transactions, and connection status for all linked accounts in one place. You can link accounts from most financial institutions. Full Accounts Widget A smaller view of the widget is available (mini widget). This view displays key information and drives traffic to the full widget for more details. Mini Accounts Widget This is how the widget appears without any data. Empty Accounts widget ## Key Features * Add accounts * Filter the accounts that show in the widget to focus on specific account types or institutions * View account details such as balances and transactions * Hide the account so it's no longer used in any widget. **Note:** hidden accounts can still have an active balance and receive transactions * Mark the account as a business, duplicate, or closed account. **Note:** closed accounts will no longer update balance or transaction information ## Add an Account 1. In Accounts, select **+ Add an Account**. 2. Search for a financial institution by its name or URL, or select one from the list of popular institutions. 3. Enter the requested login credentials. **INFO** Some institutions use multifactor authentication as part of the login process. ## Add a Manual Account Sometimes it's not possible to automatically bring in important financial information. It might be that one of your financial institutions doesn't support our software, or it might be that you paid off your home a decade ago, so there wouldn't be an online account with any information about it. In these situations, you need to add a manual account. This will allow you to keep track of things with a lot of value: property like a home or car, cash that isn't in a bank, a credit card that isn't compatible with the tools, a loan you're paying back to a friend. These are all critical to your finances, so add as many as you can. **INFO** If you have a mortgage or loan that was used to buy property like a home or a car, you should add a manual account for the full value of that home, car, and so on. That way, the app will keep track of the positive value of your assets and not just your debt. Manual accounts must be updated using manual transactions. To add a manual account: 1. Select **+ Add an Account**. 2. Select **+ Add Manual Account**. 3. Choose an account type. 4. Enter the details. 5. Select **Save**. ## Delete a Manual Account You may wish to delete a manual account from time to time, like when you sell a computer, car, or even your home. To delete a manual account: 1. In Accounts, select the account you wish to delete. 2. Select the menu button, then select **Delete Account**. 3. Type "DELETE." 4. Select **Delete**, or exit out of the delete box if you change your mind. ## Hide an Account If you don't want an account to be used in any of the available features or reports, you can choose to hide the account. This way, no information or transactions from that account will be factored into other tools. The data related to that account won't be deleted, however, and you can easily unhide an account. To hide an account: 1. In Accounts, select the account you want to hide. 2. Select the menu icon, then **Hide Account** from the dropdown. 3. A warning message will appear asking if you really want to hide the account. 4. Select **Hide** to confirm, or exit out of the box if you change your mind. Your hidden accounts will still be visible in Accounts. They'll show at the bottom of your accounts list, with their icons grayed out and marked "Hidden." ## Unhide an Account 1. In Accounts, select the account you want to unhide. 2. Select the menu icon, then **Unhide Account** from the dropdown. Your account data will appear and be included in other features. ## Merge Duplicate Accounts Duplicate accounts can appear when existing account connections are altered, such as when a financial institution changes the way they name accounts in their system, or when a lost or stolen credit card is replaced. When the account is relayed to the tools under a different name or identity than in the past, it's created as a new account. This type of duplication can be fixed by merging the accounts to ensure all data is retained. **WARNING** Merging an account can't be undone. To merge duplicate accounts: 1. Determine which account is the original. It will have a longer transaction history than the new account. 2. Select the original account. 3. Select the menu icon, then select **Mark as Duplicate** from the dropdown. 4. Select the duplicate account from the list of accounts that appears. A message will appear warning you that merging two accounts into one can't be undone. 5. Select **Merge**. 6. Type the word "MERGE" and select **Confirm** to complete the process. ## Resolve a Connection Error If there's a connection error on an account, you'll see an error icon over the account. To resolve a connection error: 1. Select the account with an error. A window will appear explaining the connection issue. 2. Follow the troubleshooting steps indicated for your connection. 3. If you're unable to reconnect the account, submit a support request. # Budgets Widget Overview Source: https://docs.mx.com/products/experience/pfm/widget-overviews/budgets-widget The Budgets Widget lets users create and manage their budgets. Full Budgets Widget A smaller view of the widget is available (mini widget). This view displays key information and drives traffic to the full widget for more details. Mini Budgets Widget This is how the widget appears without any data. Empty Budgets widget When a user first opens this widget, they have two options: * Select **Auto-generate Budgets**. This requires there to be transactions in the same category for the previous two months. * Select **Start From Scratch**. Once they've set up their budgets, users can view and edit them from the main budgets screen where each budget is represented by a colorful bubble. Each budget is also available in a list view. By default, users will see bubble budgets. The benefit of bubble budgets is that they allow users to see both the health and the impact of their budget categories. The larger the bubble, the more of someone's income it takes up. The color of each budget indicates whether a user is on track, nearing their budget limit, or over limit: * Green = under 80% * Yellow = from 80–100% * Red = over 100% ## Key Features * Auto-generate a budget based on average spending in each category over the last two months. This feature requires complete transaction data and works best when all accounts are connected and transactions are accurately categorized. * Manually create a budget * View budgets as bubbles that change color and size depending on the amount of money and if the budget has been exceeded or not * Filter the accounts shown * View bubble budgets of current or previous months * Select a bubble budget and: * View the transactions associated with the budget * Edit the budget's amount * Add a new sub-budget * Delete a budget * Modify monthly projected income * Recalculate budgets * Recalculation is based on the user's last two months of available data. If the recalculation is unsatisfactory, they can revert the changes For a list of all budget types, see [Transaction Categories](/api-reference/platform-api/reference/transactions#transaction-categories). ## Editing a Budget If a user increases a sub-budget to an amount greater than the main budget, the main budget amount will automatically increase. However, deleting or reducing a sub-budget won't affect the main budget. ## List View Your implementation determines where the list view appears: on the right side next to the bubble budgets, under the bubble budgets, or hidden under the bubble budgets. If the list view is hidden, a list view button will appear on the lower right. ## Recalculate Your Budgets If your budgets seem a bit off or you want to take advantage of automatically created budgets, you can use the recalculate feature. Recalculation is based on the last two months for which complete data is available. To recalculate your budgets: 1. In Budgets, select **Add New Budget**. 2. Select **Recalculate Budgets**. You'll see a preview of each newly created budget next to the previous budget amount. 3. Select **Save** if you want to keep these budgets, or **Undo** if you change your mind. ## Edit Projected Income 1. In Budgets, select the pencil icon under the green **Projected Income** bar. 2. Enter a new amount. 3. Select **Save**. # Cash Flow Widget Overview Source: https://docs.mx.com/products/experience/pfm/widget-overviews/cash-flow-widget The Cash Flow Widget helps users project how much cash they'll have for the next 30 days, based on the user's checking and savings accounts. This widget uses transactions that have been classified as [repeating transactions](/api-reference/platform-api/reference/transactions#repeating-transactions). Full Cash Flow Widget A smaller view of the widget is available (mini widget). This view displays key information and drives traffic to the full widget for more details. Mini Cash Flow Widget This is how the widget appears when there is no available data. Empty Cash Flow widget This is how the widget appears before accounts are connected. Zero Cash Flow widget ## Key Features * See each account's balance, projected income and expenses, and remaining cash for that month * Filter the accounts that show in the widget * Manage expenses and income by adding a recurring transaction, modifying an existing one, or removing one entirely **DEVELOPER NOTE** You can integrate this widget so that the "Manage Income" drawer is open by default. See the [`deep_link_params`](/api-reference/platform-api/reference/widgets) for more details. # Connections Widget Overview Source: https://docs.mx.com/products/experience/pfm/widget-overviews/connections-widget The Connections Widget lets end users manage their connected institutions and accounts. This widget can be accessed when the user selects **Manage Connections** from the Money Dashboard. **WARNING** This widget is **not the same** as the [Connect Widget](/connect/index). While the Connect Widget lets users connect their accounts, the Connections Widget helps users manage those connections and connect to their accounts. Full Connections Widget ## Key Features * View connected institutions and accounts within those institutions * Connect accounts and resolve connection issues * Disconnect an institution * Hide an account from use in other widgets * Merge accounts that show up twice * Mark an account as closed ## Filter Connections If you're using the `use_cases` parameter, you can set the widget to only show connections (members) with the `use_cases` you set when requesting the widget URL. To do this, set the: * `connections_use_case_filter` parameter to `true`. * `use_cases` parameter to `PFM` and/or `MONEY_MOVEMENT`, depending on what connections you want to show in the widget. **INFO** For more info on the `use_cases` parameter, see one of the following guides depending on the API you're using: * [Member Use Cases for Platform API](/api-reference/platform-api/overview/formats-requirements#member-use-cases) * [Member Use Cases for Nexus API](/api-reference/nexus/reference/01-members-overview) ### Example 1 In this example using the Platform API, the Connections Widget will only show connections (members) that have `PFM` set as a use case. A connection (`member`) could have its `use_cases` parameter set to `["PFM", "MONEY_MOVEMENT"]` and still display in the widget, since the `member` contains one of the use cases defined in the request. ```json theme={null} { "widget_url": { "widget_type": "connections_widget", "ui_message_version": 4, "use_cases": ["PFM"], "connections_use_case_filter": true } } ``` ### Example 2 In this example using the Platform API, the Connections Widget will only show connections (members) that have `PFM` or `MONEY_MOVEMENT` set as a use case. A connection (`member`) could have its `use_cases` parameter set to only `["MONEY_MOVEMENT"]` and still display in the widget, since the `member` contains one of the use cases defined in the request. ```json theme={null} { "widget_url": { "widget_type": "connections_widget", "ui_message_version": 4, "use_cases": ["PFM", "MONEY_MOVEMENT"], "connections_use_case_filter": true } } ``` # Debts Widget Overview Source: https://docs.mx.com/products/experience/pfm/widget-overviews/debts-widget The Debts Widget lets end users to see all their debts in one place and create an expedited payoff plan. Debts Widget This is how the widget appears when no data is available. Empty Debts Widget ## Key Features * View debts sorted by priority * For each account, see the balance, APR, final payment, and amount due * Select a debt payoff strategy * See and edit total monthly paydown * Filter the accounts shown ## Debt Payoff Strategies Users can select one of the following debt payoff strategies: * Fastest payoff first: Debts are ordered by which debt you will pay off soonest, based on balance, APR, and minimum payment. This ordering is considered the standard snowball method. * Highest interest first: Debts are ordered from your highest APR to the lowest APR. This ordering is often referred to as the "avalanche method"; it can save you more money over the life of the debt. * Lowest balance first: Debts are ordered by balance from lowest to highest. * Highest balance first: Debts are ordered by balance from highest to lowest. The list of debts are sorted by priority, which reflects the debt payoff strategy the user chooses. ## Change Debt Priorities 1. In Debts, select the **Fastest Payoff First** dropdown menu. 2. Select one of the four available options. The chart and all associated calculations will automatically update. ## Hide an Account From Debts 1. In Debts, select an account from the list under the detail window. 2. Select the three dots in the top right. 3. Select **Hide From Debts**. The account will be moved to the end of the list, grayed out, and won't be calculated in the chart. To reinclude an account: 1. Select the hidden account at the bottom of the debts list. 2. Select **Include Account**. ## Simulate Extra Payments Towards Debts 1. In Debts, select the **Total Monthly Paydown** dropdown. 2. Enter an additional amount in the **Extra Payment Toward Debt** box. The graph will readjust and show you how much you could save by putting extra money toward your debt. ## View Breakdown of the Snowball Method The snowball method is a common debt-reduction strategy. It allows you to pay debts off faster without increasing your monthly contribution toward debt. To use the snowball method, you should "roll over" your monthly minimum payments as each debt is fully repaid. In other words, when you're done paying off a debt, you'll take the monthly contribution to that debt and put it toward another. The total amount you pay each month stays the same, but the monthly contribution to each debt goes up progressively as they are paid off. This can help you get out of debt without the need for painful budget cuts. To view a breakdown of the snowball method, go to Debts, then select **What is Snowballing?**. # FinStrong Widget Overview Source: https://docs.mx.com/products/experience/pfm/widget-overviews/finstrong-widget The FinStrong Widget helps end users visualize their financial health. FinStrong Widget This is how the widget appears without any data. Empty FinStrong Widget A FinStrong score analyzes transaction history to figure out a user's spending, saving, and borrowing habits. The widget also gives users advice on how to improve their FinStrong score and move toward financial freedom. ## Key Features * View FinStrong Score with explanation * See average score by month * Filter FinStrong data by account * Add income, credit score, and connected accounts for an accurate score * View score indicators by spending, saving, and borrowing # Goals Widget Overview Source: https://docs.mx.com/products/experience/pfm/widget-overviews/goals-widget The Goals Widget helps end users plan and visualize their financial goals. Goals Widget A smaller view of the widget is available (mini widget). This view displays key information and drives traffic to the full widget for more details. Mini Goals Widget This is how the widget appears when no data is available. Empty Goals Widget Goals need to be associated with a specific account. More than one savings goal can be set on the same account, but they need to be ranked in order of priority. Ranking can be manually adjusted. If a user has multiple goals on one account, the highest-priority goal will get all the funds. Goals automatically update as users put money into a savings account or pay off a debt. Debt-type accounts (credit card, loan, line of credit, mortgage) will auto generate a debt goal. This is the only auto-generated goal type. Savings and retirement goals must be manually created. Goals appear as tiles in order of projected payoff date (unless manually prioritized) with the earliest to be paid off at the top. Each tile shows: * The account that's linked to the goal * % paid off * Progress bar of completion * Projected payoff date * Amount paid vs amount owed ## Key Features * Add a new goal (savings, debt payoff, retirement) * See goals, progress, and projected completion date * Hide a debt payoff goal * Delete a savings or retirement goal * Edit the details of a goal * Filter the accounts shown ## Goal Types There are 3 types of goals: Savings, Debt, and Retirement. Goals will be grouped along the top by goal type. Each goal type has a color assigned to make them easily identifiable. * Savings – Green * Debt Payoff – Blue * Retirement – Purple **DEBT GOALS** If a user has already connected a debt account, the widget will automatically pull in the information it needs to create a debt goal, including balance, APR, and minimum payments. The widget will use the minimum payment information to automatically calculate the date the debt will be repaid, however, users can add more to pay the debt off sooner. ## Create a Debt Payoff Goal 1. In Goals, select **Add a Goal**. 2. Choose the **Debt Payoff** goal type. This will bring up a window that lists all your debt accounts. 3. Check all the accounts you wish to track. 4. Select **Save**. Each debt account you selected will appear on the main page of Goals. ## Create a Retirement Goal 1. In Goals, select **Add a Goal**. 2. Choose the **Retirement** goal type. 3. Select your date of birth. If you've already entered personal information in Settings, your birthday will automatically be imported. 4. Choose the age at which you'd like to retire. The default is 65. 5. Enter the amount of money you'd like to have when you retire. 6. Select **Current Savings**. This will open a window from which you can choose your retirement accounts. 7. Check one or more retirement accounts. The total balance of selected accounts will be listed as your current savings. 8. Select **Add it Here** at the top of the panel if you need to connect another account to the software. 9. Select **Save**. 10. Select **Save** on the next window as well. The retirement goal will appear on the main page of Goals. If you aren't projected to achieve your desired retirement savings by your selected age — based on a 6 percent average rate of return — a blue "i" symbol will appear. ## Create a Savings Goal 1. In Goals, select **Add a Goal**. 2. Select the **Savings** goal type. 3. Select a more specific type of savings goal. You can choose from: emergency fund, automobile, college, home, recreational, vacation, electronic, or other. 4. Edit the details for the goal: give it a name and set an amount you would like to save for your goal. 5. Select the **Select an Account** field. A window will appear listing all your non-checking, non-debt accounts. 6. Select the account you'd like to use for this goal. 7. Select **Save**. The goal will appear on the main page of Goals. ## Change Your Debt Goal Priority 1. In Goals, select the dropdown menu on the right side of the panel. The default setting is **Fastest Payoff First**. 2. Choose your preferred priority method. You can choose from **Fastest Payoff First**, **Highest Interest First**, **Lowest Balance First**, and **Highest Balance First**. ## Change Your Goal Contribution 1. In Goals, under Manage Goals, open the monthly contribution window. Select **Savings**, **Debt Payoff**, or **Retirement**. 2. Select **Edit Contribution**. 3. Enter your new contribution amount. 4. Select **Save**. You'll see the new goal reflected in the goal summary at the bottom of the window. The projected date will also automatically update. ## Change Your Savings Priority 1. Select **Reorder**. 2. Drag the goals to your preferred order. # Widget Overviews Source: https://docs.mx.com/products/experience/pfm/widget-overviews/index You can integrate our [Money Dashboard Widget](/products/experience/pfm/widget-overviews/money-dashboard-widget), which is a container for PFM widgets that you can learn more about in later sections. If your use case won't use the Money Dashboard widget, you can coordinate with your MX representative to enable the newest versions of each individual widget. ## Widget Availability | | Full Widget | Mini Widget | Micro Widget | | :---------------------------- | :---------: | :---------: | :----------: | | Accounts Widget | ✓ | ✓ | | | Budgets Widget | ✓ | ✓ | | | Cash Flow Widget | ✓ | ✓ | | | Connect Widget | ✓ | ✓ | | | Connections Widget | ✓ | | | | Debts Widget | ✓ | | | | FinStrong Widget | ✓ | | | | Goals Widget | ✓ | ✓ | | | Investments Widget | ✓ | | | | Money Dashboard Widget | ✓ | | | | Net Worth Widget | ✓ | | ✓ | | Recurring Transactions Widget | ✓ | ✓ | ✓ | | Settings Widget | ✓ | | | | Spending Widget | ✓ | ✓ | | | Transactions Widget | ✓ | | | | Trends Widget | ✓ | ✓ | ✓ | # Investments Widget Overview Source: https://docs.mx.com/products/experience/pfm/widget-overviews/investments-widget The Investments Widget shows a user's investment accounts in one place and analyzes their investment data, offering insight into a portfolio's composition and market positioning. Investments Widget This is how the widget appears when no data is available. Empty Investments Widget ## Key Features * View investment account details like gains and losses * Visualize allocations * See total portfolio value **Overview** displays the total portfolio value and gain/loss, and then each linked account and its gain/loss percentage individually. Selecting the arrow next to an account will expand the row and display the holdings, cost basis, market value, and other data. Full Investments Widget overview **Allocation** shows asset distribution across categories such as: * Cash * U.S. stocks * Foreign stocks * U.S. bonds * Other asset classes Each asset can further show individual trade tickers for deeper insight. The chart shows the holdings plus the cash balance. Full Investments Widget desktop **Analysis** shows the portfolio positioning across market capitalization (small, mid, large) and valuation style (value, core, growth). Full Investments Widget analysis # Money Dashboard Widget Overview Source: https://docs.mx.com/products/experience/pfm/widget-overviews/money-dashboard-widget **INFO** The Money Dashboard widget is the new version of the `master_widget`. Users are redirected here when the Money Dashboard is enabled. The widget type remains the same in the widget URL request. To enable the Money Dashboard, coordinate with your Client Strategy Executive. The Money Dashboard Widget consolidates our various Personal Financial Management (PFM) widgets into one widget, providing users the ability to easily navigate among the widgets in the left navigation pane. The Dashboard page within the Money Dashboard widget provides a comprehensive financial overview at a glance. To integrate the widget, see [Integrate Any PFM Widget](/products/experience/pfm/integration-guides/integrate-a-widget). Dashboard ## Dashboard Customization You can customize the look and feel of your Money Dashboard. Contact your MX representative to make these changes.