{"openapi":"3.1.0","info":{"title":"PriceMyBet API","version":"1.0.0","description":"Sportsbook odds and prediction-market prices for the same bet, side by side, in cents on the dollar. Every price is an implied probability; lower is cheaper. The cheapest price is computed, never chosen, and sources that pay us nothing are included on the same terms as those that do.","contact":{"name":"PriceMyBet","url":"https://pricemybet.com"},"license":{"name":"Free to use with attribution","identifier":"CC-BY-4.0"}},"servers":[{"url":"https://pricemybet.com","description":"Production"}],"paths":{"/api/v1/events/{id}":{"get":{"summary":"One matchup, every market and every price","description":"The same data the matchup page is rendered from: both teams, every source's price per market and side, opening prices, the cheapest and dearest source, and the gap between them.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Event id, as returned by the league endpoint."}],"responses":{"200":{"description":"The matchup.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"400":{"description":"The id is not a uuid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such event.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/leagues/{league}/events":{"get":{"summary":"The next seven days in a league","description":"One line per game: both teams, the cheapest and dearest price per side, and the gap. Follow `event_url` for the full board.","parameters":[{"name":"league","in":"path","required":true,"schema":{"type":"string","examples":["nfl"]},"description":"League id. `nfl` today."}],"responses":{"200":{"description":"Matchups grouped by date.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeagueEvents"}}}},"404":{"description":"No such league.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/savings":{"get":{"summary":"What readers have saved, and the widest gap on the board","description":"`totals` is money saved by people who took a highlighted price, on an assumed $10 stake. It is a price difference, never a profit and never an outcome. Null means nobody has taken one yet, which is not the same as zero.","responses":{"200":{"description":"Totals and the widest current gap.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Savings"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}}},"components":{"responses":{"RateLimited":{"description":"More than 60 requests in a minute from one IP.","headers":{"retry-after":{"schema":{"type":"integer"},"description":"Seconds until the window resets."},"x-ratelimit-limit":{"schema":{"type":"integer"}},"x-ratelimit-remaining":{"schema":{"type":"integer"}},"x-ratelimit-reset":{"schema":{"type":"integer"},"description":"Unix seconds when the window resets."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Attribution":{"type":"string","description":"On every response. Please keep it with the numbers.","examples":["Prices from PriceMyBet — https://pricemybet.com"]},"Error":{"type":"object","properties":{"error":{"type":"string"},"detail":{"type":"string"},"attribution":{"$ref":"#/components/schemas/Attribution"}},"required":["error","attribution"]},"Source":{"type":"object","properties":{"id":{"type":"string","examples":["kalshi"]},"name":{"type":"string","examples":["Kalshi"]},"kind":{"type":"string","enum":["sportsbook","prediction_market"]},"affiliate_url":{"type":["string","null"],"description":"Null means we earn nothing from this source. It is listed and can win the highlight regardless."},"site_url":{"type":["string","null"]},"states":{"type":"array","items":{"type":"string"},"description":"US states where this operator is licensed."}}},"Price":{"type":"object","properties":{"source":{"$ref":"#/components/schemas/Source"},"cents":{"type":"number","description":"Implied probability in cents on the dollar, 0-100. 38 means the contract costs 38 cents and pays $1 if that side wins, so a lower number is a cheaper bet."},"raw_price":{"type":"string","description":"As the source sent it: '-110' from a book, '0.38' from a market."},"raw_format":{"type":"string","enum":["american","decimal","probability"]},"line":{"type":["number","null"],"description":"Spread or total. Null on a moneyline."},"seen_at":{"type":"string","format":"date-time"},"opening":{"type":["object","null"],"description":"The first price we ever stored for this series."},"move_cents":{"type":["number","null"],"description":"Now minus opening. Positive means the side got dearer."},"closing":{"type":["object","null"],"description":"Frozen at grading time; present only once the event is final."},"is_best":{"type":"boolean","description":"The cheapest price for this side. Computed, never chosen."},"is_worst":{"type":"boolean"},"off_line":{"type":"boolean","description":"Quoted at a different spread or total, so excluded from the comparison."}}},"Side":{"type":"object","properties":{"side":{"type":"string","enum":["home","away","over","under"]},"label":{"type":"string"},"line":{"type":["number","null"]},"prices":{"type":"array","items":{"$ref":"#/components/schemas/Price"}},"best":{"type":["object","null"]},"worst":{"type":["object","null"]},"gap_cents":{"type":["number","null"],"description":"Dearest minus cheapest, in cents."},"saved_on_10":{"type":["number","null"],"description":"The gap on an assumed $10 stake, in dollars. A price difference, not a profit."}}},"Event":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"league_id":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"starts_at":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["scheduled","live","final","postponed","cancelled"]},"home_score":{"type":["integer","null"]},"away_score":{"type":["integer","null"]},"home":{"$ref":"#/components/schemas/Team"},"away":{"$ref":"#/components/schemas/Team"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/Source"}},"markets":{"type":"array","items":{"type":"object","properties":{"market":{"type":"string","enum":["moneyline","spread","total"]},"consensus_line":{"type":["number","null"]},"sides":{"type":"array","items":{"$ref":"#/components/schemas/Side"}}}}},"updated_at":{"type":["string","null"],"format":"date-time"},"attribution":{"$ref":"#/components/schemas/Attribution"}}},"Team":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"short":{"type":"string"},"abbr":{"type":"string"}}},"LeagueEvents":{"type":"object","properties":{"league":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"days":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","description":"US Eastern calendar date, the same one the slug uses."},"matchups":{"type":"array","items":{"type":"object"}}}}},"attribution":{"$ref":"#/components/schemas/Attribution"}}},"Savings":{"type":"object","properties":{"totals":{"type":"object","properties":{"total_usd":{"type":["number","null"],"description":"Null until somebody has taken a highlighted price. Not zero."},"vs_big_two_usd":{"type":["number","null"]},"via_pm_usd":{"type":["number","null"]},"since":{"type":["string","null"],"format":"date-time"}}},"biggest":{"type":["object","null"],"description":"The widest gap on the board right now."},"attribution":{"$ref":"#/components/schemas/Attribution"}}}}}}