Switch Kit

Switch Kit

Switch Kit

This Switch Kit Tutorial is for switching aggregators from Plaid to Envestnet | Yodlee.

Switch Kit Tutorial

This documentation provides a step-by-step guide to migrate from Plaid Link to Link Money, in order access Envestnet | Yodlee data.

There are two prerequisites to working with this guide:

These two sets of credentials are required for the Switch Kit demo to work as expected.

Clone Repository

Go to GitHub, clone, and install the Switch Kit repository. If you are not familiar with cloning repositories from GitHub, you can learn more.

Add Credentials

Once the repository is downloaded onto your machine, navigate to the folder and open it. Within, you will find a file tree. At the root of this file tree, within the repository folder, create a new file called .env and insert the following text:

PLAID_CLIENT_ID=""
PLAID_SECRET=""

LINK_MONEY_CLIENT_ID=""
LINK_MONEY_CLIENT_SECRET=""

Plug in your client IDs and client secrets for Plaid and Link Money from their respective portals. NOTE: You can use a Plaid sandbox or a Plaid development key pair.

Running the Plaid Application

If you’re interested to see how this application runs with Plaid Link, open a terminal at the repository level and run the commands listed here:

npm install --save 
npm run dev

This will run the application on http://localhost:3000. Navigate there to see how the demo application is running with your Plaid instance!

Generate an Authentication Token

Our first step to switch this demo app from Plaid to Link Money is to generate some user authentication. Unlike Plaid, Link Money does not use an SDK. However, requesting an authorization token for Link Money's Plaid-type endpoints is not very different from obtaining a Plaid token.

To authenticate with Plaid, the developer must:

  1. Initialize a new Plaid Client and pass it an object with a clientID and secret specific to the developer.
  2. Create a Link Token by calling the linkCreateToken method and passing it an object that includes further details, including an optional user property and a webhook property for receiving updates.

After making these calls, a Plaid developer receives an authentication token, which they can use to authenticate and launch Plaid Link.

