Passa al contenuto principale

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​

Successful Response