---
title: "Public Calibration"
method: GET
path: "/api/transparency/calibration"
tags: ["transparency"]
---

# Public Calibration

`GET /api/transparency/calibration`

## Request

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

Live post-selection calibration over the trailing `days`, public.

Bins each placed bet's stated probability against how often it won and the
claimed edge against the realized edge, per market, over a window ending
today. A sport with fewer than 500 graded bets in the window answers with
its graded count, `below_floor: true`, and no numbers, so no public surface
prints a win rate or a skill score off a thin sample. The window is trailing (not caller-supplied dates) so the surface
stays a fixed shape the frontend can render simply.

Availability: `days` clamps up to one of four buckets, so this route asks the
shared cache in `api.calibration_cache` for at most 20 keys (five sport
choices x four buckets), keyed by sport and bucket rather than by date, so
the keys survive midnight. A result younger than 15 minutes is served as is.
A result between 15 minutes and 24 hours old is served at once while one
background refresh runs, so no caller waits on the query after the first
compute. Each successful public result is also saved to the
calibration_cache_entries table and restored at startup, and the api warms
the four per-sport 365-day keys in the background after it boots. Concurrent
misses for one key await one shared asyncio.Task. This route's SQL passes
through the public one-token AnyIO capacity limiter, and
/api/audit/calibration uses a separate one, so each API process runs at most
two calibration queries at once, one public and one authenticated. Waiting
callers do not occupy the default AnyIO thread capacity. The `30/hour` quota
uses a member-specific key for requests carrying the trusted MCP secret and a
valid on-behalf-of user, and the frontend's server-side fetch, which carries
the trusted X-Frontend-Secret header, gets its own key with a quota it cannot
trip. Other requests use the first X-Forwarded-For hop, which a caller can
spoof, so their per-IP quota cannot bound a determined client on its own.

## Query parameters

- `sport` string, nullable: Filter by sport (mlb/nhl/epl/nfl)
- `days` integer: Trailing window in days, ending today (max 365)

## Response `200`

Successful Response

- CalibrationResponse: Post-selection calibration over graded bets in a date range.
  - `start_date` string, date, required
  - `end_date` string, date, required
  - `sport` string, nullable, required
  - `below_floor` boolean
  - `value_flags_gated` boolean
  - `note` string, nullable
  - `overall` MarketCalibration, required: Calibration rollup for one market (or 'overall').
    - `market` string, required
    - `n_graded` integer, required
    - `brier` number, nullable, required
    - `calibration_error` number, nullable, required
    - `base_rate` number, nullable
    - `brier_baseline` number, nullable
    - `brier_skill` number, nullable
    - `mean_claimed_edge` number, nullable, required
    - `realized_edge` number, nullable, required
    - `suggested_lambda` number, nullable, required
    - `reliability` ReliabilityBin[], required
      - `lo` number, required
      - `hi` number, required
      - `n` integer, required
      - `mean_predicted` number, required
      - `observed_rate` number, required
    - `edge_bins` EdgeBin[], required
      - `lo` number, required
      - `hi` number, required
      - `n` integer, required
      - `mean_claimed_edge` number, required
      - `realized_edge` number, required
      - `shrink_ratio` number, nullable, required
  - `by_market` MarketCalibration[], required
    - `market` string, required
    - `n_graded` integer, required
    - `brier` number, nullable, required
    - `calibration_error` number, nullable, required
    - `base_rate` number, nullable
    - `brier_baseline` number, nullable
    - `brier_skill` number, nullable
    - `mean_claimed_edge` number, nullable, required
    - `realized_edge` number, nullable, required
    - `suggested_lambda` number, nullable, required
    - `reliability` ReliabilityBin[], required
      - `lo` number, required
      - `hi` number, required
      - `n` integer, required
      - `mean_predicted` number, required
      - `observed_rate` number, required
    - `edge_bins` EdgeBin[], required
      - `lo` number, required
      - `hi` number, required
      - `n` integer, required
      - `mean_claimed_edge` number, required
      - `realized_edge` number, required
      - `shrink_ratio` number, nullable, required

## Other responses

- `422`: Validation Error

---

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