---
title: "Calibration By Family"
method: GET
path: "/v1/calibration/families"
---

# Calibration By Family

`GET /v1/calibration/families`

## Request

- Base URL: `https://api.anteproof.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.anteproof.com/v1/calibration/families`
- Auth: none declared

The calibration page's data: the same resolved-forecast pool the
launch gate judges, broken down by question family, plus the live
track the gate does not judge yet.

Scope follows the gate exactly. The pastcast track is the current
question-generation scheme and the forecaster version named by the
most recent gate evaluation — older regimes are retired, and mixing
them was measured to flatter the numbers (see
foresight_backtest.report._resolved_pastcasts). The live track is
every real-time forecast that has resolved, all versions, because a
reader deserves the whole real-time record, not a curated slice.
One row per question: the latest forecast, which is what resolution
scored against.

Horizon is the REAL horizon the gate scopes on — resolution date
minus the as-of date (a live forecast's issue date) — bucketed, with
every bucket's row count returned so the page can offer only the
scopes that exist. The default scope is the gate verdict's own
horizon (its report's `horizon_days`, bucketed): since the 30-day
experiment the archive holds pastcasts at more than one horizon and
pooling them was measured to flatter the headline (BSS 0.155 pooled
against 0.107 at the gate's 7 days). `horizon=all` pools on purpose;
a verdict that names no horizon (older reports) scopes nothing.

The verdict follows the same scope. `regime.gate` is the latest
verdict that judged THIS horizon, or null with `regime.gate_scope`
saying in words that no gate covers it — never a fallback to another
horizon's verdict, because a passing 7-day verdict served beside the
90-day maintenance families reads as those families having passed a
gate they have not. `regime.latest_gate` still carries the newest
verdict overall, stamped with its own `domain` and `horizon_days`, so
the distinction survives outside the browser (the MCP tool has no
page, no card and no selector).

Both verdict blocks are under the withheld contract, through
`calibration.public_gate_row` — the same helper /v1/calibration's
`gate_history` uses, not a second copy of the rule. A verdict scoped
to a withheld family keeps its identity and its recorded `passes`,
every statistic in its `report` is `null`, and it carries a
`withheld` block; `withheld` is `null` on every verdict still
published. This block used to be the row as stored, `report` blob and
all, and it read as harmless only while the newest row happened to be
the trusted news-tone run: the first gate row scoped to a withheld
family — which is what a backtest over the maintenance families
creates — would have published that family's `n` and Brier skill
here, from a route whose family table withholds exactly those numbers
three keys further down.

Every family resolved off a GH Archive activity series is WITHHELD,
unconditionally: the windowed maintenance families (`commits_90d`,
`release_90d`) and the legacy daily-threshold families that read the
same three series (`commits_hourly`, `release_published`,
`stars_hourly` — keyed by their metric because they carry no
provenance family). Every question in that pool was resolved by
counting a GH Archive series whose capture collapsed, so the outcomes
those forecasts were scored against are themselves unreliable and no
score over the pool is sound — at any horizon, over any window, however
healthy the series looks now. Their `n` and every statistic beside it
are JSON `null` (never 0, never omitted) and the family carries a
`withheld` block with `reason: "resolutions_untrusted"` saying so;
`withheld` is `null` on everything still published. Their rows are not
folded into a track total either, and a track left with nothing to
score goes null rather than reporting n=0. This matches /v1/risk and
/v1/proof exactly: one endpoint must not withhold a number the next
one publishes. It does not end when the source looks healthy again.

Unknown query parameters are ignored on purpose: published proof
links carry campaign tags (`utm_campaign=...`), and a 422 on those
would break every campaign-tagged link into this record. An invalid
VALUE for `horizon` is still a 422.

## Query parameters

- `horizon` string, nullable: Horizon bucket to scope to: 7 (up to 7 days), 30, 90 or long (over 90); 'all' for every horizon. Omit for the horizon the latest gate verdict scopes on. `regime.gate` is the verdict for the horizon asked for, or null when none was run on it; `regime.latest_gate` is the newest verdict overall, whatever its horizon.

## Response `200`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/anteproof/apis/anteproof-api.md) · [All operations](https://skmtc.dev/anteproof/apis/anteproof-api/llms.txt) · [OpenAPI document](https://skmtc.dev/anteproof/apis/anteproof-api/revisions/c0d5ac701f1e?raw)
