Public Freshness
Per-bookmaker freshness — last_update summary across all markets.
Returns: bookmakers: [ { key, market_count, latest_update, staleness_seconds, is_stale, worst_staleness_seconds, suspended_market_count, market_classes: { game_lines: { market_count, latest_update, staleness_seconds, active_market_count, oldest_market_update, worst_staleness_seconds, suspended_market_count }, props: { ...same shape }, } } ] stale_threshold_seconds as_of (server time the rows were sampled)
staleness_seconds is the time since the most recent successful market write for the book — a rough proxy for "how fresh is the freshest line on this book." It overstates per-event freshness because any single market touch resets it; for the marketing page that's fine since the public claim we're backing is "we ingest book data continuously and recently."
market_classes splits that per class (game lines vs props) so a class going dark behind fresh game lines — the Pinnacle 2026-08-02 prop incident — is visible here too. Single grouped query, no Event join, so unlike the monitor's query this split does NOT exclude futures markets (they land under props and can keep it looking fresher than the per-game prop board really is) — acceptable for a trust surface.
Each class (and the book) also carries the WORST case: worst_staleness_seconds / oldest_market_update — the age of the oldest NON-SUSPENDED market on the active board (events from -6h to +48h) — plus active_market_count and suspended_market_count. Headline staleness answers "is the book being ingested"; worst-case answers "is any individual market being silently missed". A market with suspended_at set is excluded from the worst-case number because a flagged withdrawal is not a capture hole (the book pulled it; we keep its last price and say so on /odds). Second grouped query with an Event join, bounded by the active-board window.
Response
Successful Response