Skip to main content
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"
}
FieldTypeDescription
titlestringRaw transaction description (1-256 characters)
countrystringISO 3166-1 alpha-2 country code
typestringexpense or income

Transaction Title Best Practices

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.
Keep the original case, spacing, and punctuation:
✓ "AMAZON.COM*2K4X9T3H2 AMZN.COM/BILL WA"
✗ "Amazon"
If your transaction source provides additional description fields, concatenate them:
const title = [
  transaction.description,
  transaction.merchantName,
  transaction.locationInfo
].filter(Boolean).join(' ');

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:
TypeWhen 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

curl -X POST https://api.triqai.com/v1/transactions/enrich \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "title": "NETFLIX.COM",
    "country": "US",
    "type": "expense"
  }'

Processing Multiple Transactions

For multiple transactions, make individual requests but implement rate limiting:
async function enrichTransactions(transactions) {
  const results = [];
  
  for (const tx of transactions) {
    const result = await enrichSingleTransaction(tx);
    results.push(result);
    
    // Respect rate limits - add delay between requests
    await sleep(100); // 10 requests per second max
  }
  
  return results;
}

async function enrichSingleTransaction(tx) {
  const response = await fetch('https://api.triqai.com/v1/transactions/enrich', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.TRIQAI_API_KEY
    },
    body: JSON.stringify({
      title: tx.description,
      country: tx.country,
      type: tx.amount < 0 ? 'expense' : 'income'
    })
  });
  
  return await response.json();
}

Processing the Response

Successful Response

A successful enrichment returns structured data:
{
  "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": 98
      },
      "subscription": { "recurring": true, "type": "streaming" },
      "channel": "online",
      "confidence": 96
    },
    "enrichments": {
      "merchant": {
        "status": "found",
        "confidence": 99,
        "data": {
          "id": "...",
          "name": "Netflix",
          "icon": "https://logos.triqai.com/images/netflixcom",
          "website": "https://www.netflix.com"
        }
      },
      "location": { "status": "not_applicable", "confidence": null, "data": null },
      "paymentProcessor": { "status": "not_applicable", "confidence": null, "data": null },
      "peerToPeer": { "status": "not_applicable", "confidence": null, "data": null }
    }
  },
  "meta": {
    "generatedAt": "2026-01-19T10:30:00Z",
    "requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a123",
    "version": "1.0.0",
    "categoryVersion": "triqai-2025.11"
  }
}

Extracting Key Data

function processEnrichment(response) {
  if (!response.success) {
    throw new Error(response.error.message);
  }

  const { data, meta } = response;
  
  return {
    // Transaction metadata
    transactionId: meta.requestId,
    confidence: data.transaction.confidence,
    
    // Category
    category: data.transaction.category.primary.name,
    subcategory: data.transaction.category.secondary?.name,
    
    // Merchant
    merchantName: data.enrichments.merchant.data?.name,
    merchantLogo: data.enrichments.merchant.data?.icon,
    
    // Location (if available)
    location: data.enrichments.location.data?.formatted,
    
    // Additional signals
    isSubscription: data.transaction.subscription.recurring,
    subscriptionType: data.transaction.subscription.type,
    channel: data.transaction.channel
  };
}

Handling Different Transaction Types

Regular Purchases

Most transactions identify a merchant directly:
{ "title": "STARBUCKS STORE 1234", "country": "US", "type": "expense" }

Payment Processor Transactions

When a payment processor is involved:
{ "title": "STRIPE* ACME INC", "country": "US", "type": "expense" }
Triqai identifies both the processor (Stripe) and attempts to identify the underlying merchant (Acme Inc).

P2P Transfers

Peer-to-peer payments include recipient information:
{ "title": "VENMO PAYMENT TO JOHN DOE", "country": "US", "type": "expense" }
Returns the P2P platform and recipient details.

Income Transactions

Refunds, salary, and other income:
{ "title": "PAYROLL ACME CORP", "country": "US", "type": "income" }
Uses income-specific categories and classification logic.

Next Steps