Response formats
The API has two payload shapes:
| Surface | Content type | Shape |
|---|---|---|
Datasets — GET /v1/games/{game_id}/{dataset} |
application/vnd.apache.parquet |
One typed, compressed Parquet file per game |
Discovery & reference — /v1/games, /v1/leagues, /v1/teams, /v1/players, /v1/datasets, /v1/me |
application/json |
JSON objects / {data, next_cursor} envelopes |
Why Parquet
Section titled “Why Parquet”Dataset artifacts run from thousands to ~190k rows across up to 79 columns. At that size Parquet beats JSON on every axis that matters: columns carry real types (int64 timestamps, doubles, string lists — no string re-parsing), compression is columnar (a sportsbook-lines game is tens of MB as Parquet vs. hundreds as JSON), and every analytical tool — DuckDB, pyarrow, pandas, polars — reads it natively. The server streams the file byte-for-byte and never filters, sorts, or re-encodes rows; queries run on your CPU.
curl -s "https://api.betflux.ai/v1/games/NBA_GSW_MIA_20260401/closing-lines" \ -H "Authorization: Bearer $BETFLUX_API_KEY" -o closing.parquetResponses carry an ETag (the artifact’s content hash) and
Accept-Ranges: bytes; full responses are edge-cached for 24 hours.
HTTP Range / partial reads
Section titled “HTTP Range / partial reads”Standard byte ranges are honored (206 Partial Content with
Content-Range), which is what lets Parquet-aware readers fetch only the
footer and the column chunks a query touches:
curl -s "https://api.betflux.ai/v1/games/NBA_GSW_MIA_20260401/closing-lines" \ -H "Authorization: Bearer $BETFLUX_API_KEY" -H "Range: bytes=0-65535"Note that quota is debited per artifact request at the file’s full row count — a partial read is still a read (see Rate limits & quotas).
DuckDB straight at the files
Section titled “DuckDB straight at the files”The dataset endpoints are plain authenticated Parquet URLs, so DuckDB can query them in place — predicate pushdown means it reads only the byte ranges it needs:
CREATE SECRET betflux ( TYPE http, EXTRA_HTTP_HEADERS MAP {'Authorization': 'Bearer bfx_live_...'});SELECT operator, market_type, odds, timestampFROM read_parquet('https://api.betflux.ai/v1/games/MLB_BOS_NYY_20260715/sportsbook-lines')WHERE market_type = 'MONEYLINE'ORDER BY timestamp;Downloaded files work the same way, minus the auth setup:
SELECT * FROM 'closing.parquet' WHERE operator = 'PINNACLE';Table / CSV / JSON output is client-side
Section titled “Table / CSV / JSON output is client-side”The CLI’s --format flag (table, record, json, jsonl, csv) renders
locally after download — same UX as ever, no server involvement. The compact
table view is a display-time projection; json, jsonl, and csv always
carry every column. See the CLI guide.
betflux get closing-lines --game NBA_GSW_MIA_20260401 --format csv > lines.csv