---
title: "Backtest Grid Radar's detectors over a past window"
method: POST
path: "/api/v1/insights/backtest"
tags: ["Insights"]
---

# Backtest Grid Radar's detectors over a past window

`POST /api/v1/insights/backtest`

## Request

- Base URL: `https://askthegrid.com`
- URL: `https://askthegrid.com/api/v1/insights/backtest`
- Auth: HTTP bearer

`replay` evaluates the current detectors every `stepMinutes` across `[from, to)` using only what was knowable at each step, through the same lifecycle the live store uses. `recorded` summarizes the episodes the store holds for the window, from the live evaluation and the history backfill. Both report per-detector occurrence counts, durations and peak severities alongside each episode, and every run is saved: list them with `listInsightBacktests`.

## Request body

- object
  - `iso` 'ERCOT' | 'NYISO' | 'CAISO' | 'PJM' | 'MISO' | 'ISONE' | 'SPP' | 'BPAT' | 'TVA' | 'DUK' | 'CPLE' | 'CPLW' | 'FPC' | 'FPL' | 'SOCO' | 'BCA' | 'AESO' | 'IESO' | 'CENACE' | 'HQ' | 'BCH' | 'MHEB' | 'SPC' | 'NBSO' | 'NSIESO', required
  - `from` string, date-time, required
  - `to` string, date-time, required
  - `mode` 'replay' | 'recorded'
  - `stepMinutes` integer
  - `detectors` string[]

## Response `200`

Success

- object
  - `iso` 'ERCOT' | 'NYISO' | 'CAISO' | 'PJM' | 'MISO' | 'ISONE' | 'SPP' | 'BPAT' | 'TVA' | 'DUK' | 'CPLE' | 'CPLW' | 'FPC' | 'FPL' | 'SOCO' | 'BCA' | 'AESO' | 'IESO' | 'CENACE' | 'HQ' | 'BCH' | 'MHEB' | 'SPC' | 'NBSO' | 'NSIESO', required
  - `mode` 'replay' | 'recorded', required
  - `from` string, required
  - `to` string, required
  - `stepMinutes` number, required
  - `steps` number, required
  - `failedSteps` number, required
  - `detectors` object[], required
    - `detectorId` 'operator_condition' | 'system_price' | 'binding_constraint' | 'price_separation' | 'current_headroom' | 'next_day_capacity' | 'load_forecast_error' | 'load_forecast_skill' | 'renewable_forecast_error' | 'system_frequency' | 'tie_congestion' | 'net_load_surprise' | 'net_load_ramp_risk' | 'scarcity_pressure' | 'local_congestion' | 'cross_market_spread' | 'interface_loading' | 'node_price' | 'forecast_price_spike' | 'forecast_negative_price' | 'demand_record' | 'reliability_adder' | 'reserve_decline', required
    - `episodes` number, required
    - `activated` number, required
    - `activeMinutes` number, required
    - `medianActiveMinutes` number, nullable, required
    - `peakSeverity` object, required
      - `watch` number, required
      - `critical` number, required
    - `unevaluableSteps` number, required
  - `episodes` object[], required
    - `id` string, required
    - `origin` 'live' | 'backfill' | 'replay', required
    - `fingerprint` string, required
    - `detectorId` 'operator_condition' | 'system_price' | 'binding_constraint' | 'price_separation' | 'current_headroom' | 'next_day_capacity' | 'load_forecast_error' | 'load_forecast_skill' | 'renewable_forecast_error' | 'system_frequency' | 'tie_congestion' | 'net_load_surprise' | 'net_load_ramp_risk' | 'scarcity_pressure' | 'local_congestion' | 'cross_market_spread' | 'interface_loading' | 'node_price' | 'forecast_price_spike' | 'forecast_negative_price' | 'demand_record' | 'reliability_adder' | 'reserve_decline', required
    - `subject` object, required
      - `kind` 'grid' | 'constraint' | 'settlement_point' | 'seam' | 'forecast' | 'fuel' | 'dc_tie' | 'interface' | 'asset' | 'portfolio' | 'site' | 'operator_event' | 'weather_event', required
      - `id` string, required
      - `label` string, required
    - `headline` string, required
    - `status` 'confirming' | 'active' | 'recovering' | 'resolved' | 'unevaluable', required
    - `firstDetectedAt` string, required
    - `activatedAt` string, nullable, required
    - `resolvedAt` string, nullable, required
    - `peakSeverity` 'critical' | 'watch' | 'normal', required
    - `peakMateriality` number, required
  - `limitations` string[], required
  - `runId` string, required
  - `createdAt` string, required
  - `durationMs` number, required

## Other responses

- `400`: The request did not match the contract.
- `401`: Missing or invalid credentials.
- `429`: Rate limit exceeded. Wait `Retry-After` seconds; `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` report the budget. Signed-in sessions and API keys have larger budgets than anonymous callers.

---

[API](https://skmtc.dev/askthegrid/apis/ask-the-grid-api.md) · [All operations](https://skmtc.dev/askthegrid/apis/ask-the-grid-api/llms.txt) · [OpenAPI document](https://skmtc.dev/askthegrid/apis/ask-the-grid-api/revisions/9cd80115e395?raw)
