Member API

Pull MKB's fair values, EV and Kelly sizing, the best book and its price, settled results, our player projections and model probabilities (including MLB MIQ), DvP, fantasy projections and game projections into your own spreadsheets and tools. Included with All Access.

Create a key at Dashboard → API Access. Use of the API is covered by Section 6A of our Terms: keys are personal, and API data is for your own use only.

Authentication

Send your key in the Authorization header on every request (or as X-API-Key). Never put it in a URL, a shared sheet or public code. If a key may have leaked, revoke it from your dashboard: it stops working on its next request.

curl -H "Authorization: Bearer $MKB_API_KEY" \
  "https://www.mama-knows-bets.com/api/v1/nba/board?min_kelly=0.0001&limit=500"

Endpoints

{sport} is one of mlb, nfl, nba, nhl, wnba, ncaaf, soccer, futures. Results and projections are available for mlb, nfl, nba, nhl, wnba; fantasy and DvP for nfl, nba, nhl; game projections for nba, nhl, wnba, nfl. /status lists what each sport offers.

EndpointWhat it returnsCounts toward quota
GET /{sport}/boardThe live Value Finder boardYes
GET /all/boardBest of All: +EV across every sport, or where to use a promoYes
GET /all/insightsBest of All Insights: the day's biggest moves on MLB, NFL, NBA, NHL and what our data shows around themYes
GET /{sport}/resultsSettled bets, one row eachYes
GET /{sport}/results/summaryAggregated results by date, book, market, side and lineYes
GET /{sport}/projectionsPlayer projections and model probabilitiesYes
GET /{sport}/fantasyFantasy points (DraftKings) with their distribution and scoring inputsYes
GET /{sport}/gamesGame projections: projected scores, total and game probabilitiesYes
GET /{sport}/dvpDefense vs position (DvP HQ)Yes
GET /nfl/team-defenseNFL coverage, pressure and red-zone defenseYes
GET /{sport}/statusWhen the board last updatedNo
GET /usageYour plan, quota and what's leftNo

Base URL: https://www.mama-knows-bets.com/api/v1

Board

All filters are optional and can be combined. A misspelled or malformed one is refused with a 400.

ParameterWhat it doesExample
market_typeExact marketmarket_type=player_points
sideOver / Under / Yes / Noside=Over
game_dateSlate date (ET)game_date=2026-10-27
playerPlayer name containsplayer=tatum
gameGame contains (either team)game=celtics
team / opponentThe player's team or opponent (MLB, NFL, NBA, NHL, WNBA)team=BOS
line_valueExact lineline_value=24.5
min_line / max_lineLine rangemin_line=19.5&max_line=29.5
min_odds / max_oddsBest-price range, American oddsmin_odds=-150&max_odds=300
min_evMinimum EV %min_ev=3
min_kellyMinimum stake in units (0.0001 = +EV only)min_kelly=0.0001
min_coverageMinimum books pricing the linemin_coverage=6
best_bookBest price is at this bookbest_book=FD
leagueSoccer and futures onlyleague=epl
selectionFutures only, instead of playerselection=thunder
sort / orderev, kelly, odds or game_time; asc or desc (ev/kelly/odds default desc, game_time asc)sort=ev&order=desc

team and opponent come from our player projections, matched by player and game date, and use the same abbreviations as /projections. When a player can't be matched (no projection that day, such as an injured player, a defense/special-teams line or a market like "No Touchdown"), both are empty: we never guess. On a normal day nearly every MLB, NBA, NHL and WNBA row has a team. NFL rows for games more than a few days out get theirs when that week's projections are published. NCAAF, soccer and futures have no projections, so they refuse team/opponent; use game there. Sorting always breaks ties the same way, so paging through a sorted board never skips or repeats a row.

With no filters you get the whole board, including lines with no edge. Most rows have none, so min_kelly=0.0001 (+EV only) is usually what you want, and it keeps you well inside your quota.

