BBBetBotResearch Command Center

Settings Status

Every BetBot configuration setting, what it does, and how to change it. Secret values are never displayed — only whether they are configured.

System: Warning
Data Mode
Unknown (live_or_external)

Selects whether BetBot uses bundled sample data or live providers. Sample mode never makes a network call and is the safe default for demos.

How to change it
Set BETBOT_DATA_MODE=sample (default) or BETBOT_DATA_MODE=live in your .env file.
Real Decisions
Disabled (default)

When enabled, Simple Mode shows model-driven picks promoted from the decision engine instead of the seeded demo card. Off by default for safety so demos stay reproducible.

How to change it
Off is the safe default. Set BETBOT_ENABLE_REAL_DECISIONS=true in your .env only if you have built and validated a model you trust.
Real Decisions Preview Mode
Always On (read-only)

Preview mode lets you inspect model-driven picks without changing Simple Mode. It reuses the engine's existing decision and moneyline previews and never sends alerts.

How to change it
Open Analyst Mode → 'Real Decisions Preview' to inspect what BetBot would pick. To promote those picks into Simple Mode, set BETBOT_ENABLE_REAL_DECISIONS=true in your .env.
Alerts
Disabled (default)

Controls whether the daily pipeline is allowed to send the card preview to a Discord webhook / Telegram chat / email. The UI never sends alerts even when this is enabled.

How to change it
Off is the safe default. Set BETBOT_ALERTS_ENABLED=true and configure one of: BETBOT_DISCORD_WEBHOOK_URL, BETBOT_TELEGRAM_BOT_TOKEN + BETBOT_TELEGRAM_CHAT_ID, BETBOT_EMAIL_TO.
Odds Provider
External (The Odds API)

Source of sportsbook odds for the slate. 'sample' reads data/sample_odds.json; 'placeholder' is always empty; 'external' calls The Odds API and falls back to cache or sample data on failure.

How to change it
Set BETBOT_ODDS_PROVIDER=sample (default), placeholder, or external in your .env. External requires BETBOT_ODDS_API_KEY.
Odds API Key (BETBOT_ODDS_API_KEY)🔒 Secret
Configured

Optional API key for the external odds provider. Without this, BetBot stays in sample mode and runs normally. With it, BetBot can call the external odds API (or use its cache).

How to change it
Add `BETBOT_ODDS_API_KEY=your_key_here` to your .env file. BetBot only reads the variable — it never displays the value.
Public Data Provider (ESPN / Sample)
Sample (bundled JSON)

Provider that supplies team schedules and recent stats. ESPN's public scoreboard requires no API key. Sample uses bundled JSON.

How to change it
Set BETBOT_PROVIDER=sample (default), espn, or placeholder in your .env. ESPN cache TTL is controlled by BETBOT_ESPN_CACHE_TTL_SECONDS.
Odds Cache (data/cache/odds)
11 cached files

On-disk cache of external odds API responses. Used to avoid burning the rate limit and as a stale-fallback when the API is unreachable. TTL controlled by BETBOT_ODDS_CACHE_TTL_SECONDS.

How to change it
Cache files appear automatically the first time the external provider successfully fetches odds. Safe to delete — they will be regenerated on the next live fetch.
Database (data/betbot.db)
OK · 17 games, 151654 odds rows

SQLite database that stores games, odds snapshots, predictions, decisions, and pipeline runs.

How to change it
Re-seed any time with `python3 scripts/seed_database.py`. Append-only tables keep history across runs.
Latest Pipeline Run
OK · 2026-05-25T14:15:22+00:00

Status of the most recent daily pipeline run, including card-pick count, duration, and source log path.

How to change it
Use the Run Daily Pipeline button in the Pipeline Status section to refresh — alerts are never sent from the UI.
Odds Freshness
Fresh · 0 min old

How recently the latest odds batch was collected. External odds go stale after 15 minutes; cached external after 30. Sample data is never stale — it's always labeled Sample.

How to change it
Click Run Daily Pipeline (Pipeline Status section) or run `python3 scripts/run_daily_pipeline.py`.
Pipeline Freshness
Stale · 20764 min old