Rather than going through an SDK, Link Money exposes an endpoint (POST https://dev-jhhgu9vc.auth0.com/oauth/token) that replicates Plaid token generation. All of the fields that Plaid uses for authentication should be included in the Link Money token request.

try {
    const { userId, itemId } = options;
    const data = {
      client_id: '{YOUR_CLIENT_ID}',
      client_secret: '{YOUR_CLIENT_SECRET}',
      audience: 'https://link-money-api/',
      grant_type: 'client_credentials',
      organization: '{YOUR_ORGANIZATION_ID}',
    };

		// use a userId string if you require a user token.
    if (userId) {
      data.userId = userId;
    
		// use an item_id string if you require an item token. 
    } else if (itemId) {
      data.item_id = itemId; 
    }
    
    const config = {
      method: 'post',
      url: 'https://dev-jhhgu9vc.auth0.com/oauth/token',
      headers: {
        'Content-Type': 'application/json',
      },
      data: data,
    }

    const createTokenResponse = await axios(config);
    const { data: tokenData } = createTokenResponse;
		const { access_token } = tokenData;
  } catch (error) {
    // any http errors will be surfaced here. 
  }

In the demo application, it makes the most sense to add this code to a backend route, as Link Money’s token signer does not allow calls from frontend-facing codebases. In the demo application, this code lives in /api/methods/index.js. Open that file, and add the following code:

  • Replace (const { userId, itemId } = options;)
export const getLinkMoneyToken = async (req, res, next) => {
	try {
	const { body } = req;
	    const { userId, itemId } = body;
	    const data = {
	      client_id: process.env.LINK_MONEY_CLIENT_ID,
	      client_secret: process.env.LINK_MONEY_CLIENT_SECRET,
	      audience: 'https://link-money-api/',
	      grant_type: 'client_credentials',
	      organization: 'switchkit',
	    };
	
			// use a userId string if you require a user token.
	    if (userId) {
	      data.userId = userId;
	    
			// use an item_id string if you require an item token. 
	    } else if (itemId) {
	      data.item_id = itemId; 
	    }
	    
	    const config = {
	      method: 'post',
	      url: 'https://dev-jhhgu9vc.auth0.com/oauth/token',
	      headers: {
	        'Content-Type': 'application/json',
	      },
	      data: data,
	    }
	
	    const createTokenResponse = await axios(config);
	    const { data: tokenData } = createTokenResponse;
			const { access_token } = tokenData;
			res.status(200).send({ access_token });
	  } catch (error) {
	    // any http errors will be surfaced here. 
			res.status(500).send({ message: error.message });
	  }
}

The code above adapts the original token function into an Express.js controller, which will be accessible from the front end demo application. The above code also adds the credentials from our env file, so that they can be accessed securely from the backend.

Now we only need to add a route to access this method, by altering /api/routes/index.js. Add getLinkMoneyToken to the import list from ../methods:

import {
  createLinkToken,
  getAccounts,
  exchangeForPublicToken,
  getTransactions,
	getLinkMoneyToken
} from '../methods';

And in the same file, create the route:

router.post("/link-money-token", getLinkMoneyToken);

This is all we need to do to make the Link Money authentication token available to the frontend of the demo application!

Replace the Plaid Link with the Link Money Gateway

Now we turn our attention to the frontend. Our Plaid Link code is generated by the file /pages/index.vue. Navigate there now. A large amount of the code in this file - like the createPlaidInstance method and the handler data property, will no longer be needed since we are removing the Plaid Link.

Our first step is to generate a Link Money token, using the backend code we just wrote. Fortunately, there’s a method in this file, generateToken, which is Plaid-specific. We can replace its contents and make it work with Link Money. Replace the function code for generateToken with the following code:

try {
    const request = await axios.post("/api/link-money-token", { userId: "your_user_id" });
    const { data } = request;
    const { access_token } = data;
    return access_token;
  } catch (error) {
    console.log(error);
    return null;
  }

Now let’s alter the contents of the openLink method. This method was opening the Plaid Link, but now we want it to open Link Money’s account linking application. Let’s change its contents:

async openLink() {
	const token = await this.generateToken();
	const linkMoneyGatewayUri = `https://linkmoney-gateway.fingoal.com/api/authenticate?token=${token}`;
	const redirectUri = 'http://localhost:3000/success';
	window.open(`${linkMoneyGatewayUri}&redirectUri=${redirectUri}`);
}

Make sure to mark the openLink function as async, otherwise the token will not generate in time.

We pass the token and a redirect URI for the demo application’s success page to the Link Money Gateway’s URL, and open the page. Follow the account linking process to link an account with Link Money! After you finish, you will redirect to the demo application’s success page.

For Link Money, the developer does not need to maintain the link accounts application - Link Money offers an out-of-the-box link accounts solution that requires only an access token from the call made in the previous step.

By linking users to linkmoney.fingoal.com with an access_token header, the Link Money Gateway will handle user authentication with their banking application, closing the Gateway when the user exits the process.

Access API Data

Now that we’ve linked an account, we can fetch data synchronously from Link Money in two ways:

  1. The Link Money portal inserts some account data in the callback to the demo application’s /success page.
  2. We can use API calls to get transactions and accounts.

Let’s start by looking at the account data in the callback URI. We can add methods to our success.vue file to process the return data:

async digestEvents() {
  const eventsString = this.$route.query.events;
  const events = JSON.parse(eventsString);

	if (!events || events.length === 0) {
    console.log("EVENTS_DATA_NOT_FOUND");
  }
  
  events.forEach((linkEvent) => { 
    const { user_id, item_id, institution, accounts } = linkEvent;
    this.items.push(item_id); 
    this.accounts.push(...accounts)
  });
},

Within the mounted method (which runs when the page loads), add some code to invoke the digestEvents function:

if (this.$route.query.events) {
  this.digestEvents();
}

Doing so, reload the page. If there’s events in the URI for the success page, you will see them load into the accounts table.

Now we can add further methods to fetch transactions from Link Money API. First, we need to create a new token. Notice that this token, unlike the last one, is item-specific. At this point in the flow, both Link Money’s Plaid and Plaid require that all authentication go through items, not users.

async generateToken(itemId) {
  try {
    const request = await axios.post("/api/link-money-token", { itemId: itemId });
    const { data } = request;
    const { access_token } = data;
    return access_token;
  } catch (error) {
    console.log(error);
    return null;
  }
},

With the item token ready, we can fetch transactions from Link Money API:

async getLinkMoneyTransactions(itemToken) {
	// note that you can use the same parameters here that you can for the Plaid request.
  const startDate = moment().subtract(30, 'days').format('YYYY-MM-DD');
  const endDate = moment().format('YYYY-MM-DD');

  const data = {
    start_date: startDate,
    end_date: endDate,
    options: {
      count: 250,
      offset: 0,
    },
  }

  const callConfig = { 
    method: "POST",
    url: `{YOUR_LINK_MONEY_API_URL}/v1/plaid/transactions/get`,
    headers: {
      'Content-Type': "application/json",
      Authorization: "Bearer " + itemToken
    },
    data
  }

  try {
    const transactionsResponse = await axios(callConfig);
    const { data: transactionData } = transactionsResponse;
		const { transactions } = transactionData;
		if (transactions.length === 0) {
      await this.handleError(error);
    } 
    return transactions;
  } catch(error) {
    await this.handleError(error);
  }
},

If you review the code above and compare it with the Plaid GET transactions code in /api/methods/index.js, you will see that the two code snippets are almost exactly identical. Substitute {YOUR_LINK_MONEY_API_URL} in the above snippet with the production Link Money API base URL:

https://linkmoney.fingoal.com

And then add the following iterative function to pull all the transactions for all items in the callback data into the demo application.

async getAllTransactions() {
  for (let i = 0; i < this.items.length; i++) {
    const itemId = this.items[i];
    const token = await this.generateToken(itemId);
    try {
      const transactions = await this.getLinkMoneyTransactions(token);
      this.transactions.unshift(...transactions)
    } catch (error) {
      console.log(error);
    }
  }
},

Finally, invoke the getAllTransactions method in the mounted function for the demo application,

await this.getAllTransactions()

And Link Money transactions associated with all linked accounts will appear in the website’s transactions table!

To review: While the base URL needed to be substituted, the /transactions/get endpoint remains the same, the method (POST) remains the same, the authentication scheme remains the same, and the response data scheme remains the same. The data that returns from this transactions endpoint conforms to the Plaid transaction model, so database and service changes to support Link Money data are not required. For a full roster of Plaid endpoints that Link Money offers, see Plaid Endpoints.

Process Initial Webhook

We have now completed the basics, and the Switch Kit demo application is now linking through Link Money and pulling data from both Plaid and Link Money! As a final additional caveat, though, let’s look at webhooks.

Since Link Money replicates the Plaid methodology, developers configure all webhooks by passing a callback URL of their choice as the webhook property of their call to generate an access token. Note that whatever value is passed into the webhook field on the POST token request will be interpreted as the desired callback URL and will rewrite previous values. This is in accord with Plaid's webhook methodology.

When a user links accounts for the first time, webhooks will trigger and send to all developers who are registered for webhooks on a particular user or item. The webhooks always signal that there's updated financial data available to be fetched from the APIs. These webhooks can contain any of the data updates described in Plaid Webhooks, but one of the first hooks to trigger off a new account linkage will contain this INITIAL_UPDATE webhook payload:

{
  "webhook_type": "TRANSACTIONS",
  "webhook_code": "INITIAL_UPDATE",
  "item_id": "wz666MBjYWTp2PDzzggYhM6oWWmBb",
  "error": null,
  "new_transactions": 19
}

These webhooks are exactly the same as those that Plaid sends. Both the fields and values from Plaid can be reliably expected from Link Money. In this case, the webhook notifies a developer that 19 new transactions are available for an Item of ID wz666MBjYWTp2PDzzggYhM6oWWmBb.

Plaid Schema Compatibility

Transactions

From Yodlee to Plaid

YODLEE 

{
	"date": "string",
	"sourceId": "string",
	"symbol": "string",
	"cusipNumber": "string",
	"highLevelCategoryId": 0,
	"detailCategoryId": 0,
	"description": : {
		"security": "string",
		"original": "string",
		"simple": "string",
		"consumer": "string"
		},
	"memo": "string",
	"settleDate": "string",
	"type": "string",
	"baseType": "CREDIT",
	"categorySource": "SYSTEM",
	"principal": {
		"amount": 0,
		"currency": "USD"
		},
	"lastUpdated": "string",
	"interest": {
		"amount": 0,
		"currency": "USD"
		},
	"price": {
		"amount": 0,
		"currency": "USD"
		},
	"commission": {
		"amount": 0,
		"currency": "USD"
		},
	"id": 0,
	"amount": {
		"amount": 0,
		"currency": "USD"
		},
	"checkNumber": "string",
	"quantity": 0,
	"valoren": "string",
	"isManual": true,
	"merchant": {
		"website": "string",
		"address": {
			"zip": "string",
			"country": "string",
			"address3": "string",
			"address2": "string",
			"city": "string",
			"sourceType": "string",
			"address1": "string",
			"street": "string",
			"state": "string",
			"type": "HOME"
		},
		"contact": {
			"phone": "string",
			"email": "string"
		},
		"categoryLabel": [
			"string"
		],
		"coordinates": {
			"latitude": 0,
			"longitude": 0
		},
		"name": "string",
		"id": "string",
		"source": "YODLEE"
	},
	"sedol": "string",
	"transactionDate": "string",
	"categoryType": "TRANSFER",
	"accountId": 0,
	"createdDate": "string",
	"sourceType": "AGGREGATED",
	"CONTAINER": "bank",
	"postDate": "string",
	"parentCategoryId": 0,
	"subType": "AUTH_HOLD",
	"category": "string",
	"runningBalance": {
		"amount": 0,
		"currency": "USD"
	},
	"categoryId": 0,
	"holdingDescription": "string",
	"isin": "string",
	"status": "POSTED"
}
PLAID

{
    "accounts": [{
        "account_id": "string",
        "balances": {
            "available": "number" | null,
            "current": "number" | null,
            "iso_currency_code": "string" | null,
            "limit": "number" | null,
            "unofficial_currency_code": "string" | null
        },
        "mask": "string" | null,
        "name": "string",
        "official_name": "string" | null,
        "subtype": "string" | null,
        "type": "string"
    }],
    "transactions": [{
        "account_id": "string",
        "amount": "number",
        "iso_currency_code": "string" | null,
        "unofficial_currency_code": "string" | null,
        "category": ["string"] | null,
        "category_id": "string" | null,
        "date": "string",
        "authorized_date": "string" | null,
        "location": {
            "address": "string" | null,
            "city": "string" | null,
            "region": "string" | null,
            "postal_code": "string" | null,
            "country": "string" | null,
            "lat": "number" | null,
            "lon": "number" | null,
            "store_number": "string" | null,
        },
        "name": "string",
        "merchant_name": "string" | null,
        "payment_meta": {
            "by_order_of": "string" | null,
            "payee": "string" | null,
            "payer": "string" | null,
            "payment_method": "string" | null,
            "payment_processor": "string" | null,
            "ppd_id": "string" | null,
            "reason": "string" | null,
            "reference_number": "string" | null
        },
        "payment_channel": "string",
        "pending": "boolean",
        "pending_transaction_id": "string" | null,
        "account_owner": "string" | null,
        "transaction_id": "string",
        "transaction_code": "string" | null,
        "transaction_type": "string"
    }],
    "item": {
        "available_products": ["string"],
        "billed_products": ["string"],
        "consent_expiration_time": "string" | null,
        "error": {
            "error_type": "string",
            "error_code": "string",
            "error_message": "string",
            "display_message": "string" | null,
            "request_id": "string",
            "causes": "array",
            "status": "number" | null,
            "documentation_url": "string",
            "suggested_action": "string"
        },
        "institution_id": "string" | null,
        "item_id": "string",
        "update_type": "string",
        "webhook": "string" | null
    },
    "total_transactions": "number",
    "request_id": "string"
}

Translations

Yodlee FieldPlaid FieldYodlee TypePlaid TypeCompatibleNotes
date
date
string
string
sourceId
string
sourceId is a unique ID that the provider site has assigned to the transaction. The source ID is only available for the pre-populated accounts. Pre-populated accounts are the accounts that the FI customers shares with Yodlee, so that the user does not have to add or aggregate those accounts.
symbol
string
cusipNumber
string
CUSIP numbers consist of nine characters (including letters and numbers) that uniquely identify a company or issuer and the type of financial instrument.
highLevelCategoryId
category_id
number
string
Both are aggregator specific but we will write a translation service to return the appropriate categoryId.
detailCategoryId
number
description
object
description.security
string
description.original
name
string
string
description.simple
string
description.consumer
string
isPhysical
payment_channel
boolean
string
Indicates online or physical transaction
memo
string
settleDate
string
type
accounts.type
string
string
baseType
accounts.subtype
string
stringnull
baseType has two values → [ CREDIT, DEBIT ] while subtype has a host of values like 401b, thrift savings plan etc
categorySource
string
principal
object
principal.amount
number
principal.currency
string
lateUpdated
string
interest
object
interest.amount
number
interest.currency
string
price
object
price.amount
number
price.currency
string
commission
object
commission.amount
number
commission.currency
string
id
transaction_id
number
string
The unique ID of the transaction. Like all Plaid identifiers, the transaction_id is case sensitive.
amount
object
amount.amount
amount
number
number
amount.currency
iso_currency_code, unofficial_currency_code
string
stringnull
checkNumber
string
quantity
number
valoren
string
isManual
boolean
merchant
object
merchant.website
string
merchant.address
location
object
object
merchant.address.zip
location.postal_code
string
stringnull
merchant.address.country
location.country
string
stringnull
merchant.address.address3
location.address
string
merchant.address.address2
location.address
string
merchant.address.city
location.city
string
stringnull
merchant.address.sourceType
string
merchant.address.address1
location.address
string
stringnull
Plaid only has one address field, so we should probably concat Yodlee's address1, 2, 3 and merchant.street to Plaid's loaction.address
merchant.address.street
location.address
string
stringnull
merchant.address.state
location.region
string
stringnull
merchant.address.type
string
merchant.contact
object
merchant.contact.phone
string
merchant.contact.email
string
merchange.categoryLabel
array
merchant.coordinates
object
merchant.coordinates.latitude
location.lat
number
numbernull
merchant.coordinates.longitude
location.lon
number
numbernull
merchant.name
merchant_name
string
stringnull
merchant.id
string
merchant.source
string
sedol
string
transactionDate
authorized_date
string
stringnull
categoryType
string
accountId
accounts.account_id, account_id
number
string
createdDate
date
string
string
sourceType
string
CONTAINER
string
postDate
string
parentCategoryId
number
subType
string
category
category
string
[string]null
Remember category in Plaid is array of string. Also, we'll need a translation service here to make sure we return the expected Plaid category.
runningBalance
accounts.balances
object
object
runningBalance.amount
accounts.balances.available
number
numbernull
runningBalance.currency
accounts.balances.iso_currency_code, accounts.balances.unofficial_currency_code
string
stringnull
categoryId
number
holdingDescription
string
isin
string
status
pending
string
boolean
location.store_number
stringnull
payment_meta
object
all payment_meta fields are for inter-bank transfers. we'll have to exclude these fields for now.
payment_meta.by_order_of
stringnull
payment_meta.payee
stringnull
payment_meta.payer
stringnull
payment_meta.payment_method
stringnull
payment_meta.payment_processor
stringnull
payment_meta.ppd_id
stringnull
payment_meta.reason
stringnull
payment_meta.reference_number
stringnull
string
pending_transaction_id
stringnull
account_owner
stringnull
The name of the account owner. This field is not typically populated and only relevant when dealing with sub-accounts.
accounts.balances.current
numbernull
accounts.balances.limit
numbernull
accounts.mask
stringnull
accounts.name
string
items.available_products
[string]
items.billed_products
[string]
items.consent_expiration_time
stringnull
items.error
object
items.error.error_type
string
items.error.error_code
string
items.error.error_message
string
items.error.display_message
stringnull
items.error.request_id
string
items.error.causes
array
items.error.status
numbernull
items.error.documentation_url
string
items.error.suggested_action
string
items.institution_id
stringnull
items.item_id
string
items.update_type
string
items.webhook
stringnull
errorCode
string
Yodlee: This is in case of 400 Bad Request
errorMessage
string
Yodlee: This is in case of 400 Bad Request
referenceCode
string
Yodlee: This is in case of 400 Bad Request
total_transactions
number
This can be accessed when you hit the Yodlee getTransactionsCount API
request_id
string

Accounts

Schema

YODLEE

{
  "account": [
    {
      "availableCash": {
        "amount": 0,
        "currency": "AUD"
      },
      "includeInNetWorth": true,
      "moneyMarketBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "enrollmentDate": "string",
      "estimatedDate": "string",
      "memo": "string",
      "guarantor": "string",
      "interestPaidLastYear": {
        "amount": 0,
        "currency": "AUD"
      },
      "lastUpdated": "string",
      "balance": {
        "amount": 0,
        "currency": "AUD"
      },
      "homeInsuranceType": "HOME_OWNER",
      "id": 0,
      "cash": {
        "amount": 0,
        "currency": "AUD"
      },
      "totalCreditLine": {
        "amount": 0,
        "currency": "AUD"
      },
      "providerName": "string",
      "valuationType": "SYSTEM",
      "marginBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "apr": 0,
      "availableCredit": {
        "amount": 0,
        "currency": "AUD"
      },
      "currentBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "isManual": true,
      "profile": {
        "identifier": [
          {
            "type": "NIE",
            "value": "string"
          }
        ],
        "address": [
          {
            "zip": "string",
            "country": "string",
            "address3": "string",
            "address2": "string",
            "city": "string",
            "sourceType": "string",
            "address1": "string",
            "street": "string",
            "state": "string",
            "type": "HOME"
          }
        ],
        "phoneNumber": [
          {
            "type": "HOME",
            "value": "string"
          }
        ],
        "email": [
          {
            "type": "PRIMARY",
            "value": "string"
          }
        ]
      },
      "escrowBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "nextLevel": "string",
      "classification": "OTHER",
      "loanPayoffAmount": {
        "amount": 0,
        "currency": "AUD"
      },
      "interestRateType": "FIXED",
      "loanPayByDate": "string",
      "faceAmount": {
        "amount": 0,
        "currency": "AUD"
      },
      "policyFromDate": "string",
      "premiumPaymentTerm": "string",
      "policyTerm": "string",
      "repaymentPlanType": "STANDARD",
      "availableBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "accountStatus": "ACTIVE",
      "lifeInsuranceType": "OTHER",
      "fullAccountNumber": "string",
      "premium": {
        "amount": 0,
        "currency": "AUD"
      },
      "aggregationSource": "SYSTEM",
      "overDraftLimit": {
        "amount": 0,
        "currency": "AUD"
      },
      "nickname": "string",
      "term": "string",
      "interestRate": 0,
      "deathBenefit": {
        "amount": 0,
        "currency": "AUD"
      },
      "address": {
        "zip": "string",
        "country": "string",
        "address3": "string",
        "address2": "string",
        "city": "string",
        "sourceType": "string",
        "address1": "string",
        "street": "string",
        "state": "string",
        "type": "HOME"
      },
      "cashValue": {
        "amount": 0,
        "currency": "AUD"
      },
      "holder": [
        {
          "identifier": [
            {
              "type": "NIE",
              "value": "string"
            }
          ],
          "gender": "string",
          "ownership": "PRIMARY",
          "name": {
            "middle": "string",
            "last": "string",
            "fullName": "string",
            "first": "string"
          }
        }
      ],
      "401kLoan": {
        "amount": 0,
        "currency": "AUD"
      },
      "homeValue": {
        "amount": 0,
        "currency": "AUD"
      },
      "accountNumber": "string",
      "createdDate": "string",
      "interestPaidYTD": {
        "amount": 0,
        "currency": "AUD"
      },
      "providerAccountId": 0,
      "collateral": "string",
      "dataset": [
        {
          "lastUpdated": "string",
          "updateEligibility": "ALLOW_UPDATE",
          "additionalStatus": "LOGIN_IN_PROGRESS",
          "nextUpdateScheduled": "string",
          "name": "BASIC_AGG_DATA",
          "lastUpdateAttempt": "string"
        }
      ],
      "runningBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "sourceId": "string",
      "dueDate": "string",
      "frequency": "DAILY",
      "maturityAmount": {
        "amount": 0,
        "currency": "AUD"
      },
      "associatedProviderAccountId": [
        0
      ],
      "isAsset": true,
      "principalBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "totalCashLimit": {
        "amount": 0,
        "currency": "AUD"
      },
      "maturityDate": "string",
      "minimumAmountDue": {
        "amount": 0,
        "currency": "AUD"
      },
      "annualPercentageYield": 0,
      "accountType": "string",
      "originationDate": "string",
      "totalVestedBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "rewardBalance": [
        {
          "expiryDate": "string",
          "balanceToReward": "string",
          "balanceType": "EXPIRING_BALANCE",
          "balance": 0,
          "description": "string",
          "balanceToLevel": "string",
          "units": "string"
        }
      ],
      "sourceAccountStatus": "IN_REPAYMENT",
      "derivedApr": 0,
      "policyEffectiveDate": "string",
      "totalUnvestedBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "annuityBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "accountName": "string",
      "totalCreditLimit": {
        "amount": 0,
        "currency": "AUD"
      },
      "policyStatus": "ACTIVE",
      "shortBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "lender": "string",
      "lastEmployeeContributionAmount": {
        "amount": 0,
        "currency": "AUD"
      },
      "providerId": "string",
      "lastPaymentDate": "string",
      "primaryRewardUnit": "string",
      "lastPaymentAmount": {
        "amount": 0,
        "currency": "AUD"
      },
      "remainingBalance": {
        "amount": 0,
        "currency": "AUD"
      },
      "userClassification": "BUSINESS",
      "bankTransferCode": [
        {
          "id": "string",
          "type": "BSB"
        }
      ],
      "expirationDate": "string",
      "coverage": [
        {
          "amount": [
            {
              "cover": {
                "amount": 0,
                "currency": "AUD"
              },
              "unitType": "PER_FAMILY",
              "type": "DEDUCTIBLE",
              "limitType": "IN_NETWORK",
              "met": {
                "amount": 0,
                "currency": "AUD"
              }
            }
          ],
          "planType": "PPO",
          "endDate": "string",
          "type": "VISION",
          "startDate": "string"
        }
      ],
      "cashApr": 0,
      "autoRefresh": {
        "additionalStatus": "SCHEDULED",
        "asOfDate": "string",
        "status": "ENABLED"
      },
      "oauthMigrationStatus": "IN_PROGRESS",
      "displayedName": "string",
      "fullAccountNumberList": {
        "paymentAccountNumber": "string",
        "unmaskedAccountNumber": "string"
      },
      "amountDue": {
        "amount": 0,
        "currency": "AUD"
      },
      "currentLevel": "string",
      "originalLoanAmount": {
        "amount": 0,
        "currency": "AUD"
      },
      "policyToDate": "string",
      "loanPayoffDetails": {
        "payByDate": "string",
        "payoffAmount": {
          "amount": 0,
          "currency": "AUD"
        },
        "outstandingBalance": {
          "amount": 0,
          "currency": "AUD"
        }
      },
      "paymentProfile": {
        "identifier": {
          "type": "REFERENCE_NUMBER",
          "value": "string"
        },
        "address": [
          {
            "zip": "string",
            "country": "string",
            "address3": "string",
            "address2": "string",
            "city": "string",
            "sourceType": "string",
            "address1": "string",
            "street": "string",
            "state": "string",
            "type": "HOME"
          }
        ],
        "paymentBankTransferCode": {
          "id": "string",
          "type": "ROUTING_NUMBER"
        }
      },
      "CONTAINER": "bank",
      "lastEmployeeContributionDate": "string",
      "lastPayment": {
        "amount": 0,
        "currency": "AUD"
      },
      "recurringPayment": {
        "amount": 0,
        "currency": "AUD"
      }
    }
  ]
}
PLAID