{
  "status": "ok",
  "sport": "nba",
  "mode": "pinned",
  "consistency": "single_run",
  "run_timestamp": "2026-10-21T15:02:02.666563+00:00",
  "as_of": "2026-10-21T15:02:02.666563+00:00",
  "board_age_minutes": 6,
  "stale": false,
  "total_count": 541,
  "count": 500,
  "next_cursor": "eyJ2IjoxLCJhIjoi...",
  "data": [
    {
      "id": "…",
      "player_name": "…",
      "market_type": "player_points",
      "side": "Over",
      "line_value": 24.5,
      "best_book": "fd",
      "best_book_odds": 120,
      "fair_value_odds": 108,
      "ev_percentage": 5.77,
      "kelly_standard": 0.0961,
      "kelly_confidence_adjusted": 0.0836,
      "market_coverage": 9,
      "coverage_weight": 0.87,
      "…": "…"
    }
  ]
}

My books only

books=FD,DK,MG counts only those books; exclude_books=KS,NV,PX counts every book except those. Best book, best price, EV and stake are recalculated from the books you allow, exactly as the Value Finder's book filter does it. Lines none of your books price are left out. Fair value doesn't change. It's still the whole market's. A price our pipeline flagged as a likely error is never used. For exchanges (Kalshi, Novig, ProphetX), the best book, EV and stake use the price after the exchange's fee: best_book_odds stays the posted price and best_book_net_odds is what you actually get (except futures). Boosts use the book's posted price. You still get only the best price, never a list of every book's. Without these parameters the board returns the best book exactly as our pipeline chose it.

curl -H "Authorization: Bearer $MKB_API_KEY"   "https://www.mama-knows-bets.com/api/v1/nba/board?books=FD,DK,MG,CZ&min_ev=2&sort=ev"

Boosts

Price a promo the way the site's boost tool does. You get back only the lines that book prices, each with both prices: posted_odds with posted_ev_percentage and posted_kelly (the bet as the book posts it), and boosted_odds (also in best_book_odds) with the boosted ev_percentage and stake. The difference is what the boost adds. Risk-free and bonus-bet modes don't change the price, only its EV.

boost_book=FD&boost_pct=50                         profit boost: +50% on winnings
boost_book=DK&boost_mode=surge&surge_points=100     flat points: +140 becomes +240
boost_book=FD&boost_mode=riskfree                   risk-free bet (optional conversion_rate=75&riskfree_coverage=100)
boost_book=FD&boost_mode=bonusbet                   bonus bet: EV is the conversion %

Every other board filter and sort applies to the re-priced numbers. These requests are worked out from the whole board, so they can take a second or two longer than a plain board request.

Fields

idRow id. Stable within a run; use it with next_cursor, not as a long-term key.
player_name, game_info, game_date, game_timeWhat the bet is on. game_date is the slate date (ET); game_time is ET.
market_type, side, line_valueThe market (e.g. player_points), Over/Under/Yes/No, and the line.
best_book, best_book_oddsThe book with the best price on this line and that price (American odds). Book codes are listed below.
fair_value_oddsMKB's no-vig fair price for this outcome (American odds), from our weighted de-vig across books.
ev_percentageExpected value of betting best_book_odds against the fair value, in percent (3.2 = +3.2%).
kelly_standardKelly stake in units before the confidence adjustment.
kelly_confidence_adjustedKelly stake in units scaled by how much of our fair-value weighting is present on this line. This is the number the Value Finder sorts by.
market_coverageHow many books price this line.
coverage_weightShare (0–1) of our fair-value book weighting that is present on this line.
run_timestampWhen this row was priced (UTC).
team, opponentThe player's team and opponent, from our projections (MLB, NFL, NBA, NHL, WNBA). Empty when the player can't be matched, never guessed.
game_pk (MLB), game_id (NFL), event_id (NCAAF, soccer)Game identifiers. MLB game_pk can be empty.
league, home_team, away_team (soccer)Soccer only.

Futures fields

sport_key, league, market_type, selection, resolution_dateWhat the future is on and when it settles.
fair_probability, fair_value_oddsMKB's fair probability and price. Empty on low-confidence rows.
low_confidence, fv_below_marketFlags: too few books to trust the fair value; fair value shorter than every book.
books_in_consensusBooks that went into the fair value.

Best of All (every sport)

GET /all/board is the site's Best of All page: today's +EV bets across every sport you choose, player props and game lines together. It's ranked by edge_pts: our fair chance of winning minus the chance the price implies, in points. That reads the same at any odds. EV % puts long shots first, Kelly stake puts heavy favorites first, and kelly_confidence_adjusted is scaled differently in each sport. Only +EV rows are returned. Each sport's exchange fees are applied to its own rows.