How recently the daily pipeline finished. Stale after 12 hours; Unknown if it has never been run.

How to change it
Rerun via Run Daily Pipeline in the UI or `python3 scripts/run_daily_pipeline.py` in the terminal.
Fallback Inputs Detected
No

Some sections use sample-tagged-as-fallback data when the external odds API failed and no cache was available. Real decisions never auto-promote fallback rows.

How to change it
If unwanted, ensure BETBOT_ODDS_API_KEY is configured and the external API is reachable, then rerun the pipeline.
Sample Inputs Detected
No

Sample data is the safe default. Games / features and / or odds may be sample data — that's expected for demos and is always clearly labeled.

How to change it
Switch to live data via BETBOT_DATA_MODE=live and / or BETBOT_ODDS_PROVIDER=external once you have an API key.
Real Decision Readiness
Not Ready · 76/100

10 pass / 6 warning / 1 fail across the 12-item readiness checklist. This card never enables real decisions — it's a read-only summary of the Analyst-Mode section.

How to change it
Open Analyst Mode → 'Real Decisions Readiness' for the full checklist + manual enable instructions.
Real Decisions Dry Run
Available

Lets you preview the switch without changing any setting. Read-only — never writes to the database, never mutates the environment, never sends alerts.

How to change it
Open Analyst Mode → 'Real Decisions Dry Run' to see what Simple Mode would look like if you flipped BETBOT_ENABLE_REAL_DECISIONS=true. No settings will change.
Real Decisions Safety Gate
Blocking · Blocked

Blocked: BETBOT_ENABLE_REAL_DECISIONS is false.; Model-driven preview card has zero picks.; +2 more (score 76/100, 4 blocker(s), 2 warning(s)).

How to change it
Open Analyst Mode → 'Real Decisions Safety Gate' for the blocker/warning list. The gate never enables real decisions on its own.
Live Bet Card
No Picks · Cached · last refresh 2026-06-09T00:19:58+00:00

Preview-only Live Bet Card surfaced near the top of Analyst Mode. Never enables real decisions and never sends alerts.

How to change it
Click 'Refresh Live Bet Card' in the panel or run `python3 scripts/refresh_live_bet_card.py` from the terminal.
Live Card Quality
No Picks · 0/100

0 qualified · 0 filtered out by Phase 39 quality controls (edge, confidence, odds source, fallback inputs).

How to change it
Refresh the Live Bet Card to recompute quality. Connect a live odds API key and use real model features to push quality from Cached/Medium toward Strong.
Player Props Provider
External

Source of player-prop odds. 'sample' reads the bundled demo file; 'placeholder' returns nothing; 'external' calls The Odds API per-event prop endpoint. Defaults to sample.

How to change it
Set BETBOT_PLAYER_PROPS_PROVIDER=sample / placeholder / external in your .env.
Player Props Status
Cached · 388 prop(s)

Whether live player props are reachable from the configured provider today. Available = props returned; Cached = served from the file cache; Missing Key = no API key; Not Available = provider couldn't return props (often a plan limitation).

How to change it
Open Analyst Mode → 'Live Player Props Test' for the full diagnostic. To probe from the terminal: `python3 scripts/test_player_props_provider.py`.
Player Props Cache
9 cached file(s)

On-disk cache for per-event player-prop responses at data/cache/player_props/. TTL controlled by BETBOT_PLAYER_PROPS_CACHE_TTL_SECONDS.

How to change it
Cache files appear automatically after the first successful external props fetch. Safe to delete — they'll regenerate.
Include Live Props in Live Card
Disabled (default)

When enabled, qualified live player-prop picks may appear on the Live Bet Card alongside team markets. Default off.

How to change it
Set BETBOT_INCLUDE_LIVE_PLAYER_PROPS_IN_LIVE_CARD=true in your .env to opt in.
Live Player Props Card Status
Cached · 1 pick(s) · 388 prop(s) fetched

Preview-only player props card built from external prop odds. Sample props never feed this card.

How to change it
Refresh from the terminal: `python3 scripts/refresh_live_player_props_card.py --fresh`.
Live Market Scanner Status
Available · 1 event(s) · 9 book(s) · 314 best-price row(s) · 807 near-miss(es)

