Skip to content
Product Documentation

Overview

BetFlux continuously scrapes US sportsbooks, stores every raw response, and normalizes changes into versioned analytical tables. The API serves per-game Parquet artifacts of those tables. Final files are precomputed and streamed byte-for-byte; you (or the SDK) query them locally. While a game is unsettled, sportsbook-lines is served through provisional live segments that the CLI/SDK can assemble into its current history. The final artifact replaces them after settlement.

Four datasets are live, all at GET /v1/games/{game_id}/{dataset}:

Dataset Grain Rows / game (typ.)
closing-lines (game, operator, market, selection, side) ≈ 12,000
market-results graded (game, operator, market, selection) ≈ 12,000
sportsbook-lines every change-only line observation ≈ 190,000
game-state-timeline (beta) change in our estimate of the game state, with confidence ≈ 200–1,500

The workflow is uniform: discover game ids via the games reference endpoint (league, ET date range, team, status), fetch each game’s file, query locally. The CLI and SDK wrap that loop behind familiar query interfaces. The datasets key on ids from the reference data — games, teams, and players — which is served as JSON alongside them.

The registry is queryable, so you can enumerate datasets and their schemas without leaving the API (both endpoints are public — no key needed):

Terminal window
curl -s https://api.betflux.ai/v1/datasets
curl -s https://api.betflux.ai/v1/datasets/closing-lines/schema

/v1/datasets lists each dataset’s name, covered leagues, content type, and column names. /v1/datasets/{name}/schema returns the row shape as JSON Schema — the same column descriptions rendered in these docs.

Odds are recorded change-only: a new record exists only when something meaningful moved. Counts like pre_game_records and line_move_count count those change records, not polls — a market that never moved has one record no matter how long it was live. This is also why sportsbook-lines is the size it is: ~190k rows per game is every observed change across every market a book offered, not a fixed-interval sampling. Size is a download concern only — reading the game counts it once against your games allowance, like any other dataset.

Each artifact is derived from a versioned analytical table and regenerated — never edited — when upstream data or logic changes. Responses carry an ETag (the artifact’s content hash) so you can cheaply detect a regeneration. Artifacts appear shortly after a game settles; before that, the dataset endpoint returns an honest 404 (see errors).