Quickstarts
LinkMoney API
Aggregator Guides
FinSight API
Resources
Privacy
Developer Account
FinSight Quickstart
FinSightAPI is a set of tools that developers can use to add deep enrichment to transactions, accounts, and user records. The data that FinSightAPI returns can have many different uses, but the flow that developers should follow for using the API always consists of the same several steps:
- Request a FinGoal developer account.
- Get credentials for API access.
- Generate a FinSightAPI authentication token.
- Send transactions to FinSightAPI.
- Register for Webhooks.
- Request Enrichment.
Request a FinGoal Developer Account
Before we start a FinSightAPI integration, we need to generate some credentials. Like all other FinGoal APIs, FinSightAPI requires authentication for access. This means that developers will need to generate a credential pair. To get a credential pair, request a FinGoal developer account. You can expect FinGoal dev support to send you your credentials within 24 hours. You will use these credentials in the following steps.
Generate Auth Token
To generate your FinSight API Authentication Token:
With a client credentials pair, we are one step away from generating a JWT. JWT is short for JSON web token, which is short for “a web token written in JavaScript Object Notation format.” The JWT is, essentially, an encoded packet of authentication information that can only be verified by the same secret that was used to encode the token.
Let’s take a look at a request body for a FinSightAPI authentication token:
{
"client_id": "{YOUR_CLIENT_ID}",
"client_secret": "{YOUR_APPLICATION_SECRET}"
}
All we need to generate the authentication token we’ll be using for FinSightAPI is the credential pair we were issued. Now that the request body is prepared, we can direct a call to the FinSightAPI authentication endpoint and generate a token:
const headers = new Headers();
headers.append("Content-Type", "application/x-www-form-urlencoded");
const body = new URLSearchParams();
body.append("client_id", "{YOUR_CLIENT_ID}");
body.append("client_secret", "{YOUR_CLIENT_SECRET}");
const requestOptions = {
method: 'POST',
headers: headers,
body: body,
redirect: 'follow'
};
try {
const response = await fetch("https://findmoney-dev.fingoal.com/v3/authentication", requestOptions);
const data = response.json();
const { access_token } = data;
console.log({ access_token });
} catch(error) {
console.log('AUTHENTICATION_ERROR:', error);
}
In the code snippet above, we use the Node fetch
API to request an access token from FinSight API. We include the client_id
and client_secret
in the request body. After we make our request, we await the response and pull the access_token
out of the response body. If we do encounter an error, we make sure to log it. If everything goes correctly, though, we will receive the following JSON response from the API:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlEwWTRSRGcxTTBNd1JEWTJRamRETmpVNU4wVTFRalZGUJSQSJ9.eyJpc3MiOiJodHRwczovL2Rldi1qaGhndTl2Yy5hdXRoMaZXhSZGl2emY3eU5AY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vZmluc2lnaHRzLWFwaS5jb20vdjIiLCJpYTmFlQ2ZabzdjNHh2QUpWa0ZaZXhSZGl2emY3eU4iLCJzY29wZSI6InJlYWQ6dHJhbnNhY3Rpb25zIHdyaXRlOnRyYW5zYWN0aW9ucyB1cGRhdGU6dHJhbnNhY3Rpb25zIGRlbGV0ZTp0cmFuc2FjdGlvbnMgcmVhZDpjbGllbnQgcmVhZDp1c2VycyByZWFkOmFjY291bnRzIHdyaXRlOmFjY291bnRzIHJlYWQ6Zmluc2lnaHRzIHdyaXRlOnVzZXJzIHVwZGF0ZTp1c2VycyBwb3N0OnRyYW5zYWN0aW9ucyBnZXQ6Zmluc2lnaHRzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIiwicGVybWlzc2lvbnMiOlsicmVhZDp0cmFuc2FjdGlvbnMiLCJ3cml0ZTp0cmFuc2FjdGlvbnMiLCJ1cGRhdGU6dHJhbnNhY3Rpb25zIiwiZGVsZXRlOnRIiwicmVhZDp1c2VycyIsInJlYWQ6YWNjb3VudHMiLCJ3cml0ZTphY2NvdW50cyIsInJlYWQ6Zmluc2lnaHRzIiwid3JpdGU6dXNlcnMiLCJ1cGRhdGU6dXNlcnMiLCJwb3N0OnRyYW5zYWN0aW9ucyIsImdldDpmaW5zaWdodHMiXX0.JlaSkSXHxiIu-FpDs9LOLNIhDIKl7Q4qBCcwfncsDcJRgTbiaNJRuciWDMicN3kimEMBE9XTBZt3AVaT939MGugcynSnsFzN2BHqA32fy901VqNoVIalfDrGinwcbduSIVJNdDtkcCIvRJSB1mHIZYAylu1EpN-3-DJyTvAFoTh6xtNPd0WNGxtC6aQJ4-ijjOlbTyigYpammsr3e4xzLpfOat-wsxIk0RALgQ4we4EMGsPhgvhtw8DFX4ZHjc2bdnXRHJ-HP7JzmmiPFGln2cu7fil09bemOIkFBoSEtTCJCF-gmzdn_R3-FtuKuUMjCETcNufp9LJ9qwD_1rdSXw",
"scope": "read:transactions write:transactions update:transactions delete:transactions read:client read:users read:accounts write:accounts read:finsights write:users update:users post:transactions get:finsights",
"expires_in": 86400,
"token_type": "Bearer"
}
We can now use the access_token
in all subsequent calls to authenticate with FinSightAPI! Note, however, that all FinSightAPI tokens expire in 86,400 seconds - 24 hours. As such, you will need to regenerate the token daily. FinGoal recommends that you set up a cron job or similar system to regenerate the token on a timed basis.
Send Transactions to FinSightAPI
Now that we have an access_token, we can use it as our Authorization header for calls to the FinSight API. Don’t forget to prepend the string Bearer
to the header value, otherwise FinSightAPI will reject the call.
To make your first call include the access_token
in the header as a bearer token:
const headers = new Headers();
headers.append("Authorization", "Bearer {ACCESS_TOKEN}"
Almost all of the enrichment that FinSightAPI can generate today relies on transactions. So, let’s start integrating with FinSightAPI by posting a transaction! You may already have transactions in your system - FinSightAPI supports posting them without modification, so if you know where your transaction data is aggregated from, it’s very easy to start streaming transactions to FinSightAPI. You only need to add a type
header to your call:
// header and options code
headers.append("type", "mx");
const mxTransactions = [ { MX_TRANSACTION } ];
const body = { transactions: mxTransactions }
const requestOptions = {
method: 'POST',
headers: headers,
body: body,
redirect: 'follow'
}
try {
const response = await fetch("/v3/transactions", requestOptions);
const data = response.json();
console.log({ data });
} catch(error) {
console.log({ error });
}
If you don’t have an aggregator set up yet, or just want to see how the API processes data, here is a call that uses the simplest transaction record that FinSightAPI will accept:
Basic Transaction Schema
Field | Type | Notes |
uid | string | A unique ID for the user in your system. This can be any string you want, but it must to only a single user for FinSightAPI to have the expected results. |
amountnum | float | The amount associated with the transaction. |
date | string | The ISO 8601 formatted date for when the transaction occurred. |
simple_description | string | A cleaned-up description of the transaction. |
original_description | string | The transaction description as it appeared initially upon aggregation. |
transactionid | string | A unique ID associated with the transaction. FinSightAPI will not save two transactions with the same transactionid, so make sure this field is truly unique. |
// header and options code
const basicTransaction = {
"uid": "example_user_id",
"amountnum": 10.99,
"date": "2022-10-01",
"simple_description": "Target",
"original_description": "TARGET #234 purchase ****1234 20221001",
"transactionid": "sample_transaction_id"
}
const body = { transactions: [ basicTransaction ] }
const requestOptions = {
method: 'POST',
headers: headers,
body: body,
redirect: 'follow'
}
try {
const response = await fetch("{{BASE_URL}}/v3/transactions", requestOptions);
const data = response.json();
console.log({ data });
} catch(error) {
console.log({ error });
}
If everything works, you will receive a message from FinSightAPI in the response data
that notifies you of the number of transactions it has received. Because FinSightAPI’s enrichment is usually asynchronous, it does not return any additional data in the POST transactions response. To get FinSightAPI enrichment, there are two options:
- Register for and receive webhooks from FinSightAPI when new enrichment is written (recommended)
- Fetch enrichment data from the endpoints.
Register For Webhooks
Because enrichment can continue to be applied to your transaction data over a long period of time, FinGoal recommends that you set up a webhook endpoint to receive any updates from FinGoal without having to explicitly call for them.
To register an endpoint, we simply have to invoke an API endpoint with the address we want the data to go to:
const headers = new Headers();
headers.append("Authorization", "Bearer {YOUR_TOKEN}");
headers.append("Content-Type", "application/json");
var raw = JSON.stringify({
"webhook": "{YOUR_CALLBACK_URI}"
});
var requestOptions = {
method: 'PATCH',
headers: headers,
body: raw,
redirect: 'follow'
};
try {
const response = await fetch("{{BASE_URL}}/v3/configuration/webhook", requestOptions);
const data = response.json();
console.log({ data });
} catch(error) {
console.log({ error });
}
If the webhook is registered, you will see your new webhook URI appear in the callback data. From this point on, FinSightAPI will send all enrichment updates to this endpoint. You may change the endpoint at any time, but note that all enrichment data for every user you’ve registered with FinSightAPI will flow to this endpoint.
Here is an example of the payload you can expect for a FinSight webhook:
{
"finsights": [
{
"uid": "example_user_id",
"amountnum": 10.99,
"date": "2022-10-01",
"simple_description": "Target",
"original_description": "TARGET #234 purchase ****1234 20221001",
"transactionid": "sample_transaction_id",
"insight_ctaurl": "http://example.com",
"finsight_image": "https://example.com/example.jpg",
"insight_text": "Get Target Red Card to save on your Target shopping!",
"recommendation": "Target Red Card",
"finsightDate": "2022-10-14",
"amountFound": 10.00
}
]
}
Request Enrichment
As an alternative to webhooks, you can request FinSight and other enrichment data directly from FinSightAPI. Although FinGoal strongly recommends setting up webhooks for a long term integration, requesting the enrichment directly can be simpler for developers who are just trying to experiment with the API without building infrastructure.
FinSight Schema
Field | Value | Notes |
insight_ctaurl | string | A URL for the call-to-action, which can be used as an HREF for the insight text. |
finsight_image | string | a URL for an image relevant to the FinSight. |
insight_text | string | User-facing copy that describes the insight. |
finsightDate | string | An ISO 8601 formatted date for when the FinSight was generated by FinSightAPI. |
recommendation | string | A title for the FinSight. |
amountFound | float | The estimated amount the user can expect to save if they were to follow the advice. |
To get the FinSight data that is shown in the previous section, for example, we need only make a request to the FinSights endpoint:
const headers = new Headers();
headers.append("Authorization", "Bearer {YOUR_TOKEN}");
headers.append("Content-Type", "application/json");
var requestOptions = {
method: 'PATCH',
headers: headers,
redirect: 'follow'
};
try {
const response = await fetch("{{BASE_URL}}/v3/finsights", requestOptions);
const data = response.json();
console.log({ data });
} catch(error) {
console.log({ error });
}
Notice that we must still include our authorization token in this call. The data will return the same JSON that the FinSight webhook will send. If you want to fetch data for a single user, add a ?uid={user_id}
query parameter to the call to narrow your results.
Because of FinSightAPI’s asynchronous enrichment, FinSight data will not be available at the FinSights endpoint immediately. It can take up to 24 hours for initial FinSight enrichment to run, so if you elect not to configure webhooks, you should wait about a day before checking for enrichment.