Preview-only Best Price Board across sportsbooks, plus picks that almost passed the Live Bet Card rules. The scanner never places bets, never sends alerts, and never writes the official card.

How to change it
Refresh from the terminal: `python3 scripts/scan_live_markets.py --fresh --include-props`.
Props Included in Scanner
Enabled (default)

Whether the Live Market Scanner attempts to fetch live player-prop best prices. Props are only fetched when the Player Props provider is set to 'external' — sample / placeholder always return empty.

How to change it
Set BETBOT_MARKET_SCANNER_INCLUDE_PROPS=false in your .env to skip props during the scan.
Live Market Shortlist Status
Available · 10 price-shop(s) · 5 near-miss(es) · 8 watchlist · 10 avoid

Preview-only Best Opportunities Shortlist re-organized from the Live Market Scanner. Best price shops are line-shopping info — never auto-promoted to the official card. No alerts sent.

How to change it
Refresh from the terminal: `python3 scripts/build_live_market_shortlist.py --fresh --include-props`.
Bet Slip Preview Status
Available · 2 pick(s) · 6 note(s) · 1 game(s) · 0.25u total

Preview-only Bet Slip Builder. Aggregates Live Bet Card + Live Player Props picks + Best Opportunities Shortlist Closest-to-Pick rows + Best Price Shop notes into a single review surface. Never connects to a sportsbook account, never places bets, never writes the official card, never sends alerts.

How to change it
Refresh from the terminal: `python3 scripts/build_bet_slip_preview.py --include-shortlist`.
Export Tools Status
Available · 3 format(s) · exports/ folder ready

Preview-only export tools for the Live Bet Card, Live Player Props Card, Best Opportunities Shortlist, and Bet Slip Preview. Supports txt / markdown / json. No alerts are sent. No sportsbook connection. Exports are scrubbed for any configured secret value before being returned.

How to change it
Open Analyst Mode → 'Export & Review Packet' to download a packet, or run from the terminal: `python3 scripts/export_review_packet.py --format json --output exports/review_packet.json`.
Preview Pick Tracker Status
Available · tracked=1 · graded=1 · pending=0 · net +0.00u

Preview-only Pick Tracker. Captures Live Bet Card / Live Player Props / Bet Slip picks for later manual grading. Price-shop notes are never tracked as bets. Writes are CLI-only — the UI never persists tracking rows.

How to change it
Run `python3 scripts/track_preview_picks.py` (dry-run) or `python3 scripts/track_preview_picks.py --write` to persist.
Results Provider
Espn

Source of final scores for auto-grading. 'sample' reads data/sample_results.json; 'placeholder' returns nothing; 'espn' calls the public scoreboard endpoint. Defaults to sample.

How to change it
Set BETBOT_RESULTS_PROVIDER=sample / espn / placeholder in your .env.
Results Cache
4 cached file(s)

On-disk cache for final-scores responses at data/cache/results/. TTL controlled by BETBOT_RESULTS_CACHE_TTL_SECONDS.

How to change it
Cache files appear automatically after the first successful results fetch. Safe to delete — they'll regenerate.
Auto-Grading Status
Available · team 1 · props 0 (manual) · graded 1

Preview-only auto-grader for tracked team-market picks (Moneyline / Spread / Total). Player props remain manual until a player-stat source is wired. The UI never writes grades — writes are CLI-only.

How to change it
Run `python3 scripts/grade_tracked_picks.py --dry-run` to preview or `--write` to persist.
ESPN Results Status
Available · supports MLB, NBA, NCAAB, NFL, NHL

Preview-only ESPN public-scoreboard integration. Used for automatic team-market grading. Never authenticates, never calls a sportsbook account, never sends alerts. On network failure, falls back to the stale results cache when available.

How to change it
Set BETBOT_RESULTS_PROVIDER=espn in your .env to use ESPN as the default; otherwise call `python3 scripts/test_espn_results.py --league NBA`.
Latest ESPN Results Fetch
OK · espn__nba__2026-06-04__4466e7ba06.json · 98 hr(s) old

