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

# Handling Responses

> Process enrichment responses correctly in your application

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:

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

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

```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",
  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:

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

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

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

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

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

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

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

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

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

<AccordionGroup>
  <Accordion title="Always check success status first" icon="check">
    Before accessing data, verify `success === true`.
  </Accordion>

  <Accordion title="Handle partial results gracefully" icon="circle-half-stroke">
    Don't fail if some entities are missing. Use what's available in the entities array.
  </Accordion>

  <Accordion title="Check entity existence before accessing data" icon="shield-check">
    Always use `entities.find(e => e.type === 'merchant')` and check for `null` before accessing `.data`.
  </Accordion>

  <Accordion title="Use confidence scores and reasons for display decisions" icon="chart-bar">
    Show confidence indicators to users or flag low-confidence results. Use reason tags for smarter decisions.
  </Accordion>

  <Accordion title="Store the requestId" icon="bookmark">
    Keep the `meta.requestId` for debugging and issue reports.
  </Accordion>
</AccordionGroup>

## Next Steps

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

  <Card title="Confidence Scores" icon="chart-bar" href="/concepts/confidence-scores">
    Interpret confidence values and reason tags
  </Card>
</CardGroup>
