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

# Create a configuration file

> Build a reconify.yaml that maps your files' columns and proves the mapping against real rows.

Every Reconify run reads one `reconify.yaml` file: sources (where files live and how to parse them), pairs (which two sources to compare and under what rules), and optional index settings for large files. Get it right once and every later run is a single command.

## Three ways to get a configuration file

| Route             | Best for                                         | Needs                               |
| ----------------- | ------------------------------------------------ | ----------------------------------- |
| `config infer`    | Fastest, agent-friendly.                         | 100+ parseable rows per side.       |
| Hand-written YAML | Full control: `passes`, `rights`, `group_col`.   | Knowing your column names up front. |
| `config init`     | An interactive wizard for a human at a terminal. | Cannot be driven by an agent.       |

## Infer it

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
reconify config infer --left path/to/left-file.csv --right path/to/right-file.csv --out reconify.yaml
```

This prints a `reconify.engine.config-proposal.v1` document with candidate date, amount, and reference mappings, and writes `reconify.yaml` only when it is confident in all three. If it isn't, the command returns `needs_input`, names the column it couldn't resolve, and (with `--out` set) exits `2` without writing anything.

The usual fix is to open the YAML it half-wrote and name the ambiguous column yourself, then run `config validate` to confirm.

See [Run it with an agent](/cli/agents#let-it-propose-the-config) for the exact confidence gates.

The minimum shape is two sources and one pair:

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
version: 1
timezone: "UTC"

sources:
  left_source:
    file_pattern: "path/to/left-file.csv"
    parser:
      type: csv
      date_col: "Date"
      date_layout: "2006-01-02"
      amount_col: "Amount"
      decimal: "."
      thousands: ","
      multiplier: 100
      ref_col: "Reference"
      name_col: "Description"

  right_source:
    file_pattern: "path/to/right-file.csv"
    parser:
      type: csv
      date_col: "posted_at"
      date_layout: "2006-01-02"
      amount_col: "amount_minor"
      multiplier: 1
      ref_col: "payment_id"
      name_col: "memo"

pairs:
  left_source_vs_right_source:
    left: left_source
    right: right_source
    date_window: "1d"
    amount_tolerance_minor: 0
    name_mode: "none"
```

The two sides deliberately differ. `bank` stores amounts in major units (`123.45`), so `multiplier: 100` converts `123.45` into `12345` minor units. `ledger` already stores minor units (`12345`), so its `multiplier` is `1`. Getting this backwards puts every amount off by a factor of 100 and turns most rows into `amount_diff`.

If your right-side file can exceed a few hundred MB, add an `index` block so Reconify spills to disk instead of running out of memory:

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
index:
  backend: auto
  spill_dir: "/tmp/reconify"
  auto_max_right_file_mb: 2048
```

See [Handle large files](/cli/guides/large-data) for the full set of index and memory options.

## Use the wizard

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
reconify config init --out reconify.yaml
```

The wizard reads headers from your sample files, asks you to map fields, and writes a validated config. A typical session:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
Output path [reconify.yaml]: reconify.yaml
Timezone [UTC]: UTC

Left source name: left_source
Left sample file: path/to/left-file.csv
  Detected headers: Date, Amount, Currency, Reference, Details
  Date column [Date]: Date
  Date layout [2006-01-02]: 2006-01-02
  Amount column [Amount]: Amount
  Currency column (optional) [Currency]: Currency
  Reference column (optional) [Reference]: Reference
  Name column (optional) [Details]: Details

Right source name: right_source
Right sample file: path/to/right-file.csv
  Detected headers: created, amount, currency, id, description
  Date column [created]: created
  Date layout [2006-01-02]: 2006-01-02
  Amount column [amount]: amount
  Currency column (optional) [currency]: currency
  Reference column (optional) [id]: id
  Name column (optional) [description]: description

Pair name [left_source_vs_right_source]: left_source_vs_right_source
Date window [1d]: 1d
Amount tolerance in minor units [0]: 0
Name matching mode (tokens/none) [none]: none

