API reference
Metrics
10 operations in this area of the contract. Every one declares the permission it requires.
Contract version 0.2.0All areas
Operations
/v1/metrics/alerts/false-positive-rateThe alert false-positive rate over a window
BRD §13's headline alert KPI, and the number ADR-0017 says an MLRO manages by.
`rate` is null whenever either component was suppressed, or when nothing closed in the window. Publishing "3%" against a visible denominator of 100 republishes the numerator that was suppressed for a reason, and one division is not a defence. "0% false positives" and "nothing was closed" are opposite reports of the same fact, so the second is an absent rate rather than a zero.
`breakdown` carries every closing disposition rather than only the numerator: an MLRO managing false positives needs to see what the other closures were.
Show parameters and responsesHide parameters and responses
Parameters
| Name | In | Type | Description |
|---|---|---|---|
fromrequired | query | string | Start of the half-open window, inclusive. Required and never defaulted: a metric whose period was chosen by the server is a number nobody can reproduce, and two identical requests a minute apart would return different figures with no visible reason. |
torequired | query | string | End of the window, EXCLUSIVE. Half-open because a closed interval double-counts the boundary instant whenever two periods are compared — which is what a trend chart does by design. Must be after `from`. |
rule_key | query | string | Narrows to one rule. This is the parameter that makes suppression necessary rather than tidy: it is the knob that narrows a population until a count names somebody. |
Responses
200The rate, its components and the coverage of the stream behind itMetricRate400—403—
/v1/metrics/cases/ageingAgeing bands for cases still open
BRD §8.8's ageing tile, computed in the database over every open case rather than in the browser over a bounded page of them. The dashboard previously derived this from `?limit=100`: at a microfinance bank that is wasteful, at a tier-1 bank the tile describes the first hundred rows and looks exactly as confident as a correct one.
Show parameters and responsesHide parameters and responses
Parameters
| Name | In | Type | Description |
|---|---|---|---|
as_of | query | string | The instant the question is asked about. Defaults to now. Supplying it is how a board pack reproduces last month's figure rather than recomputing a different one. |
priority | query | p1 | p2 | p3 | p4 | — |
Responses
200One cell per ageing bandMetricDistribution400—403—
/v1/metrics/coverageWhich metric streams are being published, and the live review-queue count
What a dashboard should render before it renders a single tile: per stream, whether anybody publishes it and when they last did. A stream that stopped being published a fortnight ago must not read as a quiet fortnight, and a stream nobody has ever published must name the module that owes it.
`review_queue.pending_screening_hits` is the one live count on this surface and is deliberately NOT an analytics metric. It is a count of work in progress rather than a KPI over a period, screening already owns it, and routing it through a published fact would add publication lag to a number whose entire value is being current (ADR-0027).
Show parameters and responsesHide parameters and responses
Responses
200Coverage per stream, plus the review-queue badgeobject403—
/v1/metrics/executiveCurrent active-book risk exposure plus filing trend and deadline status
BRD §8.8-05..10's aggregate executive surface. Risk is the complete CURRENT active customer book at `risk_as_of`; the filing window does not filter customers by their relationship start and is not presented as historical risk. `historical_risk_available` remains false until an append-only/SCD risk source exists.
Sector is derived from the legal party's shipped industry vocabulary or the natural party's bounded occupation risk codes. Unknown/free-text values collapse to `other`, and geography admits only a two-letter code or `UNKNOWN`, so a suppressed cell label cannot itself contain a customer's name. Counts below five are replaced by null inside SQL and complementary cells are withheld in the service. Projection coverage compares analytics' active rows with onboarding's authoritative active-customer control total; matrices are withheld when those differ. Every successful read is appended to the tenant audit chain.
Show parameters and responsesHide parameters and responses
Parameters
| Name | In | Type | Description |
|---|---|---|---|
fromrequired | query | string | Start of the half-open window, inclusive. Required and never defaulted: a metric whose period was chosen by the server is a number nobody can reproduce, and two identical requests a minute apart would return different figures with no visible reason. |
torequired | query | string | End of the window, EXCLUSIVE. Half-open because a closed interval double-counts the boundary instant whenever two periods are compared — which is what a trend chart does by design. Must be after `from`. |
grain | query | day | week | month | quarter | year | — |
dimensions | query | string[] | One to three unique current-risk dimensions. Defaults to all three. |
Responses
200Disclosure-controlled executive aggregate; no customer records or identifiers.ExecutiveAnalytics400—403—
/v1/metrics/executive/exportExport the exact executive aggregate as JSON or CSV
Computes one ExecutiveAnalytics object and serialises that same object once; the CSV path does not issue a second query. Content-Disposition names the artifact, Digest and X-Content-SHA256 identify its exact bytes, and the query plus digest are appended to the tenant's audit chain before any bytes leave the process.
Show parameters and responsesHide parameters and responses
Parameters
| Name | In | Type | Description |
|---|---|---|---|
fromrequired | query | string | Start of the half-open window, inclusive. Required and never defaulted: a metric whose period was chosen by the server is a number nobody can reproduce, and two identical requests a minute apart would return different figures with no visible reason. |
torequired | query | string | End of the window, EXCLUSIVE. Half-open because a closed interval double-counts the boundary instant whenever two periods are compared — which is what a trend chart does by design. Must be after `from`. |
grain | query | day | week | month | quarter | year | — |
dimensions | query | string[] | — |
formatrequired | query | json | csv | — |
Responses
200The exact aggregate artifact bytes.string400—403—
/v1/metrics/filings/deadlinesRegulatory deadline tracking
Reporting creates deadlines from governed reporting.deadlines configuration, publishes each current state, sweeps breached items and marks submitted filings met. A tenant for which the stream has never been published still returns UNAVAILABLE, never a confident zero; `coverage.reason` names reporting and freshness remains visible.
Configured intervals retain their compliance-validation provenance rather than being presented here as hard-coded statutory claims.
Show parameters and responsesHide parameters and responses
Parameters
| Name | In | Type | Description |
|---|---|---|---|
as_of | query | string | The instant the question is asked about. Defaults to now. Supplying it is how a board pack reproduces last month's figure rather than recomputing a different one. |
kind | query | STR | CTR | SCUML | CBN_RETURN | BOARD | — |
Responses
200One cell per deadline status and horizonMetricDistribution400—403—
/v1/metrics/filings/volumesFiling volumes and trend, bucketed by period
Show parameters and responsesHide parameters and responses
Parameters
| Name | In | Type | Description |
|---|---|---|---|
fromrequired | query | string | Start of the half-open window, inclusive. Required and never defaulted: a metric whose period was chosen by the server is a number nobody can reproduce, and two identical requests a minute apart would return different figures with no visible reason. |
torequired | query | string | End of the window, EXCLUSIVE. Half-open because a closed interval double-counts the boundary instant whenever two periods are compared — which is what a trend chart does by design. Must be after `from`. |
grain | query | day | week | month | quarter | year | The period bucket. A closed set because it is bound into `date_trunc`: a value outside it would arrive at the caller as a Postgres error through a dashboard. |
kind | query | STR | CTR | SCUML | CBN_RETURN | BOARD | Narrows to one report kind. |
Responses
200One point per period, kind and statusMetricSeries400—403—
/v1/metrics/screening/ageingAgeing bands for screening hits still awaiting a decision
How long hits have been waiting, which the pending count on the dashboard has never been able to say. Forty hits raised this morning and forty raised five weeks ago are the same tile and are not the same institution, and the second one is what an examiner opens with.
Counts only hits that are still pending. A decided hit has an age, but "how long did we take" and "how long has this been sitting" are different questions, and conflating them is how an ageing chart improves by deciding nothing. The bands are the same ones the case ageing panel uses, so the two can be read side by side without rescaling.
Show parameters and responsesHide parameters and responses
Parameters
| Name | In | Type | Description |
|---|---|---|---|
as_of | query | string | The instant the question is asked about. Defaults to now. Supplying it is how a board pack reproduces last month's figure rather than recomputing a different one. |
watchlist_key | query | string | Narrows to one list. |
Responses
200One cell per ageing bandMetricDistribution400—403—
/v1/metrics/screening/false-positive-rateThe screening false-positive rate over a window
BRD §8.4-08 asks for configurable match sensitivity balancing false positives against risk. This is the half of that sentence the product could not previously show.
Screening is the highest-volume false-positive generator in the platform — one common surname against a consolidated sanctions list produces hits by the thousand — and until the `screening.outcome` stream existed the only number held about it was a live count of the pending queue. Nothing said how many decided hits were wrong, so a tenant moving `screening.match.threshold` was turning a dial with no gauge attached.
Identical semantics to the alert rate, deliberately: `rate` is null whenever either component was suppressed or nothing was decided in the window, and `breakdown` carries every disposition — `true_positive`, `false_positive` and `suppressed` — because the other decisions are what make the rate interpretable. A hit cleared by a standing suppression is counted as decided at the instant it was raised, since the human decision it rests on was made before the hit existed.
Show parameters and responsesHide parameters and responses
Parameters
| Name | In | Type | Description |
|---|---|---|---|
fromrequired | query | string | Start of the half-open window, inclusive. Required and never defaulted: a metric whose period was chosen by the server is a number nobody can reproduce, and two identical requests a minute apart would return different figures with no visible reason. |
torequired | query | string | End of the window, EXCLUSIVE. Half-open because a closed interval double-counts the boundary instant whenever two periods are compared — which is what a trend chart does by design. Must be after `from`. |
watchlist_key | query | string | Narrows to one list. The dimension that makes the number actionable: a rate concentrated in one list is a list problem, the same rate spread evenly is a threshold problem. It is also a filter that narrows a population until a count could name somebody, which is why suppression is inside the query. |
Responses
200The rate, its components and the coverage of the stream behind itMetricRate400—403—
/v1/metrics/sla/breachesSLA breach counts, split by whether the work is late now or was delivered late
Show parameters and responsesHide parameters and responses
Parameters
| Name | In | Type | Description |
|---|---|---|---|
as_of | query | string | The instant the question is asked about. Defaults to now. Supplying it is how a board pack reproduces last month's figure rather than recomputing a different one. |
stream | query | alert.outcome | case.lifecycle | filing.volume | filing.deadline | screening.outcome | Omit for every stream that carries a deadline. |
Responses
200One cell per stream and breach kindMetricDistribution400—403—