> ## 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.

# Enriching Transactions

> A complete guide to enriching transactions with Triqai

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:

```json theme={null}
{
  "title": "AMAZON MKTPLACE PMTS AMZN.COM/BILL WA",
  "country": "US",
  "type": "expense"
}
```

| Field     | Type   | Description                                    |
| --------- | ------ | ---------------------------------------------- |
| `title`   | string | Raw transaction description (1-256 characters) |
| `country` | string | ISO 3166-1 alpha-2 country code                |
| `type`    | string | `expense` or `income`                          |

### Transaction Title Best Practices

<AccordionGroup>
  <Accordion title="Use the full, original string" icon="text">
    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.
  </Accordion>

  <Accordion title="Preserve original formatting" icon="keyboard">
    Keep the original case, spacing, and punctuation: `✓
            "AMAZON.COM*2K4X9T3H2 AMZN.COM/BILL WA" ✗ "Amazon"`
  </Accordion>

  <Accordion title="Include all available metadata" icon="list">
    If your transaction source provides additional description fields,
    concatenate them: `javascript const title = [ transaction.description,
            transaction.merchantName, transaction.locationInfo ].filter(Boolean).join('
            '); `
  </Accordion>
</AccordionGroup>

### 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)

```javascript theme={null}
// Valid country codes
"US"; // United States
"NL"; // Netherlands
"GB"; // United Kingdom
"DE"; // Germany
"FR"; // France
```

<Tip>
  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.
</Tip>

### Transaction Type

Set `type` based on the transaction direction:

| Type      | When to Use                                                |
| --------- | ---------------------------------------------------------- |
| `expense` | Money leaving the account (purchases, payments, fees)      |
| `income`  | Money entering the account (salary, refunds, transfers in) |

This affects how Triqai interprets the transaction and which categories it considers.

## Making the Request

### Basic Request

<CodeGroup>
  ```typescript Node.js theme={null}
  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",
  });
  ```

  ```bash cURL theme={null}
  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"
    }'
  ```

  ```python Python theme={null}
  import requests
  import os

  response = requests.post(
      'https://api.triqai.com/v1/transactions/enrich',
      headers={
          'Content-Type': 'application/json',
          'X-API-Key': os.environ['TRIQAI_API_KEY']
      },
      json={
          'title': 'NETFLIX.COM',
          'country': 'US',
          'type': 'expense'
      }
  )

  result = response.json()
  ```
</CodeGroup>

### Processing Multiple Transactions

For multiple transactions, make individual requests. Retries and rate limits are handled automatically:

```typescript theme={null}
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;
}
```

<Tip>
  Transient errors (429, 500, 503) are automatically retried with exponential
  backoff, so you don't need to implement retry or rate-limit logic yourself.
</Tip>

## Processing the Response

### Successful Response

A successful enrichment returns structured data with an entities array:

```json theme={null}
{
  "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"] }
      },
      "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.3.13",
    "categoryVersion": "triqai-2026.01"
  }
}
```

### Extracting Key Data

```typescript theme={null}
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,
};
```

## Handling Different Transaction Types

### Regular Purchases

Most transactions identify a merchant directly:

```json theme={null}
{ "title": "STARBUCKS STORE 1234", "country": "US", "type": "expense" }
```

### Intermediary Transactions

When a payment processor or platform is involved:

```json theme={null}
{ "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:

```json theme={null}
{ "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:

```json theme={null}
{ "title": "PAYROLL ACME CORP", "country": "US", "type": "income" }
```

Uses income-specific categories and classification logic.

## Next Steps

<CardGroup cols={2}>
  <Card title="Handling Responses" icon="reply" href="/guides/handling-responses">
    Learn to process different response types
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/guides/error-handling">
    Handle errors and edge cases
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/enrich">
    See the full API documentation
  </Card>

  <Card title="Best Practices" icon="star" href="/guides/best-practices">
    Optimization tips and patterns
  </Card>
</CardGroup>
