Backtest Alert
POST/v1/alerts/:alert_id/backtest
Has this line ever been crossed, and when? MEASURES ONLY; CHANGES NOTHING.
The question a threshold is chosen against. A user picked > 2.0 on a
column whose 110-day maximum was 0.967; the product accepted it, called it
active, and answered not_fired — byte-for-byte what a healthy
service returns. An alert that can never fire was indistinguishable from
an alert watching something that is fine. This is the number that separates
them, and POST /v1/alerts returns the same block on creation.
Read crossings next to scope. crossings: 0 is a fact, not an
error and not a refusal — a line nobody has crossed yet is often exactly
what you meant to watch for. note says it in one sentence, including
when the count is a floor because the row cap was hit.
scope is not decoration. The condition is opaque SQL, so "available
history" means one of two things and the sentence says which: a condition
that declares a window is re-run with that window WIDENED (never
narrowed) and its rows over that span are its crossings; a condition that
declares none is run exactly as written, which is all the history it
addresses — and if its SQL pins a period with a literal, the count is for
that period. A count whose scope is unstated cannot be read.
status is always an answer: ok ran, warming_up means the EC2 SQL
worker was cold and the query never ran (retry in a moment — a warm-up has
been kicked), error carries the same sentence evaluate_alert would
give for an unmeasurable condition, skipped means this alert has no
condition and fires on its clock alone.
What this does not do. It is not an evaluation. No verdict is recorded,
lastEvaluatedAt / lastVerdict / lastFiredAt do not move, nothing
is captured, nothing is delivered, no event is published and the hysteresis
edge evaluate_alert consumes is untouched — so this is safe to call in a
loop while you tune a number, which evaluate_alert is not.
Read-gated (VIEW on the alert's dashboard, the same gate as verify and
GET /v1/alerts/{alert_id}): it writes nothing and derives strictly what
the same caller could get by running the condition's own SQL through
POST /v1/query.
Request
Responses
- 200
- 404
- 422
Successful Response
Not found
Validation Error