Write reconify.yaml? [y/N]: y
[OK] wrote reconify.yaml
[OK] reconify.yaml is valid
```

Parser type is inferred from each sample file's extension (`.csv` to `csv`, `.json`/`.ndjson` to `json`, `.xlsx`/`.xlsm` to `xlsx`), and CSV sources get extra prompts for decimal and thousands separators. Cancelling at any prompt prints `Config init cancelled.` and exits cleanly.

`--agent` refuses this command outright: it's interactive by design, and an agent that ran it would hang on the first prompt. Use `config infer` or a hand-written file instead.

## Map the columns

Every parser needs `type`, `date_col`, `date_layout`, and `amount_col`.

| Type   | When to use                              |
| ------ | ---------------------------------------- |
| `auto` | Infer from file extension. Safe default. |
| `csv`  | Explicit CSV.                            |
| `json` | JSON array of objects, or NDJSON.        |
| `xlsx` | Excel workbook (`.xlsx` or `.xlsm`).     |

`auto` infers from `.csv`, `.json`, `.ndjson`, `.xlsx`, `.xlsm`. Legacy `.xls` files aren't supported: save them as `.xlsx` or `.csv` first.

`date_layout` uses Go's reference time, not `YYYY-MM-DD` placeholders. The reference date is `2006-01-02 15:04:05 MST`:

| Source format | Layout string |
| ------------- | ------------- |
| `2024-01-15`  | `2006-01-02`  |
| `01/15/2024`  | `01/02/2006`  |
| `15 Jan 2024` | `02 Jan 2006` |

Set `tz` when your dates have no offset and aren't UTC; it defaults to `UTC`. `decimal` and `thousands` control amount parsing (defaults `.` and none). Parenthetical negatives like `(1,234.56)` are handled automatically. For `xlsx`, set `sheet` if the data isn't on the first sheet; if omitted, Reconify reads the first sheet, and the first row on that sheet must be headers, not a title row.

`ref_col`, `name_col`, and `currency_col` are optional but change what Reconify can do. Omit `ref_col` and every row gets an empty reference, which disables reference matching entirely. Omit `name_col` and name-token matching has nothing to compare.

## Prove the mapping against real rows

Order matters here: each step only makes sense once the previous one passes.

<Steps>
  <Step>
    ### Validate the config's structure

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    reconify config validate --config reconify.yaml
    ```

    This checks parser fields, pair references, timezones, date windows, and tolerances, not your actual data. The three most common failures:

    * `multiplier: 0`, which is not a valid conversion factor.
    * A `date_layout` written as `YYYY-MM-DD` instead of Go's `2006-01-02`.
    * A pair naming a source that doesn't exist in `sources`.
  </Step>

  <Step>
    ### Check the source against a real file

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    reconify config check-source --config reconify.yaml --source left_source --file path/to/left-file.csv --rows 25
    ```

    This confirms every column named in the source's `parser` block actually exists in the file's headers, then parses 25 data rows to catch date-layout and amount-format errors before a full run. Use `--rows 0` for a headers-only check. Column lookup is case-insensitive and trims whitespace, so `Date` and `date` both match.

    If `date_col` or `amount_col` isn't found, fix the config or the export headers. If an optional column (`currency_col`, `name_col`, `ref_col`) isn't found, either correct the name or drop the field: Reconify parses without it.
  </Step>

  <Step>
    ### Parse and read the normalized rows

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    reconify parse --config reconify.yaml --source left_source --file path/to/left-file.csv --format table
    ```

    This is the actual output Reconify will match against, not a header check. Look at four things: the date hasn't shifted by a day or timezone, the amount is in minor units (`150000` for `1,500.00`, not `1500.00`), the reference column is populated, and the name field has useful text if `name_mode: tokens` is on.
  </Step>
</Steps>

## When rows still look wrong

If `check-source` passes but the parsed rows are wrong, the problem is almost never the column name; the header lookup already succeeded. Look at `date_layout`, `multiplier`, or `decimal`/`thousands` instead. A `date_layout` mismatch shifts every date by a fixed offset. A wrong `multiplier` puts every amount off by exactly a factor of 100.

If references come through empty, reference matching is silently disabled for every row in that source: Reconify won't error, it reports everything as unmatched instead.

Check `ref_col` against the file's actual header name before touching anything in the matching config.
