FinSight Quickstart

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:

  1. Request a FinGoal developer account.
  2. Get credentials for API access.
  3. Generate a FinSightAPI authentication token.
  4. Send transactions to FinSightAPI.
  5. Register for Webhooks.
  6. 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:

  1. Register for and receive webhooks from FinSightAPI when new enrichment is written (recommended)
  2. 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.