Reports
Deterministic reconciliation reports for ops and finance. AI narratives are generated in sequel-app using BYOAI credentials.
Reports
Payment-reconciler exposes deterministic report APIs. Numbers are computed from Expected / Incoming / Match / SyncLog / Job data. Optional AI summaries are produced later by sequel-app using BYOAI settings; this service only reports meta.ai readiness.
Endpoints
| Method | Path | Audience |
|---|---|---|
GET | /reports/exceptions | Ops — unmatched, needs-review, past-due aging, sync/job failures (snapshot) |
GET | /exceptions | Ops work queue — paginated mixed backlog; work rows via Incoming/Expected |
GET | /reports/period-close | Finance — period KPIs by currency, composition, open appendix |
GET | /reports/cash-position | Finance — collections vs disbursements (CREDIT/DEBIT), net cleared |
Both require JWT or API key (read) plus tenant/environment headers, same as Overview.
Exceptions date semantics
Open exception populations (unmatched incoming, needs-review incoming, past-due expected, aging, top list) are an as-of backlog at toDate (meta.scope.exceptionsAsOf). They are not filtered by fromDate, so aging still includes older open items.
The report remains a snapshot (top 50). Paginated work is GET /exceptions.
fromDate / toDate bound sync and job failures only (meta.scope.failuresFromDate / failuresToDate).
Unmatched rows are limited to transactionDate <= toDate so future-dated items are excluded from the as-of view.
Period close match rate
matchRate.percentByValue uses matched amounts only when both:
acceptedAt(orrejectedAtfor rejects) falls in[fromDate, toDate], and- the related expected transaction’s
expectedDatealso falls in that same range
So the numerator and denominator share the same expected-date cohort (rates should not exceed 100% from cross-period accepts).
Cash position
Financial picture of collections (CREDIT, money in) vs disbursements (DEBIT, money out). Platform convention — not tenant-invertible in v1.
- Cleared — accepted matches in
[fromDate, toDate]whose expectedexpectedDateis also in that window, split by expected direction - Standing — expected still
PENDINGwithexpectedDate <= toDate, with aging buckets - Unexpected — unmatched incoming with
transactionDate <= toDate, split by direction and broken down bysource(optionalsourcequery filters this bucket only) byCurrency.netCleared—clearedCollections.amount − clearedDisbursements.amountfor that currency only (may be negative; never cross-currency)
Multi-currency
Never sum mixed-currency amounts. Use byCurrency / per-currency KPI arrays. Cross-currency summary fields are counts only.