Quickstarts
LinkMoney API
Aggregator Guides
FinSight API
Resources
Privacy
Developer Account
Transaction Enrichment
The FinSight API clarifies transaction descriptions, adds location information, and infers additional transactional metadata to offer a more complete picture of user spending.
Data enrichment is completed by sending transactions to FinSightAPI /v3/
cleanup
endpoint. An authorization token is required in the headers, and the data to be enriched is required in the request body.
We currently offer synchronous and asynchronous flows. If you’d like to receive the enriched data back in the response, you can use https://findmoney-dev.fingoal.com/v3/cleanup/sync. If you’d prefer to send fewer, larger requests and get the response back in asynchronously via webhook, use https://findmoney-dev.fingoal.com/v3/cleanup. Everything else about the request is the same, just change the endpoint.
Responses are sent on a per-user basis. If you pass a request in with 100 transactions from a single user, you will be sent a single webhook when the request is completed. If you send a request with 100 transactions from 3 separate users, you will be sent 3 webhooks as the requests are completed for each user’s data. Synchronous requests with multiple users will return an array for each user’s transactions.
Quickstart Guide
If you haven’t done so already, follow the FinSight Quickstart guide to sign up for our developer portal, get your credentials, and generate an access token. The access token is specific to your client ID, and will grant 24-hour access to the Data Enrichment endpoint, at which time you must regenerate it. Once you have a valid access token, you’re ready to proceed with cleaning up transactions.
Then just make a call to your preferred endpoint with your token and a valid transaction body - refer to the Data Enrichment Request section in this document for a transaction schema.
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer {YOUR_TOKEN}");
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({
"transactions": [
{
"uid": "16432789fdsa78",
"accountid": "1615",
"amountnum": 12.41,
"date": "10/11/19",
"original_description": "T0064 TARGET STORE",
"transactionid": "988cee06-5d36-11ec-b00b-bc8d8f2303a12733",
"accountType" : "creditCard",
"settlement": "debit"
}
]
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://findmoney-dev.fingoal.com/v3/cleanup", requestOptions)
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.log('error', error));
Example Data Enrichment Request
Request Fields
Location | Field | Format | Notes |
Headers | |||
required | Authorization | string | Authorization: Bearer {your_token} |
required | Content-Type | string | Value should be application/json |
Body | |||
required | transactionid | string | GUID assigned to this transaction. Must be unique for this user. Max limit 100 characters. |
required | amountnum | number | Dollar amount assigned to the transaction |
required | original_description | string | Description for the transaction.
Max length: 200 characters
Min length: 2 characters |
required | uid | string | User id
Max limit: 110 characters |
required | accountType | string | options: creditCard , checking , savings |
required | settlement | string | credit (i.e. inflow) or debit (i.e. outflow) |
optional | accountid | string | User account associated with the transaction
Max limit: 50 characters |
optional | date | string | date the transaction occurred |
optional | city | string | city where the transaction occurred |
optional | zip_code | string | zip code where the transaction occurred |
Example
curl --location --request POST 'https://findmoney-dev.fingoal.com/v3/cleanup' \
--header 'Authorization: Bearer {YOUR_TOKEN}' \
--header 'Content-Type: application/json' \
--data-raw '{
"transactions": [{
"uid" : "16432789fdsa78",
"accountid" : "1615",
"amountnum" : 12.41,
"date" : "10/11/19",
"original_description" : "T0064 TARGET STORE",
"transactionid" : "988cee06-5d36-11ec-b00b-bc8d8f2303a12733",
"accountType" : "creditCard",
"settlement": "debit"
}]
}'
Example Async Data Enrichment Response
Although enriched transactions are returned by webhook, the enrichment API will send a synchronous response that indicates that the transaction data has been successfully submitted:
{
"status": {
"transactions_received": true,
"transactions_validated": true,
"processing": true,
"num_transactions_processing": 250,
"batch_request_id": "c90805f7-963f-411e-9e28-52eefa82446c"
}
}
Example Sync Data Enrichment Response
You’ll receive all enriched transactions with each user in their own array:
{
"enrichedTransactions": [
[
{
"type": "PURCHASE",
"subType": "PURCHASE",
"merchantCountry": "US",
"container": "bank",
"is_physical": true,
"is_recurring": false,
"categoryLabel": [
"Transportation",
"Gas Stations"
],
"sourceId": "BDD61dfaf10F-BBB9-4C00-B11C-88DB5C475BEF",
"merchantName": "Gas Plus",
"highLevelCategoryId": "10000003",
"categoryId": "8",
"merchantType": "OTHERS",
"simpleDescription": "Gas Plus",
"detailCategoryId": "1266",
"category": "Gasoline/Fuel",
"amountnum": -23.01,
"date": "2022-06-02T00:00:00.000Z",
"transactionid": "BDD61dfaf10F-BBB9-4C00-B11C-88DB5C475BEF",
"receiptDate": "2023-01-19T21:25:23.743Z",
"original_description": "GAS PLUS",
"accountid": "84390473001",
"uid": "1234",
"requestId": "15773d26-e5c5-4736-82ec-f6ae69bee6a7",
"transactionTags": [
"Car Owner",
"Gas Vehicle"
],
"guid": "1d24165f-d1cc-4e42-a7a2-7dc007ded8c8",
"merchantLogoURL": "https://links.fingoal.com/Gas_Fuel"
},
{
"type": "PURCHASE",
"subType": "PURCHASE",
"merchantCity": "Boulder",
"merchantState": "CO",
"merchantCountry": "US",
"container": "creditCard",
"merchantLogoURL": "https://links.fingoal.com/QxVdlb",
"merchantPhoneNumber": "3034493400",
"merchantLongitude": "-105.25631",
"merchantLatitude": "40.02174",
"merchantAddress1": "2800 pearl street",
"merchantZip": "80301",
"is_physical": true,
"is_recurring": false,
"categoryLabel": [
"Retail",
"Department Stores"
],
"sourceId": "988cee06-5d36-11ec-b00b-bc8d8f2303a12733",
"merchantName": "Target",
"highLevelCategoryId": "10000010",
"categoryId": "44",
"merchantType": "OTHERS",
"simpleDescription": "Target",
"detailCategoryId": "1306",
"category": "General Merchandise",
"amountnum": 12.41,
"date": "2019-10-11T00:00:00.000Z",
"transactionid": "988cee06-5d36-11ec-b00b-bc8d8f2303a12733",
"receiptDate": "2023-01-19T21:25:23.743Z",
"original_description": "T0064 TARGET STORE",
"accountid": "1610295",
"uid": "1234",
"requestId": "15773d26-e5c5-4736-82ec-f6ae69bee6a7",
"transactionTags": [
"Big Box Store"
],
"guid": "0bb0bd14-4ab1-4ebb-9cef-6a3aa3c4ab63"
}
],
[
{
"type": "PAYMENT",
"subType": "CREDIT_CARD_PAYMENT",
"merchantCountry": "US",
"container": "bank",
"merchantLogoURL": "https://links.fingoal.com/ClMpZo",
"is_physical": true,
"is_recurring": false,
"sourceId": "9032rfj-a3a4-418f-9dd4-307cdcdf89b7",
"merchantName": "Capital One",
"highLevelCategoryId": "10000018",
"categoryId": "26",
"merchantType": "BILLERS",
"simpleDescription": "Capital One Credit Card Payment",
"detailCategoryId": "1169",
"category": "Credit Card Payments",
"amountnum": -126.63,
"date": "2021-11-26T00:00:00.000Z",
"transactionid": "9032rfj-a3a4-418f-9dd4-307cdcdf89b7",
"receiptDate": "2023-01-19T21:25:24.617Z",
"original_description": "CAPITAL ONE - MOBILE PMT ",
"accountid": "1222298",
"uid": "12345",
"requestId": "15773d26-e5c5-4736-82ec-f6ae69bee6a7",
"transactionTags": [
"Capital One Credit Card Payment",
"Credit Card Payment",
"Account at Large Bank"
],
"guid": "a71bce9e-83d9-4118-ad32-a0770a29f08d"
}
],
[
{
"type": "PURCHASE",
"subType": "PURCHASE",
"merchantState": "CO",
"merchantCountry": "US",
"container": "bank",
"is_physical": true,
"is_recurring": false,
"categoryLabel": [
"Social",
"Food and Dining",
"Restaurants"
],
"sourceId": "5699",
"highLevelCategoryId": "10000021",
"categoryId": 22,
"merchantType": "OTHERS",
"simpleDescription": "Winot Coffee",
"detailCategoryId": "1589",
"category": "Restaurants/Dining",
"amountnum": -10.13,
"date": "2021-11-12T00:00:00.000Z",
"transactionid": "5699",
"receiptDate": "2023-01-19T21:25:25.470Z",
"original_description": "WINOT COFFEE NEWPORT CO 80503",
"accountid": "123456",
"uid": "123456",
"requestId": "15773d26-e5c5-4736-82ec-f6ae69bee6a7",
"transactionTags": [
"Local Coffee Shop"
],
"guid": "d25b5f1d-cdc3-4f51-80e6-e1b0281ae7a1",
"merchantLogoURL": "https://links.fingoal.com/Restaurants_Dining"
}
]
]
}
Webhooks
While the Data Enrichment API can process large payloads of transaction data, large batches take too long for data to be exchanged over a conventional HTTP request-response flow. As a result, all data from the data enrichment API is returned to the client over webhooks.
When you set up a client ID and a client secret in the developer dashboard, you can also set up a callback URI. The Data Enrichment API will target your callback URI endpoint with a POST
request that contains the enriched data.
Webhook POST body Schema
Field Name | Field Type |
enrichedTransactions | EnrichedTransaction[] |
The body of the webhook has one field, enrichedTransactions
, which contains enriched versions of the transactions sent to the enrichment API. Note that each request you make to enrichment can be broken up into multiple webhook payloads, so each individual webhook will contain only a portion of the enriched data, rather than every enriched records.
If necessary, you may use the uid
and transactionid
fields on the returned transaction objects to associate them with the originating transaction in your own data store.
Example Webhook Body
{
"enrichedTransactions": [{
"type":"PURCHASE",
"subType":"PURCHASE",
"merchantCountry":"US",
"container":"bank",
"merchantLogoURL":"https://links.fingoal.com/uzKsQY",
"is_physical":true,
"is_recurring":false,
"categoryLabel": [
"Transportation",
"Gas Stations"
],
"sourceId":"2bd359ec-659d-4416-985d-7fc29bb18a4f",
"merchantName":"Shell",
"highLevelCategoryId":"10000003",
"categoryId":8,
"merchantType":"OTHERS",
"simpleDescription":"Shell",
"detailCategoryId":"1266",
"category":"Gasoline/Fuel",
"amountnum":512,
"date":"2018-09-18T00:00:00.000Z",
"transactionid":"2bd359ec-659d-4416-985d-7fc29bb18a4f",
"receiptDate":"2022-10-04T19:08:01.120Z",
"original_description":"Gas Station",
"uid":"your_users_id",
"transactionTags": ["Big Box Store"]
}]
}
Enriched Transaction Schema
Enriched Transaction Data
Field Name | Type | Additional Notes |
amountnum | number | |
category | string | |
categoryId | string | |
categoryLabel | string[] | |
client_id | string | Will be equivalent to the client_id used to generate the auth token. |
container | string | |
date | string | |
detailCategoryId | string | |
highLevelCategoryId | string | |
is_physical | boolean | |
is_recurring | boolean | |
merchantAddress1 | string | |
merchantCity | string | |
merchantCountry | string | |
merchantLatitude | string | |
merchantLogoURL | string | |
merchantLongitude | string | |
merchantName | string | |
merchantPhoneNumber | string | |
merchantState | string | |
merchantType | string | |
merchantZip | string | |
requestId | string | |
simpleDescription | string | |
sourceId | string | |
subType | string | |
transactionid | string | Will be equivalent to the transactionid used on the original record. |
type | string | |
uid | string | Will be equivalent to the user ID used when submitting the transaction. |
transactionTags | string [] | Any relevant FinGoal-generated transaction tags will be included in the cleanup response. |
{
"transactions": [{
"amountnum": 12.41,
"category": "General Merchandise",
"categoryId": "44",
"categoryLabel": [
"Retail",
"Department Stores"
],
"client_id": "yourClientId",
"container": "creditCard",
"date": "2019-10-11"
"detailCategoryId": "1306",
"highLevelCategoryId": "10000010",
"is_physical": true,
"is_recurring": false,
"merchantAddress1": "2800 pearl street",
"merchantCity": "Boulder",
"merchantCountry": "US",
"merchantLatitude": "40.02174",
"merchantLogoURL": "https://links.fingoal.com/34127434d4534cb.svg",
"merchantLongitude": "-105.25631",
"merchantName": "Target",
"merchantPhoneNumber": "3034493400",
"merchantState": "CO",
"merchantType": "OTHERS",
"merchantZip": "80301",
"requestId": "eba963ac-8a62-4df7-a064-dfa617e21347",
"simpleDescription": "Target",
"sourceId": "988cee06-5d36-11ec-b00b-bc8d8f2303a12733",
"subType": "PURCHASE",
"transactionid": "988cee06-5d36-11ec-b00b-bc8d8f2303a12733",
"type": "PURCHASE",
"uid": "16432789fdsa78",
"transactionTags": ["National Retailer"]
}]
}
Common Errors and Issues
- You cannot send in duplicate
transactionid
s for the same user in a single call.
Code | Error | Issue |
401 | UnauthorizedError: secret or public key must be provided | No authorization token/bad authorization was passed in. Please check your credentials and retry your request. |
400 | Bad Request | An array of errors in the data will be returned. Fields not allowed or incorrectly formatted will be noted. |
User Tagging
FinSightAPI provides endpoints for fetching user and transaction tags that help characterize spending behavior. The tags are useful for understanding customers' spending habits and preferences.
While transaction tags can be retrieved from the cleanup endpoints and webhooks, user tags and transaction tags are also accessible at two additional dedicated endpoints:
GET /v3/users/:userId
GET /v3/users/:userId/sync
The primary difference between the two is that the /sync
route will re-run the tagging process to ensure the most up-to-date representation of tags is returned.
Authentication
These endpoints require authentication using an OAuth 2.0 Client Credentials JWT. Make sure to include the Authorization
header with the token in the format Bearer <your_token>
.
GET
v3/users/:userId , GET
v3/users/:userId/sync
Fetches user and transaction tags for a specified user ID. Both endpoints return the same schema. Use the sync
keyword to trigger a manual update on the transaction and user tags for a single user.
Request Parameters
userId
, the string ID of the user.
Request Headers
include_tagged_transactions
(optional): Set totrue
to include tagged transactions in the response. By default, tagged transactions are not included.
Response Schema
Field | Type | Description | Nullable? |
user | Object | Contains user information and user tags | |
user.client_id | String | Client Identifier | |
user.registrationDate | String (ISO Date) | User’s registration date | Yes |
user.subtenantId | String | Subtenant Idenfier | Yes |
user.totaltransactions | Number | Total number of user transactions | Yes |
uid | String | user identifier | |
user.tags | String[] | User tags | Yes |
tagged_transactions | Transaction[] | Contains all tagged transactions. | |
transaction.transaction_id | String | Transaction identifier | |
transaction.simple_description | String | Simplified transaction description | |
transaction.original_description | String | Original transaction description. | |
transaction.category | String | Transaction category | |
transaction.amount | Number | Transaction amount | |
transaction.date | String (ISO Date) | Transaction date | |
transaction.transactionTags | String[] | Transaction tags |
Example Response
{
"user": {
"id": "12345",
"uniqueId": "my_client_id:my_uid",
"client_id": "my_client_id",
"lifetimeSavings": null,
"registrationDate": null,
"subtenantId": null,
"totaltransactions": null,
"transactionsSinceLastUpdate": null,
"uid": "my_uid",
"tags": [
"Fast Foodie"
]
},
"transactions": [
{
"transaction_id": "my_transaction_id",
"simple_description": "Chick-fil-A",
"original_description": " CHICK-FIL-A",
"category": "Restaurants/Dining",
"amount": -24.38,
"date": "2023-03-29T00:00:00.000Z",
"tags": [
"Eating Out",
"Fast Food"
]
}
]
}
On This Page
- Transaction Enrichment
- Quickstart Guide
- Example Data Enrichment Request
- Example Async Data Enrichment Response
- Example Sync Data Enrichment Response
- Webhooks
- Enriched Transaction Schema
- Common Errors and Issues
- User Tagging
- Authentication
- GET v3/users/:userId , GET v3/users/:userId/sync
- Request Parameters
- Request Headers
- Response Schema
- Example Response