Skip to main content
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.
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:
{
  "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.
The catalog takes no path, query, or body parameters — the tenant is irrelevant to the built-in catalog.

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

Create a template

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[].kindstring, 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

# 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.
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": [ ... ] }'
# 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


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