This guide walks through the complete process of enriching transactions, from preparing your data to processing the results.
Preparing Transaction Data
Required Fields
Every enrichment request needs three fields:
{
"title" : "AMAZON MKTPLACE PMTS AMZN.COM/BILL WA" ,
"country" : "US" ,
"type" : "expense"
}
Field Type Description titlestring Raw transaction description (1-256 characters) countrystring ISO 3166-1 alpha-2 country code typestring expense or income
Transaction Title Best Practices
Use the full, original string
Don’t truncate or pre-process the transaction title. Include everything from the bank statement: ✓ "POS 4392 STARBUCKS STORE #1234 NEW YORK NY 10001"
✗ "STARBUCKS"
The full string contains valuable signals (store numbers, locations, dates) that improve accuracy.
Preserve original formatting
Include all available metadata
Country Code
The country code should be:
ISO 3166-1 alpha-2 format (2 letters)
The country where the transaction originated
Uppercase or lowercase (both work)
// Valid country codes
"US" // United States
"NL" // Netherlands
"GB" // United Kingdom
"DE" // Germany
"FR" // France
If you’re unsure of the country, use the account holder’s primary country. Transaction strings often contain location hints that Triqai can use for more accurate matching.
Transaction Type
Set type based on the transaction direction:
Type When to Use expenseMoney leaving the account (purchases, payments, fees) incomeMoney entering the account (salary, refunds, transfers in)
This affects how Triqai interprets the transaction and which categories it considers.
Making the Request
Basic Request
import Triqai from "triqai" ;
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! );
const result = await triqai . transactions . enrich ({
title: "NETFLIX.COM" ,
country: "US" ,
type: "expense" ,
});
Processing Multiple Transactions
For multiple transactions, make individual requests. Retries and rate limits are handled automatically:
import Triqai from "triqai" ;
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! );
async function enrichTransactions ( transactions : Array <{ description : string ; country : string ; amount : number }>) {
const results = [];
for ( const tx of transactions ) {
const result = await triqai . transactions . enrich ({
title: tx . description ,
country: tx . country ,
type: tx . amount < 0 ? "expense" : "income" ,
});
results . push ( result );
}
return results ;
}
Transient errors (429, 500, 503) are automatically retried with exponential backoff, so you don’t need to implement retry or rate-limit logic yourself.
Processing the Response
Successful Response
A successful enrichment returns structured data with an entities array:
{
"success" : true ,
"partial" : false ,
"data" : {
"transaction" : {
"category" : {
"primary" : { "name" : "Entertainment" , "code" : { "mcc" : 4899 , "sic" : 7841 , "naics" : 532230 } },
"secondary" : { "name" : "Streaming Services" , "code" : { "mcc" : 4899 , "sic" : 7841 , "naics" : 532230 } },
"tertiary" : null ,
"confidence" : { "value" : 98 , "reasons" : [ "merchant_category_match" ] }
},
"subscription" : { "recurring" : true , "type" : "streaming" },
"channel" : "online" ,
"confidence" : { "value" : 96 , "reasons" : [] }
},
"entities" : [
{
"type" : "merchant" ,
"role" : "organization" ,
"confidence" : { "value" : 99 , "reasons" : [ "name_closely_matched" , "results_consensus" ] },
"data" : {
"id" : "..." ,
"name" : "Netflix" ,
"icon" : "https://logos.triqai.com/images/netflixcom" ,
"website" : "https://www.netflix.com"
}
}
]
},
"meta" : {
"generatedAt" : "2026-01-19T10:30:00Z" ,
"requestId" : "3c90c3cc-0d44-4b50-8888-8dd25736052a123" ,
"version" : "1.1.9" ,
"categoryVersion" : "triqai-2026.01"
}
}
import Triqai from "triqai" ;
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! );
const result = await triqai . transactions . enrich ({
title: "STARBUCKS STORE #1234 NEW YORK NY" ,
country: "US" ,
type: "expense" ,
});
const { data } = result ;
const { entities } = data ;
const findEntity = ( type : string ) => entities . find ( e => e . type === type );
const merchant = findEntity ( "merchant" );
const location = findEntity ( "location" );
const intermediary = findEntity ( "intermediary" );
const processed = {
category: data . transaction . category . primary . name ,
subcategory: data . transaction . category . secondary ?. name ,
confidence: data . transaction . confidence . value ,
merchantName: merchant ?. data . name ,
merchantLogo: merchant ?. data . icon ,
location: location ?. data . formatted ,
intermediary: intermediary ?. data . name ,
intermediaryRole: intermediary ?. role ,
isSubscription: data . transaction . subscription . recurring ,
channel: data . transaction . channel ,
};
Handling Different Transaction Types
Regular Purchases
Most transactions identify a merchant directly:
{ "title" : "STARBUCKS STORE 1234" , "country" : "US" , "type" : "expense" }
When a payment processor or platform is involved:
{ "title" : "STRIPE* ACME INC" , "country" : "US" , "type" : "expense" }
Triqai identifies the intermediary (Stripe, role processor) and attempts to identify the underlying merchant (Acme Inc).
P2P Transfers
Peer-to-peer payments return both an intermediary and a person entity:
{ "title" : "VENMO PAYMENT TO JOHN DOE" , "country" : "US" , "type" : "expense" }
Returns the P2P platform as an intermediary (role p2p) and the recipient as a person entity.
Income Transactions
Refunds, salary, and other income:
{ "title" : "PAYROLL ACME CORP" , "country" : "US" , "type" : "income" }
Uses income-specific categories and classification logic.
Next Steps
Handling Responses Learn to process different response types
Error Handling Handle errors and edge cases
API Reference See the full API documentation
Best Practices Optimization tips and patterns