Newest cached ESPN scoreboard response under data/cache/results/. Read-only — used by the auto-grader on cache hit.

How to change it
Run `python3 scripts/test_espn_results.py --league NBA --fresh` to force a new fetch.
Results Matching Status
team picks pending 0 · final game_results rows 26650

Read-only summary of how many tracked team-market picks are still pending vs how many final game_results rows are available for matching. The matcher leaves a pick pending when match confidence is below 0.60 — BetBot never grades a pick it can't safely match.

How to change it
Run `python3 scripts/grade_tracked_picks.py --provider espn --dry-run` to see what would be graded.
Performance Dashboard Status
Available · 1 tracked · 1 graded · 0 pending · W0-L0 · wr — · net +0.00u · ROI +0.00%

Preview-only performance dashboard. Pushes and voids are excluded from the win rate; pending picks are never counted. Player props remain manual-only.

How to change it
Open Analyst Mode → 'Performance Dashboard' or run `python3 scripts/show_performance_dashboard.py`.
Live Command Center Status
Available · preview-only quick actions

Top-of-page command center that ties together Live Bet Card, Best Opportunities Shortlist, Bet Slip Preview, Export, Track, Results & Grading, and Performance. All quick-action buttons are preview / dry-run only — no bets, no alerts, no real-decision toggling, no official_cards writes, no sportsbook integration. Tracking writes stay CLI-only.

How to change it
Open Analyst Mode → 'Live Command Center' at the top of the page.
Demo Walkthrough Status
Available · 8 steps

Beginner-friendly 8-step walkthrough surfaced near the top of Analyst Mode. Read-only — no IO, no buttons, no state. BetBot does not place bets.

How to change it
Open Analyst Mode → 'Demo Walkthrough' (Beginner / Full Analyst / Developer view all show it).
Release Checklist Status
Needs Review · pass 11 · warning 2 · fail 0

Preview-only release-readiness audit. Verifies API keys, providers, pipeline health, exports, tracking, Simple Mode safety, alerts, no auto-betting code, secrets not leaked, no banned words. Never modifies settings or the database.

How to change it
Open Analyst Mode → 'Release Checklist' or run `python3 scripts/release_check.py`.
Analyst View Mode
Selectable · Beginner / Full Analyst / Developer

Sidebar 'View Detail' selector controls which Analyst-Mode sections render. Beginner = workflow only; Full Analyst = current default; Developer = adds raw / duplicate debug surfaces.

How to change it
Use the sidebar 'View Detail' radio (defaults to Full Analyst View).
Daily Live Report Status
Available · 0 live pick(s) · 6 price shop(s) · 8 slip item(s) · 0 warning(s)

Consolidated daily output that ties the Live Bet Card, Best Opportunities, Bet Slip Preview, tracker summary and performance snapshot into one read-only view. Refresh button + downloads never enable real decisions, never send alerts, never write the official card, and never persist tracking rows.

How to change it
Open Analyst Mode → 'Daily Live Report' or run `python3 scripts/daily_live_report.py --fresh`.
Final QA Status
Ready · pass 10 · warning 0 · fail 0

Latest snapshot from scripts/final_qa_check.py (generated_at: 2026-05-20T23:48:12+00:00). Read-only — the UI never re-runs the sweep.

How to change it
Run `python3 scripts/final_qa_check.py` to refresh.
Freeze Status
Candidate · build=phase-60-freeze-candidate

Freeze checkpoint state. Phase 60 marks the freeze candidate — daily-use ready and demo ready. See docs/FREEZE_MANIFEST.md for the full manifest.

How to change it
Run `python3 scripts/freeze_check.py` to verify the freeze candidate state.
Team Stats Provider
Missing

Source of recent_win_pct / point_diff_last_5 / rest_days. 'sample' returns bundled JSON (clearly labeled). 'espn' derives features from the public team schedule (missing fields stay None — we never invent sample values). 'external_placeholder' is the typed slot for a paid feed. 'disabled' returns nothing. **In live-only mode, ESPN is never silently replaced with sample data** — if ESPN has no rows we report Missing instead.