{
    "accounts": [
        {
            "account_id": "string",
            "balances": {
                "available": "number" | null,
                "current": "number" | null,
                "iso_currency_code": "string" | null,
                "limit": "number" | null,
                "unofficial_currency_code": "string" | null
            },
            "mask": "string" | null,
            "name": "string",
            "official_name": "string" | null,
            "subtype": "string" | null,
            "type": "string"
        }
    ],
    "item": {
        "available_products": ["string"],
        "billed_products": ["string"],
        "consent_expiration_time": "string" | null,
        "error": {
            "error_type": "string",
            "error_code": "string",
            "error_message": "string",
            "display_message": "string" | null,
            "request_id": "string",
            "causes": "array",
            "status": "number" | null,
            "documentation_url": "string",
            "suggested_action": "string"
        } | null,
        "institution_id": "string" | null,
        "item_id": "string",
        "update_type": "string",
        "webhook": "string" | null,
    },
    "request_id": "string"
}

Accounts

Yodlee FieldPlaid FieldYodlee TypePlaid TypeCompatibleNotes
availableCash
object
availableCash.amount
number
availableCash.currency
string
includeInNetWorth
boolean
moneyMarketBalance
object
moneyMarketBalance.amount
number
moneyMarketBalance.currency
string
enrollmentDate
string
estimatedDate
string
memo
string
guarantor
string
interestPaidLastYear
object
interestPaidLastYear.amount
number
interestPaidLastYear.currency
string
lastupdated
string
balance
balances
object
object
balance.amount
balances.available
number
numbernull
balance.currency
balances.iso_currency_code, balances.unofficial_currency_code
string
stringnull
homeInsuranceType
string
id
account_id
number
string
cash
object
cash.amount
number
cash.currency
string
totalCreditLine
object
totalCreditLine.amount
number
totalCreditLine.currency
string
providerName
string
valuationType
string
marginBalance
object
marginBalance.amount
number
marginBalance.currency
string
apr
number
availableCredit
object
availableCredit.amount
number
availableCredit.currency
string
currentBalance
object
currentBalance.amount
number
currentBalance.currency
string
isManual
boolean
profile
object
profile.identifier
array
profile.identifier[].type
string
profile.identifier[].value
string
profile.address[].zip
string
profile.address[].country
string
profile.address[].address3
string
profile.address[].address2
string
profile.address[].city
string
profile.address[].sourceType
string
profile.address[].address1
string
profile.address[].street
string
profile.address[].state
string
profile.address[].type
string
profile.phoneNumber
array
profile.phoneNumber[].type
string
profile.phoneNumber[].value
string
profile.email
array
profile.email[].type
string
profile.email[].value
string
escrowBalance
object
escrowBalance.amount
number
escrowBalance.currency
string
nextLevel
string
classification
string
loanPayoffAmount
object
loanPayoffAmount.amount
number
loanPayoffAmount.currency
string
interestRateType
string
loanPayByDate
string
faceAmount
object
faceAmount.amount
number
faceAmount.currency
string
policyFromDate
string
premiumPaymentTerm
string
policyterm
string
repaymentPlanType
string
availableBalance
object
availableBalance.amount
number
availableBalance.currency
string
accountStatus
string
lifeInsuranceType
string
fullAccountNumber
string
premium
object
premium.amount
number
premium.currency
string
aggregationSource
string
overDraftLimit
object
overDraftLimit.amount
number
overDraftLimit.currency
string
nickname
string
term
string
interestRate
number
deathBenefit
object
deathBenefit.amount
number
deathBenefit.currency
string
address
object
address.zip
string
address.country
string
address.address3
string
address.address2
string
address.city
string
address.sourceType
string
address.address1
string
address.street
string
address.state
string
address.type
string
cashValue
object
cashValue.amount
number
cashValue.currency
string
holder
array
holder.identifier
array
holder[].identifier[].type
string
holder[].identifier[].value
string
holder[].gender
string
holder[].ownership
string
holder[].name
object
holder[].name.middle
string
holder[].name.last
string
holder[].name.fullName
string
holder[].name.first
string
401kLoan
object
401kLoan.amount
number
401kLoan.currency
string
homeValue
object
homeValue.amount
number
homeValue.currency
string
accountNumber
string
This may be similar to "mask" of Plaid's account data, if it masks the account number to 4 digits
createdDate
string
interestPaidYTD
object
interestPaidYTD.amount
number
interestPaidYTD.currency
string
providerAccountId
number
collateral
string
dataset
array
dataset[].lastUpdated
string
dataset[].updateEligibility
string
dataset[].additionalStatus
string
dataset[].nextUpdateScheduled
string
dataset[].name
string
dataset[].lastUpdateAttempt
string
runningBalance
object
runningBalance.amount
number
runningBalance.currency
string
sourceId
string
dueDate
string
frequency
string
maturityAmount
object
maturityAmount.amount
number
maturityAmount.currency
string
associatedProviderAccountId
array
isAsset
boolean
principalBalance
object
principalBalance.amount
number
principalBalance.currency
string
totalCashLimit
object
totalCashLimit.amount
number
totalCashLimit.currency
string
maturityDate
string
minimumAmountDue
object
minimumAmountDue.amount
number
minimumAmountDue.currency
string
annualPercentageYield
number
accountType
subtype
string
stringnull
originationDate
string
totalVestedBalance
object
totalVestedBalance.amount
number
totalVestedBalance.currency
string
rewardBalance
array
rewardBalance[].expiryDate
string
rewardBalance[].balanceToReward
string
rewardBalance[].balanceType
string
rewardBalance[].balance
number
rewardBalance[].description
string
rewardBalance[].balanceToLevel
string
rewardBalance[].units
string
sourceAccountStatus
string
derivedApr
number
policyEffectiveDate
string
totalUnvestedBalance
object
totalUnvestedBalance.amount
number
totalUnvestedBalance.currency
string
annuityBalance
object
annuityBalance.amount
number
annuityBalance.currency
string
accountName
official_name
string
stringnull
totalCreditLimit
object
totalCreditLimit.amount
account.balances.limit
number
numbernull
totalCreditLimit.currency
account.balances.iso_currency_code
string
policyStatus
string
shortBalance
object
shortBalance.amount
number
shortBalance.currency
string
lender
string
lastEmployeeContributionAmount
object
lastEmployeeContributionAmount.amount
number
lastEmployeeContributionAmount.currency
string
providerId
string
lastPaymentDate
string
primaryRewardUnit
string
lastPaymentAmount
object
lastPaymentAmount.amount
number
lastPaymentAmount.currency
string
remainingBalance
object
remainingBalance.amount
number
remainingBalance.currency
string
userClassification
string
bankTransferCode
array
bankTransferCode[].id
string
bankTransferCode[].type
string
expirationDate
string
coverage
array
coverage[].amount
array
coverage[].amount[].cover
object
coverage[].amount[].cover.amount
number
coverage[].amount[].cover.currency
string
coverage[].amount[].unitType
string
coverage[].amount[].type
string
coverage[].amount[].limitType
string
coverage[].amount[].met
object
coverage[].amount[].met.amount
number
coverage[].amount[].met.currency
string
coverage[].planType
string
coverage[].endDate
string
coverage[].type
string
coverage[].startDate
string
cashApr
number
autoRefresh
object
autoRefresh.additionalStatus
string
autoRefresh.asOfDate
string
autoRefresh.status
string
oauthMigrationStatus
string
displayedName
name
string
string
fullAccountNumberList
object
fullAccountNumberList.paymentAccountNumber
string
This may be similar to "mask" of Plaid's account data, if it masks the account number to 4 digits
fullAccountNumberList.unmaskedAccountNumber
string
amountDue
object
amountDue.amount
number
amountDue.currency
string
currentLevel
string
originalLoanAmount
object
originalLoanAmount.amount
number
originalLoanAmount.currency
string
policyToDate
string
loanPayoffDetails
object
loanPayoffDetails.payByDate
string
loanPayoffDetails.payoffAmount
object
loanPayoffDetails.payoffAmount.amount
number
loanPayoffDetails.payoffAmount.currency
string
loanPayoffDetails.oustandingBalance.amount
number
loanPayoffDetails.oustandingBalance.currency
string
paymentProfile
object
paymentProfile.identifier
object
paymentProfile.identifier.type
string
paymentProfile.identifier.value
string
paymentProfile.address
array
paymentProfile.address[].zip
string
paymentProfile.address[].country
string
paymentProfile.address[].address3
string
paymentProfile.address[].address2
string
paymentProfile.address[].city
string
paymentProfile.address[].sourceType
string
paymentProfile.address[].address1
string
paymentProfile.address[].street
string
paymentProfile.address[].state
string
paymentProfile.address[].type
string
paymentProfile.paymentBankTransferCode
object
paymentProfile.paymentBankTransferCode.id
string
paymentProfile.paymentBankTransferCode.type
string
CONTAINER
type
string
string
lastEmployeeContributionDate
string
lastPayment
object
lastPayment.amount
number
lastPayment.currency
string
recurringPayment
object
recurringPayment.amount
number
recurringPayment.currency
string
items.item_id
Unique Id from Plaid. We will need to generate and send along.
balances.current
numbernull
balances.limit
numbernull
mask
stringnull
stringnull
N/A
items.available_products
[string]
A list of products available for the Item that have not yet been accessed.
N/A
items.billed_products
[string]
items.consent_expiration_time
stringnull
items.error
object
items.error.error_type
string
items.error.error_code
string
items.error.error_message
string
items.error.display_message
stringnull
items.error.request_id
string
items.error.causes
array
items.error.status
numbernull
items.error.documentation_url
string
items.error.suggested_action
string
items.institution_id
stringnull

Users

{
  "user": {
    "preferences": {
      "dateFormat": "string",
      "timeZone": "string",
      "currency": "AUD",
      "locale": "en_US"
    },
    "address": {
      "zip": "string",
      "country": "string",
      "address3": "string",
      "address2": "string",
      "city": "string",
      "address1": "string",
      "state": "string"
    },
    "loginName": "string",
    "name": {
      "middle": "string",
      "last": "string",
      "fullName": "string",
      "first": "string"
    },
    "id": 0,
    "roleType": "INDIVIDUAL",
    "email": "string",
    "segmentName": "string"
  }
}

No support for Users