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.
Triqai API responses follow a consistent structure. This guide explains how to handle different response scenarios effectively.
Response Structure
All responses share a common structure:
{
"success": boolean,
"partial": boolean, // Only for enrichment
"data": { ... }, // On success
"error": { ... }, // On failure
"meta": {
"generatedAt": "ISO timestamp",
"requestId": "unique ID",
"version": "API version"
}
}
Success Responses
Full Success
When all enrichment modules succeed, the entities array contains all identified entities:
{
"success": true,
"partial": false,
"data": {
"transaction": {
"category": { "primary": { "name": "Coffee Shops" }, "confidence": { "value": 95, "reasons": ["merchant_category_match"] } },
"confidence": { "value": 92, "reasons": [] }
},
"entities": [
{ "type": "merchant", "role": "organization", "confidence": { "value": 98, "reasons": ["name_closely_matched"] }, "data": { "name": "Starbucks" } },
{ "type": "location", "role": "store_location", "confidence": { "value": 85, "reasons": ["city_match"] }, "data": { "formatted": "1530 Broadway, New York" } }
]
}
}
Processing:
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",
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 intermediary = entities.find(e => e.type === "intermediary");
const person = entities.find(e => e.type === "person");
Partial Success
When some enrichment modules succeed and others fail:
{
"success": true,
"partial": true,
"data": {
"transaction": {
"confidence": { "value": 75, "reasons": [] }
},
"entities": [
{
"type": "merchant",
"role": "organization",
"confidence": { "value": 95, "reasons": ["name_closely_matched"] },
"data": { "name": "Acme Corp" }
}
]
},
"meta": {
"errors": ["location_timeout"]
}
}
Processing:
const result = await triqai.transactions.enrich({
title: "UNKNOWN STORE 99999",
country: "US",
type: "expense",
});
if (result.partial) {
const merchant = result.data.entities.find(e => e.type === "merchant");
if (merchant) {
console.log("Merchant found:", merchant.data.name);
}
}
Working with the Entities Array
The entities array only contains identified entities. To check for a specific entity type, use find:
const result = await triqai.transactions.enrich({
title: "STARBUCKS STORE 1234 NEW YORK",
country: "US",
type: "expense",
});
const { entities } = result.data;
const getEntity = (type: string) => entities.find(e => e.type === type) ?? null;
const processed = {
hasMerchant: !!getEntity("merchant"),
hasLocation: !!getEntity("location"),
hasIntermediary: !!getEntity("intermediary"),
hasPerson: !!getEntity("person"),
merchant: getEntity("merchant")?.data,
location: getEntity("location")?.data,
intermediary: getEntity("intermediary")?.data,
person: getEntity("person")?.data,
};
Error Responses
When a request fails entirely:
{
"success": false,
"error": {
"code": "validation_error",
"message": "Validation failed",
"details": {
"fieldErrors": {
"title": ["Title is required"],
"country": ["Invalid country code"]
}
}
},
"meta": { }
}
Error Response Handling
Errors are thrown as typed exceptions you can catch directly:
import Triqai, { ValidationError, RateLimitError, TriqaiError } from "triqai";
const triqai = new Triqai(process.env.TRIQAI_API_KEY!);
try {
const result = await triqai.transactions.enrich({
title: "",
country: "US",
type: "expense",
});
} catch (err) {
if (err instanceof ValidationError) {
console.log("Field errors:", err.fieldErrors);
} else if (err instanceof RateLimitError) {
console.log("Retry after:", err.rateLimitInfo.retryAfter, "seconds");
} else if (err instanceof TriqaiError) {
console.log(`API error ${err.statusCode}: ${err.message}`);
}
}
Working with Enrichment Data
Merchant Data
const result = await triqai.transactions.enrich({
title: "STARBUCKS NYC",
country: "US",
type: "expense",
});
const merchant = result.data.entities.find(e => e.type === "merchant");
if (merchant) {
console.log(merchant.data.name); // "Starbucks"
console.log(merchant.data.icon); // logo URL
console.log(merchant.data.website); // "https://www.starbucks.com"
console.log(merchant.confidence.value); // 98
}
Location Data
const location = result.data.entities.find(e => e.type === "location");
if (location) {
console.log(location.data.formatted); // "1530 Broadway, New York"
console.log(location.data.structured.city); // "New York"
console.log(location.data.structured.coordinates); // { latitude, longitude }
console.log(location.confidence.value); // 85
}
Category Data
const { category } = result.data.transaction;
const parts = [
category.primary.name,
category.secondary?.name,
category.tertiary?.name,
].filter(Boolean);
console.log(parts.join(" > ")); // "Coffee Shops > Food & Dining"
console.log(category.primary.code.mcc); // 5814
console.log(category.confidence.value); // 95
Complete Processing Example
import Triqai, { TriqaiError } from "triqai";
const triqai = new Triqai(process.env.TRIQAI_API_KEY!);
async function processTransaction(title: string, country: string, type: "expense" | "income") {
try {
const result = await triqai.transactions.enrich({ title, country, type });
const { transaction, entities } = result.data;
const find = (t: string) => entities.find(e => e.type === t);
const merchant = find("merchant");
const location = find("location");
const intermediary = find("intermediary");
const person = find("person");
return {
category: transaction.category.primary.name,
subcategory: transaction.category.secondary?.name,
confidence: transaction.confidence.value,
merchant: merchant ? {
name: merchant.data.name,
logo: merchant.data.icon,
confidence: merchant.confidence.value,
} : null,
location: location ? {
formatted: location.data.formatted,
coordinates: location.data.structured.coordinates,
confidence: location.confidence.value,
} : null,
intermediary: intermediary ? {
name: intermediary.data.name,
role: intermediary.role,
confidence: intermediary.confidence.value,
} : null,
person: person ? {
displayName: person.data.displayName,
confidence: person.confidence.value,
} : null,
};
} catch (err) {
if (err instanceof TriqaiError) {
console.error(`API error ${err.statusCode}: ${err.message}`);
}
throw err;
}
}
Best Practices
Always check success status first
Before accessing data, verify success === true.
Handle partial results gracefully
Don’t fail if some entities are missing. Use what’s available in the entities array.
Check entity existence before accessing data
Always use entities.find(e => e.type === 'merchant') and check for null before accessing .data.
Use confidence scores and reasons for display decisions
Show confidence indicators to users or flag low-confidence results. Use reason tags for smarter decisions.
Keep the meta.requestId for debugging and issue reports.
Next Steps
Error Handling
Handle errors and edge cases
Confidence Scores
Interpret confidence values and reason tags