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

# Field mapping

> Rename each source's raw columns to Matcher's canonical fields — external_id, amount, currency, date, plus optional description and fee slots per source.

A field map tells Matcher which raw column in a source carries each canonical transaction field. Because every source (bank statements, ledger exports, gateway reports) names its columns differently, the field map normalizes those column names into one fixed vocabulary before matching runs.

<Info>
  A field map only **renames columns**. It does not parse, compute, transform, or combine values. Each canonical field is populated from exactly one source column.
</Info>

## What a field map is

***

A field map belongs to a single **source** inside a **context**. A context reconciles two sides — a `LEFT` source and a `RIGHT` source — and each source has its own field map. Matcher compares the canonical fields produced by both maps, so both sides must resolve to the same vocabulary even when their raw files look nothing alike.

The mapping is a JSON object in the form:

```JSON theme={null}
  { 
    "<canonicalKey>": "<sourceColumnName>"
  }
```

* The **key** is a canonical field. Keys come from a **closed, case-sensitive vocabulary** — Matcher rejects any key outside it.
* The **value** is the name of the column in the raw source that carries that field. Values are free text (whatever your file calls the column) and must be non-empty strings.

## Canonical vocabulary

***

The key space is closed. These are the only keys Matcher accepts.

### Required keys

Every field map must declare all four:

| Key           | Description                                       |
| ------------- | ------------------------------------------------- |
| `external_id` | Unique identifier of the record within the source |
| `amount`      | Transaction amount                                |
| `currency`    | ISO 4217 currency code                            |
| `date`        | Transaction date                                  |

### Optional keys

Declare these only when the source carries them:

| Key            | Description                                                      |
| -------------- | ---------------------------------------------------------------- |
| `description`  | Free-text label copied into the transaction's description column |
| `fee_amount`   | Column carrying a fee amount for the record                      |
| `fee_currency` | Column carrying the currency of that fee                         |

<Info>
  `fee_amount` and `fee_currency` are the optional **fee slot**. When present, the mapped column's value is copied into the transaction metadata that fee verification reads, so a column named anything (for example `mdr_fee`) can carry fees end to end without hand-built metadata. Omit them and behavior is identical to a map without a fee slot.
</Info>

## Creating a field map

***

Field maps are created **per source**. Send the mapping object to the source's field-map endpoint:

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/contexts/{contextId}/sources/{sourceId}/field-maps" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "mapping": {
     "external_id": "Transaction ID",
     "amount": "Amount",
     "currency": "Currency",
     "date": "Post Date",
     "description": "Memo"
   }
 }'
```

**Response**

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "contextId": "969a11cd-6b7d-4e71-b82b-0828e0603149",
  "sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "mapping": {
    "external_id": "Transaction ID",
    "amount": "Amount",
    "currency": "Currency",
    "date": "Post Date",
    "description": "Memo"
  },
  "version": 1,
  "createdAt": "2025-01-15T10:00:00Z",
  "updatedAt": "2025-01-15T10:00:00Z"
}
```

<Tip>
  API Reference: [Create field map](/en/reference/matcher/create-field-map)
</Tip>

## Updating a field map

***

Each source has one field map. To change a mapping, `PATCH` it by its own ID (not the source ID). Send the full mapping — it replaces the previous one and increments `version`.

```bash cURL theme={null}
curl -X PATCH "https://api.matcher.example.com/v1/field-maps/{fieldMapId}" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "mapping": {
     "external_id": "Transaction ID",
     "amount": "Amount",
     "currency": "Currency",
     "date": "Value Date",
     "description": "Memo",
     "fee_amount": "Fee",
     "fee_currency": "Fee Currency"
   }
 }'
```

<Tip>
  API Reference: [Update field map](/en/reference/matcher/update-field-map)
</Tip>

Other operations:

| Operation                         | Endpoint                                                     |
| --------------------------------- | ------------------------------------------------------------ |
| Get a source's field map          | `GET /v1/contexts/{contextId}/sources/{sourceId}/field-maps` |
| List every field map in a context | `GET /v1/contexts/{contextId}/field-maps`                    |
| Delete a field map                | `DELETE /v1/field-maps/{fieldMapId}`                         |

## Example: both sides of a context

***

A context reconciles a bank feed against an internal ledger export. The two files use different column names, so each source declares its own map — but both resolve to the same canonical keys.

### LEFT source — bank statement (CSV)

Raw columns:

```csv theme={null}
BankRef,BookingDate,Amount,Ccy,Narrative
BANK-001,2025-01-15,-500.00,USD,Wire to Acme Corp
```

Field map:

```json theme={null}
{
  "mapping": {
    "external_id": "BankRef",
    "amount": "Amount",
    "currency": "Ccy",
    "date": "BookingDate",
    "description": "Narrative"
  }
}
```

### RIGHT source — ledger export (CSV)

Raw columns:

```csv theme={null}
entry_id,posted_at,value,asset,memo,mdr_fee,fee_ccy
LDG-9931,2025-01-15,-500.00,USD,Payment Acme Corp,2.50,USD
```

Field map:

```json theme={null}
{
  "mapping": {
    "external_id": "entry_id",
    "amount": "value",
    "currency": "asset",
    "date": "posted_at",
    "description": "memo",
    "fee_amount": "mdr_fee",
    "fee_currency": "fee_ccy"
  }
}
```

Both sources now expose `external_id`, `amount`, `currency`, and `date` in the canonical vocabulary, so match rules can compare them directly — even though one file called the amount `Amount` and the other called it `value`.

## Common mistakes

***

<AccordionGroup>
  <Accordion title="Reversing the direction">
    The key is the canonical field and the value is your column — `{"external_id": "BankRef"}`, not `{"BankRef": "external_id"}`. Writing it backwards puts an unknown key (`BankRef`) on the left and is rejected.
  </Accordion>

  <Accordion title="Using keys outside the vocabulary">
    Only `external_id`, `amount`, `currency`, `date`, `description`, `fee_amount`, and `fee_currency` are accepted. Keys such as `transaction_id`, `reference`, `counterparty`, or `type` are rejected as unknown keys, and the error names each offender.
  </Accordion>

  <Accordion title="Wrong case">
    Keys are case-sensitive lowercase tokens. `External_Id`, `Amount`, or `CURRENCY` are treated as unknown keys.
  </Accordion>

  <Accordion title="Missing a required key">
    All of `external_id`, `amount`, `currency`, and `date` must be present. A map missing any of them fails validation with a "missing required keys" message.
  </Accordion>

  <Accordion title="Empty or non-string values">
    Every value must be a non-empty string naming a source column. `null`, numbers, objects, or `""` are rejected.
  </Accordion>

  <Accordion title="Expecting transformations">
    Field maps do not parse dates, divide amounts, concatenate columns, or apply conditionals. Deliver values already in the expected shape from the source file, or normalize upstream before upload.
  </Accordion>
</AccordionGroup>

## Next steps

***

<Card title="Match rules" icon="scale-balanced" href="/en/matcher/configuration/matcher-match-rules" horizontal>
  Define how the canonical fields are compared and grouped.
</Card>

<Card title="Uploading files" icon="upload" href="/en/matcher/daily-reconciliation/matcher-uploading-files" horizontal>
  Import transactions using your field maps.
</Card>
