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

# Formats and templates

> Browse the built-in format catalog Matcher can parse and register per-tenant fixed-width layout templates for operator-specific files.

Matcher parses incoming files against a catalog of built-in formats and, when a file does not fit one of them, against per-tenant fixed-width **layout templates** you define. This guide covers browsing the format catalog and managing layout templates.

## The format catalog

***

The catalog is the read-only inventory of formats the ingestion engine can parse. It is **global-first and static**: built-in parsers carry no tenant, so the response is identical for every authenticated caller. The catalog is organized as a `region → family → variant` tree, matching the canonical format descriptor axes.

```bash theme={null}
curl -X GET "https://api.matcher.example.com/v1/imports/formats" \
  -H "Authorization: Bearer $TOKEN"
```

Each variant carries the canonical namespaced registry key — the identity an upload or source declaration pins:

```json theme={null}
{
  "regions": [
    {
      "region": "BR",
      "families": [
        {
          "family": "cnab240",
          "variants": [
            { "variant": "febraban-base", "key": "br/cnab240/febraban-base" }
          ]
        }
      ]
    },
    {
      "region": "XX",
      "families": [
        {
          "family": "camt",
          "variants": [
            { "variant": "", "key": "xx/camt/camt053" }
          ]
        }
      ]
    }
  ]
}
```

Regions use the ISO-3166 alpha-2 code (uppercased), or `XX` for region-neutral formats. A single-canonical-layout family (for example `camt`) yields one entry with an empty `variant`.

<Note>The catalog takes no path, query, or body parameters — the tenant is irrelevant to the built-in catalog.</Note>

## Layout templates

***

When a file uses an operator- or brand-specific fixed-width layout that no built-in parser covers, register a **layout template**. A template namespaces a positional layout under the `{region, family, variant}` axes and is resolved by the parse path as an additive layout source for your tenant.

Every submission and edit runs through a **well-formedness gate** *before* storage. Overrun, overlap, missing-required fields, a zero-field record, or a mis-marked money column all reject with `422` and the template is never stored.

<Note>Money third rail: a money column **must** declare `kind: "decimal"`. A money field that omits or mis-marks its kind is rejected by the submission gate — it never reaches the parse path.</Note>

### Create a template

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/imports/formats/templates" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "region": "BR",
    "family": "cnab400",
    "variant": "acme-cobranca",
    "discriminatorStart": 0,
    "discriminatorLength": 1,
    "records": [
      {
        "recordType": "1",
        "width": 33,
        "fields": [
          { "name": "external_id", "startByte": 1, "length": 10, "kind": "string" },
          { "name": "amount", "startByte": 11, "length": 12, "kind": "decimal" },
          { "name": "date", "startByte": 23, "length": 10, "kind": "date" }
        ]
      }
    ],
    "requiredFields": ["external_id", "amount", "date"]
  }'
```

Field values:

* `region` — ISO alpha-2 region (uppercased) or `XX`.
* `family` — closed-enum format family the template namespaces under.
* `variant` — open operator/brand axis (must be non-blank).
* `discriminatorStart` / `discriminatorLength` — the byte range the parser reads to select a record type.
* `records[]` — each record type with its fixed `width` (bytes) and ordered positional `fields`.
* `fields[].kind` — `string`, `decimal` (money/numeric verbatim token, parsed downstream), or `date`.
* `requiredFields` — field names the variant must declare across its record types.

A successful create returns `201` with the stored template, including its `formatKey` (for example `br/cnab400/acme-cobranca`), the discriminator, the full positional layout, and `recordWidths`.

### List and get templates

```bash theme={null}
# List every active template on the tenant (unpaginated)
curl -X GET "https://api.matcher.example.com/v1/imports/formats/templates" \
  -H "Authorization: Bearer $TOKEN"

# Get one template by id
curl -X GET "https://api.matcher.example.com/v1/imports/formats/templates/{templateId}" \
  -H "Authorization: Bearer $TOKEN"
```

The list is unpaginated: layout templates are bounded operator config.

### Update and delete a template

`PUT` is a **full replace**, not a sparse patch — the byte-range invariants are whole-layout properties. The replacement runs through the same well-formedness gate the create path enforces; a failing layout rejects with `422` and the stored template is left unchanged.

```bash theme={null}
curl -X PUT "https://api.matcher.example.com/v1/imports/formats/templates/{templateId}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "region": "BR", "family": "cnab400", "variant": "acme-cobranca", "discriminatorStart": 0, "discriminatorLength": 1, "records": [ ... ] }'
```

```bash theme={null}
# Soft-delete, freeing the format/variant key for reuse
curl -X DELETE "https://api.matcher.example.com/v1/imports/formats/templates/{templateId}" \
  -H "Authorization: Bearer $TOKEN"
```

Delete responds `204`. A missing template returns `404`; a format-key collision with another active template returns `409`.

## Response codes

***

| Status | Meaning                                                                                                   |
| ------ | --------------------------------------------------------------------------------------------------------- |
| `200`  | Catalog, template list, get, or update returned                                                           |
| `201`  | Template created                                                                                          |
| `204`  | Template soft-deleted                                                                                     |
| `400`  | Structurally malformed field/layout                                                                       |
| `404`  | Template not found                                                                                        |
| `409`  | Format/variant key already claimed                                                                        |
| `422`  | Layout failed the well-formedness gate (overrun, overlap, missing-required, zero-field, mis-marked money) |
| `503`  | Format catalog or template store not wired on this deployment                                             |