ParameterWhat it doesExample
sportsWhich sports. Default mlb,nfl,nba,nhl (the site's default). Also wnba, soccer, ncaaf. Golf is on the site only.sports=nfl,nba,soccer
min_coverageMinimum books pricing the line. Default 3; the response counts what it hides, per sport.min_coverage=2
fvFair value to price against: market (default), model, avg (Market Average, reference only: no stakes), or book:XX (one book's no-vig price). See below.fv=model
books / exclude_booksRe-price from only your books, as on the board abovebooks=FD,DK,MG
sortedge (default), kelly_standard, kelly_confidence_adjusted, ev, odds, game_timesort=ev
sourceprops or game_linessource=props
game_dateSlate date (ET)game_date=2026-11-01
min_odds / max_oddsOdds range, American: the best price on the board; the book's posted price with a promomin_odds=-200&max_odds=300
min_evMinimum EV %min_ev=2
leagueNarrow within sports to leagues: the sport (nba, nfl …) or, for soccer, the competition by code or name (epl, mls, la_liga, "Premier League"). Each row's league fieldsports=soccer&league=epl,mls
marqueetrue = only the site's Marquee Markets: MLB home runs 1+; NFL anytime, first and 2+ TDs; NBA first basket, double double, triple double; NHL anytime, first and 2+ goals; WNBA first basket; soccer anytime goal. The site sorts it by stake (sort=kelly_confidence_adjusted)marquee=true&sort=kelly_confidence_adjusted
curl -H "Authorization: Bearer $MKB_API_KEY"   "https://www.mama-knows-bets.com/api/v1/all/board?sports=mlb,nfl,nba,nhl,soccer&books=FD,DK,MG&limit=50"

Fair value modes

The same FV modes as the site's FV Mode selector. fv=model uses each sport's own model (MLB, NFL, NBA, NHL, WNBA; soccer and NCAAF have none, so their rows are left out). fv=book:PN uses that book's no-vig price as fair value (a line the book doesn't price, or has no no-vig price for, is left out). fv=avg is Market Average, a reference view: ev_percentage is the edge against the plain average of every realistic price and the stakes are null. Anything but market is worked out from every line on the board, not just the ones +EV at market, so it's slower: a few seconds for the default four sports, up to about half a minute with soccer included.

# Today's best bets against our models
curl -H "Authorization: Bearer $MKB_API_KEY" "https://www.mama-knows-bets.com/api/v1/all/board?fv=model&sports=nba,nhl"

# Pinnacle as fair value, game lines only
curl -H "Authorization: Bearer $MKB_API_KEY" "https://www.mama-knows-bets.com/api/v1/all/board?fv=book:PN&source=game_lines"

# Market Average (reference: no stakes)
curl -H "Authorization: Bearer $MKB_API_KEY" "https://www.mama-knows-bets.com/api/v1/all/board?fv=avg&sports=nfl"

# A 50% FanDuel boost, priced against the model
curl -H "Authorization: Bearer $MKB_API_KEY" "https://www.mama-knows-bets.com/api/v1/all/board?boost_book=FD&boost_pct=50&max_stake_units=1&fv=model"

With a boost

Add boost_book (the same boosts as the site's Boost button) and you get every line that book prices on your sports, priced with the boost on that book's own price. It's ranked like the site's boosted board: by stake_units (the recommended stake for the boosted price, capped at your max_stake_units), then by expected_units. It reads the whole board, not just the +EV rows, because a boost can make a line worth betting that isn't +EV without it. A price our pipeline flagged as a likely error is never used.

ParameterWhat it doesExample
boost_bookThe book the boost is on. Switches to boost ranking.boost_book=FD
boost_modeboost (default), surge, riskfree (no-sweat), bonusbetboost_mode=riskfree
boost_pct / surge_pointsThe boost: percent for boost, flat points for surgeboost_pct=50
max_stake_unitsOptional. The promo's max stake in UNITS (the bonus bet's value for bonusbet). Stakes cap at it. Without it, the stake is the recommended (Kelly) stake and a bonus bet counts as 1umax_stake_units=1
conversion_rate / riskfree_coverageNo-sweat only: what $1 of bonus bets is worth to you (default 75) and how much of the stake comes back (default 100)conversion_rate=70
todayToday's games onlytoday=true
min_win_probabilityOnly bets with at least this fair chance of winning (0–1)min_win_probability=0.3
min_odds / max_oddsRange on the book's posted pricemin_odds=100&max_odds=400
sports / min_coverageAs abovesports=nfl,ncaaf
fvAs above: the boost is priced against that fair value. Not avg (it has no stakes)fv=book:PN
marqueeAs above: rank only the Marquee Marketsmarquee=true
# "50% profit boost on FanDuel, max $25" with a $25 unit = max 1 unit
curl -H "Authorization: Bearer $MKB_API_KEY"   "https://www.mama-knows-bets.com/api/v1/all/board?boost_book=FD&boost_pct=50&max_stake_units=1"

# "$20 bonus bet on DraftKings" at a $25 unit = 0.8u, NFL and college football
curl -H "Authorization: Bearer $MKB_API_KEY"   "https://www.mama-knows-bets.com/api/v1/all/board?boost_book=DK&boost_mode=bonusbet&max_stake_units=0.8&sports=nfl,ncaaf"

Fields

sport, source, leagueThe sport, props or game_lines, and the league (soccer competitions, NCAAF).
fv (top level)The fair value the numbers use: market, model, avg or book:XX. With anything but market, fair_value_odds, ev_percentage, edge_pts and the stakes are that FV's. A row with no value under it (no model for the sport, no stored price at that book) is left out.
edge_ptsOur fair win chance minus the win chance the price implies, in percentage points (after exchange fees). 30% fair against a +300 price (25%) is 5.0.
…Every board field above, except team/opponent and the per-sport game ids. Game lines put the bet in player_name ("Green Bay Packers -5.5") with market_type h2h, spreads, totals, alt_spreads or alt_totals.
sourcesEvery chosen sport's props and game-lines board: state (ok, unavailable, no_board), newest_run, age_minutes, stale. A sport that failed to load is listed as unavailable, never left out.
hidden_by_min_coveragePer sport, +EV rows hidden by min_coverage.

Boost fields

posted_odds, promo_oddsThe book's posted price, and the price with the boost. The same for no-sweat and bonus bets, which don't change the price.
win_probabilityFair chance the bet wins (0–1), from MKB's fair value.
promo_ev_percentageEV % of the stake with the promo. For bonusbet, the conversion %: expected cash per $1 of bonus bet.
posted_ev_percentageEV % of the same bet without the promo.
promo_kelly_unitsThe recommended stake for the boosted price, in units, before your max.
stake_unitsWhat you'd bet: promo_kelly_units capped at max_stake_units (a bonus bet: its value).
expected_unitsExpected profit in units at stake_units (a bonus bet: expected cash). Results are ranked by stake_units, then this.
incompletetrue when any chosen sport's board couldn't be read; see sources.

Sports refresh on their own schedules, so this endpoint is "rolling": a long pull can straddle a refresh, which returns a 409 asking you to start again. Pages are worked out from the whole board, so they can take a few seconds.

Insights

GET /all/insights is the Best of All Insights tab as data, refreshed hourly: for MLB, NFL, NBA and NHL, the props and main lines (main spread, total and moneyline) whose market moved most in the last 24 hours. Each mover has move_pts (the like-for-like change in win chance, in points, the boards' Movement column), move_logit (the same move in log-odds, for long shots), prob_then / prob_now, timing (when most of the move happened, or null), other_lines and facts. Each fact has its at time and a relation to the move: after, coincided (both only when the move is timed), today (in our data in the last 24h) or now (current goalie, probable starter or weather). Facts are what our data shows next to a move, never its cause. Parameters: sports (mlb, nfl, nba, nhl; default all four) and section (props or main_lines; default both). Each mover also has direction (up or down), ev_percentage, kelly_confidence_adjusted and history (its fair value and best price over the last 24 hours). Up to 15 movers per sport, section and direction by each ranking (move size and log-odds); the site lists the top 15 across your sports. The site's "Long shots" view (ranked by move_logit) covers props only; main lines are ranked by move_pts.

curl -H "Authorization: Bearer $MKB_API_KEY" "https://www.mama-knows-bets.com/api/v1/all/insights?sports=nba,nhl&section=props"

Results

Yesterday's bets settle after our 6 AM ET results run. Your plan sets how far back you can go.

ParameterWhat it doesExample
date_from / date_toGame dates (default: the last 7 days)date_from=2026-10-01&date_to=2026-10-20
market_type / side / player / gameAs on the boardgame=celtics
team / opponentThe player's team or opponentopponent=NYK
bookThe book the bet was flagged atbook=DK
line_value / min_line / max_lineLinemin_line=0.5&max_line=1.5
min_odds / max_oddsPrice when flagged, American oddsmin_odds=200
min_kellyStake when flagged, unitsmin_kelly=0.01
min_coverageBooks pricing the line when flaggedmin_coverage=5
sort / orderdate, kelly, odds or pl; asc or desc (default desc)sort=pl&order=desc
curl -H "Authorization: Bearer $MKB_API_KEY"   "https://www.mama-knows-bets.com/api/v1/nfl/results?date_from=2026-10-01&min_odds=200&sort=pl"
game_date, player_name, game_info, market_type, side, line_valueThe bet.
team, opponentFrom our projections; empty when the player can't be matched.
book, odds, fair_value_oddsThe book, price and fair value when we flagged it (American odds).
kelly, kelly_standard, coverageStake in units (confidence-adjusted and standard) and books pricing the line, when flagged.
flagged_atWhen the bet was flagged (UTC).
actual_value, hitWhat happened, and whether the bet won. hit is empty if it could not be graded.
dnp, is_outlierDid-not-play and outlier flags. These rows are included, not removed, so filter them yourself if you want our Profitability Suite's numbers.
flat_pl, kelly_plProfit/loss at 1 unit flat, and at the Kelly stake.

/results/summary takes date_from (default 30 days), min_kelly and min_coverage, and returns one document of cols and rows, the same numbers as our Profitability Suite (DNP and outliers excluded, +EV bets only).

Projections and model probabilities

Our player projections (proj_*, projected means) and our Monte Carlo probabilities (mc_*), the numbers behind the projections and feeds on the site. Filters: game_date (default: today and later), player (contains), team, opponent, position, and player_type (batter/pitcher for MLB, skater/goalie for NHL).

  • Every probability is 0–1 in every sport (0.42 = 42%). A field like mc_points_20plus is the chance of 20 or more.
  • *_probs and mc_ladders are ladders: {"49.5": 0.77, "74.5": 0.60} means a 77% chance of 49.5 or more and 60% of 74.5 or more. NBA's mc_ladders is keyed by stat first.
  • A value is empty (null) when we don't have a projection for it, never 0. A 0 or a ladder of zeros is a real near-zero chance (a tight end's passing yards, for example).
  • A player is missing when we don't have enough data to project that player yet, mostly relievers and bench players.
  • MLB adds MIQ: master_miq and its four parts, mix_match_score (pitch mix), zone_fit_score, barrel_vs_hand_score (batter barrels) and pitcher_barrel_score. There's also pitcher_tier and pitcher_rank of pitcher_rank_total. They're on a 0–100 scale where 50 is neutral; a barrel score is also 50 when there isn't enough barrel data for that matchup.
  • NFL rows are only for games that haven't kicked off. Projections refresh about every two hours from 8 AM to 6 PM ET; as_of is the newest update.

Fantasy

/fantasy returns the Fantasy HQ numbers: proj_fantasy_pts in DraftKings scoring, its distribution mc_fantasy_pts_probs (chance of scoring at least each value), and the projected stats you need for any other scoring. Fantasy HQ builds other formats from those stats, like this:

NFL  DraftKings (stored, full PPR): pass_yds×0.04 + pass_tds×4 − interceptions×1
                                   + rush_yds×0.1 + rush_tds×6 + receptions×1 + rec_yds×0.1 + rec_tds×6
     PPR: as DraftKings but interceptions×−2   Half PPR: also receptions×0.5
     Standard: also receptions×0               (no yardage bonuses in any format)
NBA  DraftKings (stored): points×1 + threes×0.5 + rebounds×1.25 + assists×1.5 + steals×2 + blocks×2
                          − turnovers×0.5 + double_double×1.5 + triple_double×3
     FanDuel: points×1 + rebounds×1.2 + assists×1.5 + steals×3 + blocks×3 − turnovers×1
NHL  DraftKings skaters (stored): goals×8.5 + assists×5 + shots×1.5 + blocks×1.3
                                  + shorthanded points×2 + hat-trick bonus 3

Multiply a double-double or triple-double probability by its bonus to get its expected value. NHL goalie fantasy points aren't included.

Game projections

Our game model for NBA, NHL, WNBA and NFL: each upcoming game's projected score for both teams and the projected total. NBA, NHL and WNBA add our Monte Carlo game probabilities, all 0–1:

  • NBA / WNBA: away_win_prob/home_win_prob, the total over/under ladder (mc_total_over_220 = chance of more than 220) and each team's points ladder (mc_home_over_110), plus each team's offense and defense scores.
  • NHL: each team's goals ladder (mc_home_3plus_g, mc_away_0g) and the total over/under ladder (mc_total_over_5_5).
  • NFL: projected points for both teams, projected_total, projected_margin (home minus away) and projected touchdowns. Games that haven't kicked off.
  • Filters: game_date (default: today and later) and team (either side of the game). A game appears once we've projected it, which can be later in the day for tomorrow's slate. MLB game projections aren't in the API yet.
curl -H "Authorization: Bearer $MKB_API_KEY" "https://www.mama-knows-bets.com/api/v1/nba/games?team=BOS"

DvP and team defense

  • NBA: one row per team and position: stats allowed, ranks (1 = allows the most), dvp_score and percentile (higher = softer matchup for the offense), games_sampled. Filters: team, position.
  • NHL: one row per team and line unit (F1–F4, D1–D3, PP1–PP2). PP rows count power-play scoring only. Filters: team, unit, unit_type.
  • NFL: one row per upcoming game, defense and position (QB/RB/WR/TE): the matchup score (higher = softer matchup), position rank and sub-scores (TD, red zone, yards, volume). Filters: game_date, defense, position. /nfl/team-defense adds this season's coverage, pressure and red-zone numbers per defense.
  • NBA and NHL return every team, whether or not it plays today, each with its latest numbers and their calculation_date. from_latest_calculation is false when a team's row is older than the newest run. Early in a season that means last season's final numbers: a team only gets new-season DvP after three games at that position.
  • NFL DvP only exists for upcoming games, so a team on a bye week isn't listed.
  • MLB has no /dvp: its matchup quality is MIQ, and it comes with each player in /mlb/projections (master_miq and its four parts). MIQ HQ's pitch-by-pitch breakdowns stay on the site.

Pagination and freshness

  • Up to 1,000 rows per page (limit). Follow next_cursor until it is null, keeping every other parameter identical.
  • The first page includes total_count. Your rows should add up to it.
  • MLB, NFL, NBA, NHL, WNBA and futures boards are one complete pricing run (consistency: "single_run"). Every page of your pull reads the same run, even if a new one lands mid-pull. If we can't give you the complete run, you get a 409, never a short list.
  • Soccer and NCAAF boards update line by line (consistency: "rolling"), so a long pull can include rows priced at slightly different times. Check each row's run_timestamp.
  • Projections, fantasy and DvP are rewritten in place when they refresh. If that happens while you page, you get a 409 data_changed: start again.
  • Boards refresh about every 15 minutes at peak and 30 overnight. Poll /status, which doesn't count toward your quota, and pull the board only when run_timestamp changes.
# Cheap polling: /status is not metered. Pull the board only when it changes.
curl -H "Authorization: Bearer $MKB_API_KEY" "https://www.mama-knows-bets.com/api/v1/nba/status"

Empty is not an error, and an error is never empty

  • A successful response always has "status": "ok" and a data array.
  • An empty data is real, and comes with a reason: no_matches_for_filters, no_opportunities_this_run, board_empty, no_runs, not_settled_yet, no_settled_bets_in_range, no_upcoming_games or no_data.
  • "stale": true means the data is older than it should be (for example a sport between seasons). You still get it, flagged, with board_age_minutes or age_hours.
  • Any failure is a non-200 response with "status": "error", a code and a message, and no data field. Treat it as an error, not as "no bets".

Limits

Your plan sets a per-minute rate limit and a monthly quota, counted per member across all your keys, by calendar month in US Eastern time: it resets at midnight ET on the 1st. Every response carries:

X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset   (per minute)
X-Quota-Limit     / X-Quota-Remaining     / X-Quota-Reset         (per month)
Retry-After                                                       (on 429)

Resets are Unix timestamps in seconds. See your live usage on the API Access page or at /usage.

Errors

400unknown_parameter / invalid_parameter / unsupported_parameterA parameter is misspelled, malformed, or not available on that endpoint. We reject them rather than ignore them.
400invalid_cursor / cursor_mismatchThe cursor is corrupt, or the filters changed between pages.
400outside_history_windowResults date_from is earlier than your plan's history allows.
401missing_key / invalid_keyNo key sent, or the key is unknown or revoked.
403subscription_inactive / no_api_plan / trial_no_apiYour subscription isn't active, or your plan doesn't include the API.
404unknown_sport / no_results_for_sport / no_dvp_for_sport / no_fantasy_for_sportNot a supported sport, or that data isn't available for it.
409run_expired / run_changed / data_changedThe data you were paging changed or expired. Start again without a cursor.
410endpoint_retiredAn old beta endpoint. Use the endpoints on this page.
429rate_limited / quota_exceededPer-minute limit or monthly quota reached. See Retry-After.
503upstream_unavailable / auth_unavailableSomething on our side failed. Retry with backoff.

Examples

Python

import os, time, requests

KEY = os.environ["MKB_API_KEY"]
URL = "https://www.mama-knows-bets.com/api/v1/nba/board"

def pull_board(params):
    rows, cursor = [], None
    while True:
        p = dict(params, **({"cursor": cursor} if cursor else {}))
        r = requests.get(URL, params=p, headers={"Authorization": f"Bearer {KEY}"}, timeout=30)
        if r.status_code == 429:
            time.sleep(int(r.headers.get("Retry-After", "60")))
            continue
        if r.status_code == 409:          # the run rotated mid-pull: start over
            rows, cursor = [], None
            continue
        r.raise_for_status()              # any other error is an error, not "no bets"
        body = r.json()
        if body.get("stale"):
            print("warning: board is", body["board_age_minutes"], "minutes old")
        rows.extend(body["data"])
        cursor = body.get("next_cursor")
        if not cursor:
            return rows, body

rows, last = pull_board({"min_kelly": 0.0001})
print(len(rows), "rows", last.get("reason", ""))

Google Sheets (Apps Script)

// Google Sheets → Extensions → Apps Script. Store your key in
// Project Settings → Script Properties as MKB_API_KEY (never in a cell).
function pullNbaBoard() {
  const key = PropertiesService.getScriptProperties().getProperty("MKB_API_KEY");
  const cols = ["player_name","market_type","side","line_value","best_book",
                "best_book_odds","fair_value_odds","ev_percentage","kelly_confidence_adjusted"];
  let cursor = null, out = [];
  do {
    let url = "https://www.mama-knows-bets.com/api/v1/nba/board?min_kelly=0.0001&limit=1000";
    if (cursor) url += "&cursor=" + encodeURIComponent(cursor);
    const res = UrlFetchApp.fetch(url, {
      headers: { Authorization: "Bearer " + key }, muteHttpExceptions: true });
    const body = JSON.parse(res.getContentText());
    if (res.getResponseCode() !== 200) throw new Error(body.code + ": " + body.message);
    body.data.forEach(r => out.push(cols.map(c => r[c])));
    cursor = body.next_cursor;
  } while (cursor);
  const sh = SpreadsheetApp.getActive().getSheetByName("NBA") ||
             SpreadsheetApp.getActive().insertSheet("NBA");
  sh.clearContents();
  sh.getRange(1, 1, 1, cols.length).setValues([cols]);
  if (out.length) sh.getRange(2, 1, out.length, cols.length).setValues(out);
}

Book codes

pn Pinnacle

ci Circa

fd FanDuel

dk DraftKings

mg BetMGM

fn Fanatics

cz Caesars

es theScore

bb BallyBet

hr Hard Rock

hf Hard Rock FL

ha Hard Rock AZ

ho Hard Rock OH

br BetRivers

bp betPARX

rb ReBet

bv Bovada

bo BetOnline

fl Fliff

nv Novig

px ProphetX

ks Kalshi

Futures use the same codes in upper case. Kalshi, Novig and ProphetX are exchanges or prediction markets, and they are often the best price. Filter them out with best_book if you can't bet them.

What the API doesn't include

Every book's individual price, line history, season-long projections, golf, and MLB game projections (for now). Projections and probabilities are model estimates, not guarantees, and prices change constantly: always confirm a price with the sportsbook before you bet.

Please gamble responsibly. If you or someone you know has a gambling problem, call 1-800-GAMBLER.