> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ntropy.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ntropy.com/_mcp/server.

# Transaction Enrichment

At Ntropy, a transaction denotes the movement of money between two *entities* - the *account holder*,
and the *counterparty*, mediated by one or more *intermediaries*. The direction of the flow - outgoing or incoming, is
always determined from the perspective of the account holder:

- In an **outgoing** transaction, the account holder is the sender and the counterparty is the receiver.
- In an **incoming** transaction, the account holder is the receiver and the counterparty is the sender.

# Enriching your first transaction

In order to enrich a transaction, we need to first create an [account holder](/account-holders).

<EndpointRequestSnippet endpoint="POST /v3/account_holders" />

Having the account holder created, we can now submit a transaction for enrichment:

<EndpointRequestSnippet endpoint="POST /v3/transactions" />

<Accordion title='See the full raw output'>
    <EndpointResponseSnippet endpoint="POST /v3/transactions" />
</Accordion>

## How does it work?
<Steps>
  ### Entities identification
    The algorithm starts by identifying the entities that are present in the transaction. From the description, it detects
`SQ`, `STARBUCKS` and `NW 4RD` as candidates. It then queries our [entities](/entities) database and locations service, and finds:
    - `SQ`: `Square, Inc.` (916bc837-55ef-3106-88f6-5a8269ca9f2a)
    - `STARBUCKS`: `Starbucks` (d4bc3c80-ec1a-3da2-836e-2a4ca4758be5)
    - `NW 4RD`: a location - Nw 43rd Street 5480, Gainesville, Florida 32653, US

    An additional step is ran to determine the [roles](/identification#roles) of `Square, Inc.` and `Starbucks`. `Square, Inc.` is
    determined to be an **intermediary** and `Starbucks` to be the **counterparty**.

    Learn more about entities identification [here](/identification).

  ### Categorization
    The categorization algorithm looks at the description of the transaction, the amount as well as the entities 
    recognized in the previous step. Since the account holder in the transaction is `consumer`, it'll choose the consumer
    category set. More specifically, the subset of `outgoing` categories, since this is an `outgoing` transaction.
    
    The algorithm determines the transaction to be `outgoing - coffee shops` which is accurate, considering the amount
    and the *counterparty* involved in it.

    Learn more about categorization [here](./categories).
</Steps>

# Enrichment API
The Enrichment API enriches transactions synchronously. Transactions are expected to 
have a unique `id`. If two transactions are submitted with the same `id`, the last will overwrite the older one.

Transactions require an account holder to be specified. Setting it as `null` will disable both
[categorization](./categories) and [recurrence](./recurrence). Attributes specified for an account holder can
drastically improve enrichment accuracy, for more details please refer to the [guide](/account-holders).

Enriched transactions are always accessible via the [Transactions API](/documentation/api/transactions/get-transaction)
and only by the API key that has submitted them.

## Throughput considerations
The enrichment provided by the Transactions API is optimized to reduce latency. 
As a result, it might not be the best fit for your workload, 
as you might hit [rate limits](/api/rate-limits). 
To overcome these limitations, refer to our [Batch API](/batches).

## Error handling
When submitting transactions for enrichment, some errors might occur. It is important to note that transactions 
that have errors or return a non-2xx status code on enrichment are **not** billed.
This is applicable to batch operations as well.

Transaction errors can be due to user input, such as
submitting a transaction with a non-existing account holder id, resulting in a `account_holder_not_found` error or due
to infrastructural issues on our side, such as external API timeouts and in some cases LLM instability, resulting
in an `internal_error`. 

# Managing transactions

After enrichment, the enriched transactions are persisted in our system. You can interact with them via our
[Transactions API](../../documentation/api/transactions). The API is consistent
with that of other endpoints, and it allows you to bulk fetch transactions, get and delete a transaction and reassigning
account holders. Unlike the [Enrichment API](#enrichment-api), the transactions returned by these endpoints contain
the **original** transaction input fields.

## Fetching the previous enriched transaction

<EndpointRequestSnippet endpoint="GET /v3/transactions/{id}" />

<Accordion title='See the full raw output'>
    <EndpointResponseSnippet endpoint="GET /v3/transactions/{id}" />
</Accordion>

## List all transactions
For listing operations, the SDK returns a `cursor` with the next set of results. The `cursor` has to be 
added to the subsequent requests alongside the initial query parameters. We recommend that you use our SDK for 
this purpose, as it's handled automatically there.

<EndpointRequestSnippet endpoint="GET /v3/transactions" />

<Accordion title='See the full raw output'>
    <EndpointResponseSnippet endpoint="GET /v3/transactions" />
</Accordion>


## Deleting a transaction
The transaction API also let's you delete transactions. Deleting a transaction deletes it from our system and is 
**permanent**.
<EndpointRequestSnippet endpoint="DELETE /v3/transactions/{id}" />

## Reassigning the account holder
Sometimes when submitting transactions, there is a mistake when assigning transactions to an account holder. This 
operation allows you to change account holders of a transaction without having to resubmit them. The old and new 
account holders should share the [same set of categories](./categories/#custom-categories).

<EndpointRequestSnippet endpoint="POST /v3/transactions/{id}/assign" />

<Accordion title='See the full raw output'>
    <EndpointResponseSnippet endpoint="POST /v3/transactions/{id}/assign" />
</Accordion>


# Reporting wrong results
In some cases a transaction might be incorrectly categorized - it might have the wrong counterparty or have been assigned
the wrong category. The [Reporting wrong results](../enrichment/reports) section walks you through how to report these 
incorrect results from the enrichment process and ensure that future transactions won't carry these errors.


----------------------------------------