CLI
Install the CLI with uv tool install betflux for automatic updates on Linux
and macOS. pip install betflux also installs the CLI, without automatic
updates. It reads BETFLUX_API_KEY (override with --api-key; --base-url
overrides the host).
Updates
Section titled “Updates”On verified Linux and macOS uv tool install betflux installations, BetFlux
checks for updates before data commands about once per day and installs
an eligible stable release automatically. This may occasionally delay command
startup. The updater does not mutate project or pip installations, temporary
uvx runs, or installations it cannot verify. Use uv to install and own the
CLI environment. It preserves the installation’s version constraints and
package source; uv may also change dependency versions within those
constraints. Pinned installations update only when a compatible release is
available. uv upgrades are not atomic and do not roll back automatically. If
an upgrade leaves the tool unusable, repair it with
uv tool upgrade betflux --reinstall.
Set BETFLUX_NO_AUTO_UPDATE=1 to disable automatic updates for one process,
including in CI or scripts. Persistent preference and manual update commands
are available:
betflux auto-update statusbetflux auto-update offbetflux auto-update onbetflux update # check and install now, even if auto-update is offbetflux update --check # check onlyThese controls, --help, and --version do not trigger an automatic network
check. Automatic update progress is written to stderr; an unsuccessful
automatic check lets the requested command continue. Explicit update failures
return a nonzero status. Coordination applies to BetFlux launches in the same
verified tool installation; external package-manager operations and older
pre-updater processes are outside that coordination.
Only the CLI launcher performs these checks. Importing betflux or using the
Python SDK never triggers an update.
Common commands
Section titled “Common commands”betflux keys check # tier, rate limit, and monthly usage via GET /v1/mebetflux datasetsbetflux leaguesbetflux teams --league NBAbetflux players --league NBA --team-id <team-uuid>betflux games --league NBA --date-from 2026-04-01 --date-to 2026-04-07betflux games --id NBA_GSW_MIA_20260401betflux get closing-lines --league NBA --date-from 2026-04-01 --date-to 2026-04-07betflux get market-results --game MLB_BOS_NYY_20260715 --outcome WONbetflux get sportsbook-lines --game MLB_BOS_NYY_20260715 --output lines.parquetbetflux get game-state-timeline --game NBA_GSW_MIA_20260401betflux get
Section titled “betflux get”betflux get <dataset> queries one of the four datasets. The payloads are
per-game Parquet files; the CLI downloads them and evaluates filters and
rendering locally.
| Dataset | Addressing |
|---|---|
closing-lines, market-results |
Date range (--league --date-from --date-to) or --game |
game-state-timeline, sportsbook-lines |
--game only |
sportsbook-lines is --game-only by policy, not shape: quota is debited
per file downloaded, and one game is ~190k rows — a range pull would debit
that for every game in the window. The CLI says so if you try.
| Option | Meaning |
|---|---|
--league, --date-from, --date-to |
Range query (ET game_date, inclusive); the CLI discovers games via /v1/games and fetches each game’s file |
--game <id> |
One game (public id) |
--operator, --market-type, --team, --player-id, --side |
Local filters — applied after download, so they don’t reduce quota spend |
--outcome |
market-results only: WON, LOST, PUSH, INDETERMINATE |
--limit N |
Range queries: stop after N rows — no further game files are fetched, so it caps quota spend too |
--output PATH |
With --game: save the raw Parquet file instead of rendering rows |
--no-progress |
Suppress the progress display (also BETFLUX_NO_PROGRESS=1) |
--player-id matches either player-ID list on closing-lines, market-results,
and sportsbook-lines. Rows that match both lists are returned once.
A filter the dataset has no column for is rejected up front, and flag
combinations the request would ignore (e.g. --output with filters) are
errors rather than silent no-ops.
While a get runs interactively, progress renders to stderr: game
discovery, a per-game bar for range pulls, per-file byte progress, and any
retry waits (rate limits, transient server errors). stdout carries only the
result, so piping or redirecting jsonl/csv output stays byte-clean; when
stderr is not a terminal the display turns off automatically.
Saving raw files: --output
Section titled “Saving raw files: --output”$ betflux get sportsbook-lines --game MLB_BOS_NYY_20260715 --output lines.parquetwrote lines.parquet — sportsbook-lines for MLB_BOS_NYY_20260715: 190,412 rows, ... bytesThe bytes are written untouched — the same artifact curl would save — so
the file is immediately queryable with DuckDB, pyarrow, pandas, or polars.
Output formats
Section titled “Output formats”Rendering is entirely client-side. The default is a compact table showing a curated column subset (the datasets are wide). Reshape it:
| Flag | Effect |
|---|---|
--wide |
Table with every column |
--columns game_date,operator,side,closing_odds |
Pick exact columns |
--format record |
Vertical key: value blocks — ideal for one wide row |
--format json|jsonl|csv |
Machine formats, always full-fidelity |
Table and record views are display projections only; json, jsonl, and
csv always carry every column. With --format jsonl|csv on a range query,
rows stream as each game’s file arrives instead of waiting for the whole
window. Timestamps render as ISO 8601 in every format.
betflux get closing-lines --game NBA_GSW_MIA_20260401 --format jsonl > lines.jsonlbetflux keys check
Section titled “betflux keys check”Validates the key against GET /v1/me and prints your standing — it works
even when your monthly quota is spent:
key valid (https://api.betflux.ai)tier: Beta — 120 requests/minusage: 12,345 rows this month (no row cap on this plan)Tiers with a configured row cap also see the percentage used and the reset date.