Skip to main content

betflux

Python client + CLI for the BetFlux data API — normalized sportsbook odds across US books, queryable for sharp bettors.

Install

pip install betflux            # core client + CLI
pip install "betflux[pandas]"  # add .df() DataFrames

Authenticate

Set your API key (mint one at betflux.ai/account/api-keys):

export BETFLUX_API_KEY=bfx_live_...

The file model

Every dataset payload is a per-game Parquet file served at GET /v1/games/{game_id}/{dataset} — the server streams typed, compressed bytes (with HTTP Range support) and never filters. The SDK/CLI keep their query interfaces: they discover game ids via /v1/games, download each game's file, and evaluate your filters locally with pyarrow (a core dependency). Quota is metered as rows downloaded, so narrow date ranges and --game fetches are the cheap path — local filters don't reduce spend.

Datasets: closing-lines, market-results (graded closing lines), sportsbook-lines (the full ~190k-row change-only line history per game), game-state-timeline (flat ts/field/value/source observation rows).

CLI

betflux keys check
betflux datasets
betflux games --league NBA --date-from 2026-04-01 --date-to 2026-04-07
betflux get closing-lines --league NBA --date-from 2026-04-01 --date-to 2026-04-07
betflux get closing-lines --game NBA_GSW_MIA_20260401 --format jsonl
betflux get market-results --league MLB --date-from 2026-07-01 --date-to 2026-07-07 --outcome WON
betflux get sportsbook-lines --game MLB_BOS_NYY_20260715 --output lines.parquet
betflux get game-state-timeline --game NBA_GSW_MIA_20260401
betflux leagues
betflux teams --league NBA
betflux players --team-id <team-id>

Game ids are readable — LEAGUE_AWAY_HOME_YYYYMMDD (ET date; a _2 suffix marks doubleheaders), case-insensitive, discoverable via betflux games. Internal UUIDs are accepted everywhere a game id is.

closing-lines and market-results accept a date range or --game; game-state-timeline and sportsbook-lines are --game only (sportsbook-lines over a range would debit ~190k quota rows per game). Filters (--operator, --market-type, --team, --player-id, --side, --outcome) run locally after download; a filter the dataset has no column for is rejected up front. --limit N stops fetching once N rows have been yielded. With --format jsonl|csv rows stream as each game's file arrives.

--output PATH (with --game) saves the raw Parquet file for any dataset — no parsing, one summary line with the row count:

wrote lines.parquet — sportsbook-lines for MLB_BOS_NYY_20260715: 190,412 rows, 8,214,567 bytes

Timestamp columns are real Parquet timestamps and render as ISO 8601 in every output format.

Output defaults to a compact table showing a curated column subset (the gold datasets are wide). Widen or reshape it:

  • --wide — every column in the table
  • --columns game_date,operator,side,closing_odds — pick columns
  • --format record — vertical key: value blocks, ideal for one wide row
  • --format json|jsonl|csv — machine formats (always full-fidelity)

betflux keys check validates the key and reports your plan:

key valid (https://api.betflux.ai)
tier: Beta — 120 requests/min
usage: 12,345 / 50,000 rows this month (25%) — resets 2026-08-01

Library

from betflux import Client

with Client() as bf:
    for row in bf.closing_lines.iter(
        league="NBA", date_from="2026-04-01", date_to="2026-06-30",
        operator="FANDUEL",  # local filters: operator/market_type/team/player_id/side/outcome
        max_rows=10_000,     # stop fetching once this many rows yielded; default None = all
    ):
        print(row["market_key"], row["closing_odds"])

    games = bf.games(league="NBA", date_from="2026-04-01", date_to="2026-04-07")
    df = bf.closing_lines.df(league="NBA", date_from="2026-04-01", date_to="2026-04-07")
    game_rows = bf.market_results.game(games[0]["id"], outcome="WON")
    observations = bf.state_timeline(games[0]["id"])  # flat rows; ts is epoch-ms
    raw = bf.sportsbook_lines.raw(games[0]["id"])     # the Parquet bytes, verbatim

Datasets hang off the client as closing_lines, market_results, sportsbook_lines, and game_state_timeline (or bf.dataset("closing-lines") by public name). Timestamp/date columns come back as Python datetime/date objects (pyarrow decodes the Parquet types), not ISO strings. Filters that name a column the dataset lacks raise ValueError; team matches home or away, player_id matches the market/selection player-id list columns.

Errors are typed (AuthError, PaymentRequiredError, RateLimitError, QuotaExceededError, NetworkError, …); rate limits, 5xx, and transport failures retry automatically with backoff that honors Retry-After (capped).

Breaking changes (Parquet cutover)

  • iter() lost page_size — there is no server pagination to tune anymore.
  • Client.state_timeline() returns the flat observation rows (list[dict]) instead of the old {..., observations: [...]} envelope.
  • Timestamps in rows are datetime objects, not ISO strings.

Power user: DuckDB straight at the files

The dataset endpoints are plain authenticated Parquet URLs with Range support, so DuckDB can query them directly — 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, timestamp
FROM read_parquet('https://api.betflux.ai/v1/games/MLB_BOS_NYY_20260715/sportsbook-lines')
WHERE market_type = 'MONEYLINE'
ORDER BY timestamp;

Note: quota is debited for the file's full row count per request, partial read or not.

Release files for betflux 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for betflux 0.1.1
File Size Uploaded
betflux-0.1.1.tar.gz 31.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for betflux 0.1.1
File Interpreter ABI Platform
betflux-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 63.0 kB

Release files / betflux-0.1.1.tar.gz

Download URL betflux-0.1.1.tar.gz
Size 31.6 kB
Tags Source
SHA-256 checksum
How to use checksums
d720c683b3cd7ebeb89dd26213c5d0269c783cb5ccb3f52ef4f8f397c9c6c21a
BLAKE2b-256 checksum
How to use checksums
bf622439a547263099d50cc42dbc7bd31472b5cb0d7c8b021bafdd35a61c4b28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release files / betflux-0.1.1-py3-none-any.whl

Download URL betflux-0.1.1-py3-none-any.whl
Size 31.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3e119589cbe626d1e6d22494e52aacb6b6b65f754d2646adcd5c7b285e0c3c7e
BLAKE2b-256 checksum
How to use checksums
99213cf9e5e0216244e8fe92e7961a296fbba10c8a50e9cbc7e79949855999a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page