BetrPicks
Props
0
Betr Best
0
Obs saved
0
๐Ÿ“Š
Set filters, then click Fetch Lines
Hit Fetch Lines to load Betr standard props ranked by PP value
Hit Run Scan to find edges and build a slip
Distribution Curves

Enter a standard line to see the market prior curve. Add a player to overlay their historical distribution.

Season
Market
Player
Games
Standard line
Enter a standard line to view curveoptionally add a player to overlay historical data
Loading...
Payout Reference

Break-even probability is the per-leg win rate needed for EV = 0. Flex Play accounts for all partial payout tiers in the calculation.

Loadingโ€ฆ
API Reference
Railway: betr-picks-production.up.railway.app
MethodEndpointTriggered byDescriptionntfy?
GET/healthโ€”Ping โ€” returns {status: "ok"}โ€”
POST/refresh-tokentoken-refresh service (8 min) / Vercel "Refresh Token" btnAccepts fresh JWT, updates in-memory cache + PP_JWT_CACHE env var, clears backoff. Body: {token, exp}โ€”
GET/token-statusโ€”JWT validity and seconds until expiryโ€”
GET/screener-statusโ€”Last screener run time, edge count, alert status, backoff remainingโ€”
GET/screener-edgesScreener tabEdges from the most recent screener run. Reads Supabase edges table (falls back to in-memory) so it survives restarts.โ€”
POST/screenDirect call onlyManually trigger a full screener scan across all SCAN_MARKETS. Returns edges found, sends ntfy push if any.โ˜…
GET/betr-active-leaguesDirect call onlyEvery league live/upcoming on Betr right now + whether we have a PP market mapping for it yet. Cached 10 min.โ€”
POST/fetch-linesLines tab "Fetch Lines"Fetches one market+league from PP Screen. Saves prop_observations to Supabase. Body: {market, league, books, is_live, season}โ€”
GET/payout-referencePayout tabPayout reference table (perfect play + flex, all pick counts)โ€”
GET/market-cv-curvesMkt Curves tab (hidden from nav)Hardcoded vs. calibrated CV buckets + power-law fit per market, for the curve explorer chart. Feeds off market_cv_calibrated/curve_fits (NBA-driven, empty off-season).โ€”
GET/slip-builderSlip Builder "Run Scan"Full screener scan + fantasy fetch grouped by game with same-game complements. No alert sent.โ€”
GET/ref-detailFantasy tab (row expand)Reference-book odds for one player/market/line. Params: player, market, league, lineโ€”
GET/fantasy-linesFantasy tab "Fetch Lines"All Betr standard props from PP fantasy optimizer, sorted by value% descโ€”
GET/discover-marketsDirect call onlyBatch-probes candidate market names across leagues. Returns hits (has Betr Alt) and misses. Add ?league=Soccer to scope to one league. Slow (~2-5 min full run).โ€”
GET/debug-gridDirect call onlyRaw alt-line grid + curve fit for one player/market, across CURVE_BOOKS + DK/FD/Pinnacle. Used to validate curve math. Params: player, market, leagueโ€”
Background Processes
โ˜…Screener loop
Runs every 6โ€“10 min (random jitter) during 8amโ€“10pm PT. Scans NBA, NCAAB, NHL, Soccer, MLB, WNBA, Tennis. Sends ntfy push on any edges found. 90s startup delay to absorb rapid Railway redeploys. Escalating backoff on PP rate limit (3m โ†’ 10m โ†’ 30m).
External Dependencies
ServicePurposeNotes
Prop ProfessorProp line data + devigJWT (10 min TTL) via session cookie. Session cookie itself expires ~30 days โ€” rotate PP_SESSION_TOKEN before then. Rotates on new browser login โ†’ urgent ntfy fires โ†’ tap Refresh Token on Vercel.
Betr GraphQL (api.fantasy.betr.app)Real boost tiers, straight from BetrUnauthenticated, anonymous โ€” public prop board data only, never Betr's logged-in surface. src/betr_client.py. Covers MLB, WNBA, Tennis, NFL, Soccer(MLS), UFC via LEAGUE_MAP. Falls back to odds-shape estimate when unmapped.
SupabasePostgres โ€” prop_observations, edges, curve_fitsLines tab writes prop_observations. Screener logs edges + curve_fits. market_cv_calibrated/curve_fits are NBA-driven and empty off-season.
ntfy.shPush alerts to iOSTopic: betrounds. urgent = session expired. high = rate limited or 3+ edges. default = <3 edges.
RailwayFastAPI host (amiable-nature) + token-refresh servicePP_SESSION_TOKEN, PP_JWT_CACHE, SUPABASE_URL, SUPABASE_SERVICE_KEY, NTFY_TOPIC. token-refresh runs on a separate Railway service with a fresh IP pool, pushes JWT every 8 min via /refresh-token.
VercelNext.js frontend (sports.roundscapital.co)Auto-deploys from GitHub main. NEXT_PUBLIC_API_URL must point to Railway URL.