Match the candidates from a camt.053 parse against your expected-payments list. The closed-loop step.
Takes the candidate-key list from POST /v1/iso20022/camt.053/parse plus a list of expected payments (typically your open invoices or outbound payroll lines) and produces per-entry matching outcomes.
Outcomes: matched (with the matched expected-payment id, confidence high), ambiguous (top three candidates ranked, confidence medium), unmatched (no candidate above the floor), out_of_band (entry has no candidate — typically a bank fee or interest credit).
The matching uses (carrier confidence) × (value-equality) × (amount-match-within-tolerance) as a composite score; tolerance is configurable per tenant.
See apps/api/src/routes/reconcile.ts and the matcher at apps/api/src/lib/reconcile.ts.
Mandatory header `Idempotency-Key` (UUID or other opaque ≤64 char string). A second request with the same key and the same body returns the cached response and the header `X-Iso-Compliant-Idempotent-Replay: true`. A second request with the same key but a different body returns 409.
Rate limit
Sandbox: 60 requests / minute, 1000 / day. Production: 600 requests / minute soft cap, lifted per tenant on request.