Documentation Index Fetch the complete documentation index at: https://docs.triqai.com/llms.txt
Use this file to discover all available pages before exploring further.
Follow these best practices to get the most out of the Triqai API while building reliable, efficient integrations.
Data Quality
Send Complete Transaction Data
Include the full, original transaction string:
{
"title" : "POS 4392 STARBUCKS STORE #1234 NEW YORK NY 10001" ,
"country" : "US" ,
"type" : "expense"
}
{
"title" : "Starbucks" ,
"country" : "US" ,
"type" : "expense"
}
Use Accurate Country Codes
The country code significantly affects matching accuracy:
Use the transaction’s origin country, not user’s country
Use ISO 3166-1 alpha-2 codes (US, NL, GB)
Default to account country if unknown
Set Correct Transaction Type
The type field affects category selection:
Transaction Type Purchases, payments, fees expenseSalary, refunds, deposits income
Deduplicate Similar Transactions
Group identical transactions before enriching to save credits:
import Triqai from "triqai" ;
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! );
interface Transaction {
id : string ;
title : string ;
country : string ;
type : "expense" | "income" ;
}
async function enrichBatch ( transactions : Transaction []) {
const groups = new Map < string , { representative : Transaction ; all : Transaction [] }>();
for ( const tx of transactions ) {
const key = ` ${ tx . title . toUpperCase () } | ${ tx . country } | ${ tx . type } ` ;
if ( ! groups . has ( key )) {
groups . set ( key , { representative: tx , all: [] });
}
groups . get ( key ) ! . all . push ( tx );
}
const results = new Map ();
for ( const [, group ] of groups ) {
const result = await triqai . transactions . enrich ({
title: group . representative . title ,
country: group . representative . country ,
type: group . representative . type ,
});
for ( const tx of group . all ) {
results . set ( tx . id , result );
}
}
return results ;
}
Rate Limit Management
Rate limits are handled automatically via retries and Retry-After header support. You can monitor usage through the debug hook:
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! , {
onResponse : ( info ) => {
// info.headers contains X-RateLimit-* values
console . log ( `Request completed in ${ info . durationMs } ms` );
},
});
For full rate limit details on a response, use raw requests:
const resp = await triqai . rawGet ( "/v1/categories" );
console . log ( resp . rateLimitInfo . remaining );
console . log ( resp . rateLimitInfo . concurrencyRemaining );
Error Handling
Built-In Retry Logic
Retries are handled automatically with exponential backoff on transient errors (429, 500, 503, 504). You can customize the behavior:
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! , {
maxRetries: 5 , // increase from default 3
retryDelay: 1000 , // base delay in ms
maxRetryDelay: 60_000 , // max delay cap
});
For POST requests, retries only happen when an idempotencyKey is provided:
const result = await triqai . transactions . enrich (
{ title: "STARBUCKS" , country: "US" , type: "expense" },
{ idempotencyKey: "unique-key-123" },
);
Handle Partial Results
Don’t discard partial results — use available data:
const result = await triqai . transactions . enrich ({
title: "SOME TRANSACTION" ,
country: "US" ,
type: "expense" ,
});
const { entities } = result . data ;
const merchant = entities . find ( e => e . type === "merchant" );
const location = entities . find ( e => e . type === "location" );
const processed = {
category: result . data . transaction . category ,
merchant: merchant ?. data ?? null ,
location: location ?. data ?? null ,
};
if ( result . partial ) {
console . warn ( "Partial result — some enrichers failed" );
}
Security
Protect API Keys
Store keys in environment variables
Never commit keys to version control
Use separate keys for dev/staging/prod
Rotate keys periodically
import Triqai from "triqai" ;
// Good: Environment variable
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! );
// Bad: Hardcoded — never do this!
// const triqai = new Triqai("triq_abc123...");
Make Requests Server-Side
Never expose your API key in client-side code:
import Triqai from "triqai" ;
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! );
app . post ( "/api/enrich" , async ( req , res ) => {
const result = await triqai . transactions . enrich ({
title: req . body . title ,
country: req . body . country ,
type: req . body . type ,
});
res . json ( result );
});
Monitoring and Observability
Track Key Metrics
Monitor these metrics for your integration:
Metric Why It Matters Success rate Detect issues early Latency (p50, p95, p99) Identify performance problems Partial result rate Track data quality Error rate by code Understand failure patterns Credit consumption Manage costs
Structured Logging
Use the debug hooks for structured logging:
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! , {
onResponse : ( info ) => {
console . log ( JSON . stringify ({
event: "triqai_request" ,
timestamp: new Date (). toISOString (),
status: info . status ,
durationMs: info . durationMs ,
}));
},
});
Architecture Patterns
Async Processing for Bulk Data
For large volumes, process asynchronously:
import Triqai from "triqai" ;
const triqai = new Triqai ( process . env . TRIQAI_API_KEY ! );
// Producer: Queue transactions
async function queueTransactions ( transactions : Array <{ id : string ; title : string ; country : string ; type : "expense" | "income" }>) {
for ( const tx of transactions ) {
await messageQueue . send ({ type: "enrich" , payload: tx });
}
}
// Consumer: Process from queue
async function processQueue () {
while ( true ) {
const message = await messageQueue . receive ();
const result = await triqai . transactions . enrich ( message . payload );
await saveResult ( message . payload . id , result );
}
}
Graceful Degradation
Design for partial failures:
async function getTransactionDisplay ( tx : { title : string ; country : string ; type : "expense" | "income" }) {
try {
const enrichment = await triqai . transactions . enrich ( tx );
return formatEnrichedTransaction ( tx , enrichment );
} catch ( error ) {
console . error ( "Enrichment failed:" , error );
return formatRawTransaction ( tx );
}
}
Checklist
Use this checklist when building your integration:
API key stored securely in environment
Full transaction strings sent, not truncated
Caching implemented for duplicate transactions
Retry logic with exponential backoff
Rate limiting handled gracefully
Partial results processed correctly
Errors logged with requestId
Metrics and monitoring in place
Credit usage tracked
Next Steps
Error Handling Comprehensive error handling guide
Rate Limits Manage request limits effectively