> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reconifyhq.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Reconify's API reference is read-only for customer data. Do not invent endpoints or authentication behavior beyond the OpenAPI contract.
> The public OpenAPI document contains only the documented external /v2 contract.

# Transactions

> The normalized transaction model Reconify uses after parsing.

Every row from every source, whatever the file format, becomes the same eight-field transaction. Matching, tolerances, and duplicate detection all operate on this normalized shape, not on the original file.

## From a row to a transaction

A bank CSV row like this:

```csv theme={"theme":{"light":"github-light","dark":"github-dark"}}
Date,Amount,Currency,Reference,Details
2024-01-15,1500.00,NGN,INV-1041,ACME LTD SETTLEMENT
```

becomes this transaction:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "bank-1",
  "date": "2024-01-15T00:00:00Z",
  "amount": 150000,
  "currency": "NGN",
  "reference": "INV-1041",
  "group_key": "INV-1041",
  "name": "ACME LTD SETTLEMENT",
  "source": "bank"
}
```

| Field       | Meaning                                                                                |
| ----------- | -------------------------------------------------------------------------------------- |
| `id`        | `{source}-{row}`, for example `bank-1`.                                                |
| `date`      | Parsed with the source's `date_layout` and `tz`.                                       |
| `amount`    | Minor units. See below.                                                                |
| `currency`  | From `currency_col`, or empty if unset.                                                |
| `reference` | From `ref_col`. The matching key.                                                      |
| `group_key` | From `group_col`, falling back to `reference` when unset. The duplicate-detection key. |
| `name`      | From `name_col`. Used only when `name_mode: tokens`.                                   |
| `source`    | The source name from `reconify.yaml`.                                                  |
| `raw`       | The original row fields, unless `skip_raw: true`.                                      |

## Amounts are integers

`amount` is `150000`, not `1500.00`. Reconify stores every amount as a minor-unit integer so comparisons are exact integer arithmetic: no float rounding ever enters a match decision.

The parser's `multiplier` controls the conversion, and getting it wrong puts every amount off by the same factor:

* `multiplier: 100` when the source file holds major units like `1,234.56` (most bank exports). `1,234.56` becomes `123456`.
* `multiplier: 1` when the source file already holds minor units, like a Stripe `amount` field. `123456` stays `123456`.

Pairing `multiplier: 100` with a source that is already in minor units, the classic Stripe trap, makes every amount 100 times too large and turns every row into an `amount_diff`. If a run comes back with almost nothing matching and the amounts look absurd, check `multiplier` first.

## Reference vs group key

`ref_col` is the matching key: reference matching compares it directly, and name-token matching only runs on rows without a usable reference. `group_col` is a separate key used only for duplicate detection, and it falls back to `ref_col` when you don't set it.

They diverge when several rows legitimately share one identifier but need to match independently. An invoice paid in three installments shares an invoice number in `ref_col`, but each installment has its own `payment_id`.

Leave `group_col` unset and the duplicate detector groups all three installments together and flags them. Set `group_col: payment_id` and each row gets its own duplicate-detection key, so the detector stops flagging legitimate installments while `ref_col` still ties them to the same invoice for matching.

## Optional fields and what omitting them costs

`currency_col`, `name_col`, and `ref_col` are all optional, and the file still parses without them, but matching behavior changes:

* An empty `reference` never participates in reference matching, and an empty `group_key` is never grouped as a duplicate.
* An empty `name` weakens token matching for that row when `name_mode: tokens` is set.
* An empty `currency` is allowed on its own, but mixing empty and non-empty currencies for the same base currency fails the run.

## Raw fields

By default, every transaction carries `raw`: the original row or object, unparsed. It's useful for debugging a bad mapping, but it costs memory on large sources. Set `skip_raw: true` on a source when you don't need the original fields in output.