How to change it
Set BETBOT_TEAM_STATS_PROVIDER=espn (recommended free default) or external_placeholder once a paid feed is wired.
Team Stats Provider Status
Missing

Phase 66 quick-glance label: ESPN / Partial ESPN / Missing / Sample / Disabled. Reflects today's actual probe.

How to change it
Run `python3 scripts/real_context_health.py` to diagnose.
News / Injury Provider
Cached ESPN

Source of injury / news rows. Phase 65 adds the live ESPN league-news adapter (`espn`) with stale-cache fallback (`Cached ESPN`). Placeholder modes always return empty lists with label `Missing` — BetBot never invents news. Picks downgrade when records are missing.

How to change it
Set BETBOT_NEWS_PROVIDER=espn for live data, espn_placeholder / external_placeholder for typed slots without a feed, or disabled to silence the section.
News / Injury Provider Status
Cached ESPN

Phase 65 quick-glance label: ESPN Connected / Cached ESPN / Missing / Disabled / Placeholder. Reflects the live state of the news adapter at app open.

How to change it
Run `python3 scripts/test_news_injury_provider.py --league NBA --provider espn` to diagnose.
Real Context Mode
Inactive

Phase 66 — Real Context Mode is ON when live-only mode is on AND both news + team-stats providers are set to `espn`. Activate with `scripts/activate_real_context_mode.py --write` (it never touches your API key).

How to change it
Run `python3 scripts/activate_real_context_mode.py` to preview, then `--write` to apply the safe provider flags.
Missing Context Warnings
1 warning(s)

Summary of which intelligence layers are weak / missing. Live-only candidates downgrade automatically when these warnings fire (see the Daily Live Report card notes).

How to change it
Team stats are `Missing` — picks affected by weak team context are downgraded.
Real Data Sources Needed
Odds: Connected · Player Props: Connected · Results: ESPN · Team Stats: ESPN partial · News/Injuries: Needs provider

Readiness summary for the live-only workflow. Recommended paid options: SportsDataIO, Sportradar, OddsJam / OpticOdds style providers. Recommended free / partial option: ESPN scoreboard where available. The app is **ready** — you don't need to sign up before using BetBot, but live picks will downgrade until the missing sources are wired.

How to change it
See docs/DAILY_RUNBOOK.md for provider recommendations. No paid sign-up is required to keep using BetBot.
Stats Provider
ESPN Connected

Phase 67 — real team/player stats provider. ESPN fills wins / losses / win_pct / per-game points / point diff when available; missing fields stay None (BetBot never invents stats). Paid placeholders (sportsdataio / sportradar) reserve typed slots.

How to change it
Set BETBOT_STATS_PROVIDER=espn for live data, or one of the placeholders for typed slots, or disabled to silence the section.
Player Context Provider
Partial ESPN

Phase 68 — real player context (roster, injury status, per-game averages where ESPN supplies them). Missing fields stay None (BetBot never invents player stats). Paid placeholders (sportsdataio / sportradar) reserve typed slots for future real wiring.

How to change it
Set BETBOT_PLAYER_CONTEXT_PROVIDER=espn for live data, one of the placeholders for typed slots, or disabled to silence the section.
Odds Provider Recovery
The Odds API · Cached Only · cache=Yes · quota=Unknown

Phase 73 — surfaces the current named odds provider (from BETBOT_ODDS_PROVIDER_NAME), its health (OK / Cached Only / Unauthorized / Quota Low / Missing), cache + quota state, and the recovery recommendation. Recommendation: Live odds feed is on cached data. Run a fresh refresh when ready.. Alternate providers: 3 typed slot(s) — Not configured.

How to change it
Run `python3 scripts/odds_recovery_guide.py` for detailed next steps. For a live probe, use `scripts/odds_provider_health.py --check-live`.
Main Output Status
Daily Live Report

Daily Live Report is now the first major section after the status banner in Analyst Mode. Beginner View shows the curated daily output (Daily Live Report → Live Command Center → Live Bet Card → Best Opportunities → Bet Slip → Export → Performance → Help). Older / developer sections live in Full Analyst + Developer tiers.

How to change it
Use the sidebar 'View Detail' radio to switch between Beginner / Full Analyst / Developer.