Download OpenAPI specification:Download
Complete Financial Data via Link Money API
The Link Money API is a RESTful API that provides users access to their financial data, pulled in from over 17,000 financial institutions. Along with the Link Money Web Gateway, developers can securely link user financial accounts, pull financial data, and get the verification data required for transfer and payment initiation. Link Money API also provides developers with access to financial endpoints that emulate the API behavior of the major providers of aggregation and verification,like Plaid and Yodlee. By using Link Money along with the SwitckKit quickstart below, developers can migrate from one aggregation provider to another without fully refactoring their codebase.
Before starting the Link Money Quickstart guide, you must request access to a FinGoal developer account. FinGoal developer support will approve and reply with credentials within 24 hours of a valid request.
Link Money API also provides developers with access to financial endpoints that simulate the behavior of the major providers of aggregation and verification, including Plaid and Yodlee. By using Link Money API along with the SwitckKit documentation, developers can quickly and easily migrate off of one aggregation provider and onto another.
FinGoal instantly verifies and seamlessly connects your users' off-bank data. Your users can permission accounts once providing universal access for the institutions and the fintechs that serve them.
Link Money's Instant Account Verification (IAV) is a safe, secure, and fast way to instantly connect verified accounts in real time with reduced risk. Developers using IAV gain access to verified accounts which can be used to facilitate ACH transfers.
At the core of financial technology lies the ability to move money. Most modern fintech applications move money in some capacity - whether transferring to a savings account, creating a piggy bank, or funding an investment account, money movement makes fintechs run. Instant Account Verification, or IAV, offers developers a fast and secure method for retrieving the data required to initiate transfers on the user’s behalf.
While Link Money's automatic verification works for most use-cases, some users will prefer to manually verify their bank accounts. This guide describes the steps for initiating and verifying a user's account manually through Microdeposits. For more information on automatic verification, see Instant Account Verification (IAV). For getting started with the Link Money Gateway, see the Link Money Quickstart.
Microdeposits are a series of three small transactions (2 deposits and one withdrawal) of unspecified amounts that are sent to an account via a user-entered routing and account number pair. To initiate a verification, users must provide the routing and account number of the account they want verified. To complete the verification, the user must enter the correct amounts for each microdeposit that was made to their account. After they have completed these steps, verification data will be available for their account.
To start a micro-deposit verification, you may open the Link Money Gateway as you ordinarily do. You must provide one additional parameter, flow, which must be set to initiateMicroDeposits. This will force the Link Money Gateway to automatically open the Microdeposit verification flow.
let linkMoneyGatewayUri = `https://linkmoney-gateway-dev.fingoal.com/api/authenticate?token={YOUR_TOKEN}&flow=initiateMicroDeposits`;
<iframe src=linkMoneyGatewayUri></iframe>
As the Initiate Microdeposit screen appears, you will be required to enter the Routing Number and Account Number.
Once the data is entered, the next screen appears showing that verification has started. As soon as the user hits the close button, the Link Money Gateway will emit the microDepositId, completedFlow and events as a response.
When the user is finished entering their account and routing number into the gateway, Link Money will emit a microDepositId which you must save. This numeric ID will be required to open the gateway during the verification step. We recommend preserving the microDepositId in your datastore, as several days can elapse between the initialization and verification steps in the microdeposit flow.
window.addEventListener('message', function(event) {
if (event.origin !== 'https://linkmoney-gateway-webapp-dev.herokuapp.com') {
return;
}
const messageAsString = String(event.data).replace("event ", "").trim();
const messageAsJson = JSON.parse(messageAsString);
const { events, microDepositId, completedFlow } = messageAsJson;
// preserve the microDepositId
}, false);
Link Money is not notified when the user’s account has received microdeposits. We recommend re-engaging the user after 3 - 5 days, when the deposits will have certainly dropped into the user’s account. By re-opening the Link Money Gateway with the flow parameter set to verifyMicroDeposits and the microDepositId from step 2, the verification step can be commenced.
let linkMoneyGatewayUri = `https://linkmoney-gateway-dev.fingoal.com/api/authenticate?token={YOUR_TOKEN}&flow=verifyMicroDepositsµDepositId={YOUR_USERS_MICRODEPOSIT_ID}`;
<iframe src=linkMoneyGatewayUri></iframe>
At this point, if the verification is successful, you can pull the verified account data from Link Money API’s Verification Endpoints.
Once the steps above are completed and the user has successfully confirmed their account, you can fetch detailed account data from the Link Money API, including the account number and the routing number of the verified user.
To get detailed verified account data, pass in a providerAccountId query parameter, which corresponds the item_id returned in the events object from the previous step. You will also have to authenticate this request, but you can use the same token you created when opening the linking portal.
const axios = require("axios");
const baseUrl = "https://linkmoney-dev.fingoal.com/v1/yodlee/verification";
const response = await axios.get(`${baseUrl}?providerAccountId=${YOUR_ITEM_ID}`, {
headers: {
Authorization: `Bearer ${YOUR_TOKEN}`
}
);
const { verification } = response;
// process the verification from here.
Link Money offers the following account / routing number pairs for testing your application's microdeposits flow. When the Verify Microdeposits screen appears, the correct deposit amounts will always be 0.05 and 0.15. Keep in mind that it can take at least 5 minutes for the verification step to be ready in the Link Money Gateway.
| Account Number | Routing Number |
|---|---|
| 16441 | 999988181 |
| 16442 | 999761191 |
| 18769 | 999999992 |
| 16445 | 999999921 |
| 16477 | 999678831 |
| 16486 | 999991181 |
| 16487 | 999998281 |
Before starting the Link Money Quickstart guide, you must request access to a FinGoal developer account. You can expect FinGoal developer support to approve and reply with credentials within 24 hours of the request. These credentials are required to complete the quickstart.
This quickstart guide is designed to help you build a quick integration with Link Money from scratch. While following this guide, you will:
The very first step to integrate with Link Money is to generate an access token. Link Money uses Client Credentials Oauth2 to create a JWT (JSON Web Token). The JWT tells Link Money who you are, and whose data you want to access.
While Link Money has several different kinds of tokens (corresponding to different levels of access), we must first focus on creating a user-level access token. This token lets us access Link Money on the behalf of a single end-user.
The following code snippet demonstrates how to retrieve a Link Money access token with Node.js. By requesting a token that’s specific to a user (one which has a user ID field in its request data), you can authorize the Link Money Gateway on behalf of a user.
The important fields for the generate token call are:
client_id, which is issued in the Link Money developer portal.client_secret, which is issued in the Link Money developer portal. organization, which depends on your environment. If you are developing on behalf of a larger organization, ask the broad organization for the organization ID they have registered with Link Money.userId, which can be any string you want. In this flow, you do not necessarily need to create the user before creating their authentication token - use this token with the portal, and Link Money will do the rest.const axios = require("axios");
const createLinkMoneyToken = async (options) => {
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.
}
}
With a successfully generated user-specific access token, you have what you need to authorize a call to the Link Money Gateway, where your users can link their third party financial accounts for aggregation and verification. Several query parameters determine how the gateway will behave when the user is ready to exit the account linking process:
redirectUri query parameter that you provide. Good for web applications.deeplink query parameter that you provide. Good for native applications.redirectUri nor a deeplink parameter will cause the portal to default to the auto-close flow.const linkMoneyGatewayUri = `https://linkmoney-gateway-dev.fingoal.com/api/authenticate?token={YOUR_TOKEN}`;
const redirectUri = '{YOUR_REDIRECT_URI}';
// option A:
window.open(`${linkMoneyGatewayUri}&redirectUri=${redirectUri}`);
// option B (in the HTML):
<iframe src=linkMoneyGatewayUri></iframe>
From there your user can follow the Fastlink flow to link their accounts for either aggregation or verification, depending on which flow you specified.
Once a user has linked an account, you have several options for beginning their aggregation flow:
redirectUri in step 2, the gateway will redirect to your application with a query parameter called events. This contains data about the linked accounts, along with the item_ids of anything the user linked, for use in further authentication. See Plaid Endpoints for using the item_id to retrieve data. Link Money's Instant Account Verification (IAV) is a safe, secure, and fast way to instantly connect verified accounts in real time with reduced risk. Developers using IAV gain access to verified accounts which can be used to facilitate ACH transfers.
Some users will want or need to verify accounts manually, rather than using the instant verification methods. Link Money supports manual verification through microdeposits.
Microdeposits are a series of three small transactions (2 deposits and one withdrawal) of unspecified amounts (totalling to a net $0.00 chaarge) that are sent to an account specified by a user-entered routing and account number. To initiate a mincrodeposit verification, users provide the routing and account number of the account they want verified. To complete the verification, the user must enter the correct amounts for each microdeposit that was made to their account. After they have completed these steps, verification data will be available for their account.
To start a microdeposit verification, the user opens the Link Money Gateway. The developer may provide one additional query parameter, flow, which forces the portal to load the microdeposit initiation form. However, users are also always provided the option of manually verifying in a regular gateway session.
let linkMoneyGatewayUri = `https://linkmoney-gateway-dev.fingoal.com/api/authenticate?token={YOUR_TOKEN}&flow=initiateMicroDeposits`;
<iframe src=linkMoneyGatewayUri></iframe>
As the Initiate Microdeposit screen appears, the user will be required to enter a routing aumber and account number.
Once the data is entered, the next screen appears showing that verification has started.
When the user is finished entering their account and routing number into the gateway, Link Money's iFrame will emit a microDepositId which you must save (this ID is the same as the accountId for the manually-added account). This numeric ID will be required to open the gateway during the verification step. We recommend preserving the microDepositId in your datastore, as several days can elapse between the initialization and verification steps.
window.addEventListener('message', function(event) {
if (event.origin !== 'https://linkmoney-gateway-webapp-dev.herokuapp.com') {
return;
}
const messageAsString = String(event.data).replace("event ", "").trim();
const messageAsJson = JSON.parse(messageAsString);
const { events, microDepositId, completedFlow } = messageAsJson;
// preserve the microDepositId
}, false);
Link Money is not notified when the user’s account has received microdeposits. We recommend re-engaging the user after 3 - 5 days, when the deposits will have dropped into the user’s account. By re-opening the Link Money Gateway with the flow parameter set to verifyMicroDeposits and the microDepositId from step 2, the verification step can be commenced.
let linkMoneyGatewayUri = `https://linkmoney-gateway-dev.fingoal.com/api/authenticate?token={YOUR_TOKEN}&flow=verifyMicroDepositsµDepositId={YOUR_USERS_MICRODEPOSIT_ID}`;
<iframe src=linkMoneyGatewayUri></iframe>
At this point, if the verification is successful, you can pull the verified account data from Link Money API’s verification endpoints.
Link Money offers the following account / routing number pairs for testing your application's microdeposits flow. When the Verify Microdeposits screen appears, the correct deposit amounts will always be 0.05 and 0.15. Keep in mind that it can take at least 5 minutes for the verification step to be ready in the Link Money Gateway.
| Account Number | Routing Number |
|---|---|
| 16441 | 999988181 |
| 16442 | 999761191 |
| 18769 | 999999992 |
| 16445 | 999999921 |
| 16477 | 999678831 |
| 16486 | 999991181 |
| 16487 | 999998281 |
Traditionally, changing aggregators was nearly impossible. The demands of engineering time and resources derailed your roadmap. FinGoal has built a translation layer API that allows any engineering team to fully replace their current data aggregator in fewer than two sprints. The switch won't cause account links to break or outages for your users. Instead, it is an ongoing transition. When accounts need to be re-authenticated, the user will be prompted to verify those accounts.
This documentation provides a step-by-step guide for migrating from Plaid to Yodlee by way of Link Money. It is intended to be used with the Basic Switch App repository. In this demo, we will start with an extremely basic financial application built with Plaid. All it has is a Plaid Link and a summary page that shows account and transaction information. We will switch this application over to Link Money in a few simple steps.
This walkthrough is built for Node JS and uses the Nuxt application framework. If you are built for a different language or framework but wish to follow this switchkit demonstration, you will need a few architectural features for the demo to work:
.env file (for local development) or another secret store for credential management.To start this demo, you will need:
git clone https://github.com/FinGoal/basic-switch-app.git
cd basic-switch-app
npm install
.env file in the root directory of the project and enter your credentials for both Plaid and Link Money:PLAID_CLIENT_ID="{YOUR_PLAID_CLIENT_ID}"
PLAID_SECRET="{YOUR_PLAID_CLIENT_SECRET}"
LINK_MONEY_CLIENT_ID="{YOUR_LINK_MONEY_CLIENT_ID}"
LINK_MONEY_CLIENT_SECRET="{YOUR_LINK_MONEY_CLIENT_SECRET}"
Within the project directory, run the command to initialize the application:
npm run dev
Navigate to http://localhost:3000 to view the application. A button should appear prompting you to add an account. Click it to ensure that your Plaid Link is working properly. You may link an account if you wish to see how the rest of the application runs in Plaid.
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:
Client and pass it an object with a clientID and secret specific to the developer. 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.
We must place the authentication code in a backend route, as Link Money’s token-signing endpoint does not allow calls from frontend-facing appliocations. In the demo application, this code lives in /api/methods/index.js. Open that file, and add the following code:
export const createLinkMoneyToken = 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: 'testorg1',
};
// 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,
createLinkMoneyToken
} from '../methods';
And in the same file, create the route:
router.post("/link-money-token", createLinkMoneyToken);
This is all we need to do to make the Link Money authentication token available to the frontend of the demo application!
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.
Now that we’ve linked an account, we can fetch data synchronously from Link Money in two ways:
/success page. 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.
Link Money has two types of authentication: User-Scoped and Item-Scoped. A user is a single end user registered with the Link Money API, while an item represents a single login with a single financial institution.
Use a user-scoped token for:
User an item-scoped token for:
Link Money's Authentication endpoint is hosted at https://dev-jhhgu9vc.auth0.com/oauth/token.
You must include the following fields in every authentication request:
client_id, your client ID client_secret, your client secretaudience, which is always the value shown in the example below.grant_type, which is always the value shown in the example below.organization, which is unique to your environment and will be issued along with your other credentials. {
"client_id": "{YOUR_CLIENT_ID}",
"client_secret": "{YOUR_CLIENT_SECRET}",
"audience": "https://link-money-api/",
"grant_type": "client_credentials",
"organization": "{YOUR_ORGANIZATION_ID}"
}
To scope the payload for a user token, you must include a user-specific field, including: uid, userId, guid, or user_id. Note that when registering a user in the Link Money portal, you can use whatever user identifier you would like. We recommend using an identifier that your application already has. {
"client_id": "{YOUR_CLIENT_ID}",
"client_secret": "{YOUR_CLIENT_SECRET}",
"audience": "https://link-money-api/",
"grant_type": "client_credentials",
"organization": "{YOUR_ORGANIZATION_ID}",
"user_id": "{YOUR_USER_ID}"
}
To scope the payload for an item token, you must include an item-specific field, item_id.{
"client_id": "{YOUR_CLIENT_ID}",
"client_secret": "{YOUR_CLIENT_SECRET}",
"audience": "https://link-money-api/",
"grant_type": "client_credentials",
"organization": "{YOUR_ORGANIZATION_ID}",
"item_id": "{YOUR_ITEM_ID}"
}
Note that you may only scope the token by item or user. It is not possible to use both identifiers in a single token, and doing so may result in unexpected behavior.