{"openapi":"3.1.0","info":{"title":"DawBets Public API","version":"1.0.0","description":"Read-only reference data about DawBets: the sportsbooks it compares, which of them are licensed in each US state, current subscription prices, and the version and parameters of the expected-value methodology. No authentication. No odds, fair prices or expected-value data are served here — those require an account and are available in the app or through the Claude connector (see x-mcp). Every date and time is UTC ISO-8601. Breaking changes bump the major version and are listed in x-changelog.","termsOfService":"https://dawbets.com/terms","contact":{"name":"DawBets","email":"team@dawbets.com","url":"https://dawbets.com/developers"},"x-terms":{"termsOfService":"https://dawbets.com/terms","privacyPolicy":"https://dawbets.com/privacy","summary":"Read-only. Use is governed by the Terms of Service; the citation policy in /llms.txt applies to republished data."}},"servers":[{"url":"https://dawbets.com","description":"Production"}],"tags":[{"name":"catalog","description":"Sportsbook catalog and per-state availability."},{"name":"pricing","description":"Subscription prices, formatted as displayed."},{"name":"methodology","description":"The expected-value methodology and its parameters."}],"paths":{"/api/sportsbooks":{"get":{"operationId":"listSportsbooks","summary":"Sportsbooks DawBets currently compares","description":"Every sportsbook currently active in the DawBets app, sorted by name. `id` is the slug used everywhere else in DawBets (including `/api/state-sportsbooks`). `logo` is a Cloudinary public id — render it as `https://res.cloudinary.com/dawbets/f_auto,q_auto,w_100/{logo}`. `is_prediction_market` marks exchanges (currently Kalshi, Novig, Polymarket US and ProphetX).","tags":["catalog"],"responses":{"200":{"description":"The active sportsbook catalog.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Sportsbook"}},"example":[{"id":"bet365","name":"bet365","logo":"sportsbooks/bet365","fee_percentage":0,"desktop_link_cta":"Go to market page","mobile_link_cta":"Add to slip","is_prediction_market":false},{"id":"kalshi","name":"Kalshi","logo":"sportsbooks/kalshi","fee_percentage":0,"desktop_link_cta":"Add to slip","mobile_link_cta":"Add to slip","is_prediction_market":true}]}}},"429":{"description":"Rate limit exceeded for this client IP. Wait for the number of seconds in Retry-After before retrying.","headers":{"Retry-After":{"description":"Seconds until the current window resets.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":true,"url":"https://dawbets.com/api/sportsbooks","statusCode":429,"statusMessage":"Too many requests. Try again in 42s."}}}},"500":{"description":"The catalog could not be loaded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rate-limit":{"max":60,"windowSeconds":60,"keyedBy":"client IP","exceeded":"429 with a Retry-After header (seconds) and an Error body"},"x-cache":{"maxAgeSeconds":86400,"description":"Served from a shared server cache; a change upstream can take this long to appear."}}},"/api/state-sportsbooks":{"get":{"operationId":"listStateSportsbooks","summary":"Sportsbook ids licensed in a US state","description":"Sportsbook ids (the `id` values from `/api/sportsbooks`) licensed for online betting in one US state. An unknown or unlicensed state returns an empty list, not an error. This is the list the state guide pages display; it does not gate any odds surface.","tags":["catalog"],"parameters":[{"name":"state","in":"query","required":true,"description":"Two-letter US state code, uppercase (USPS abbreviation; `DC` for Washington DC). See x-known-values for the codes DawBets carries a legality page for.","schema":{"type":"string","pattern":"^[A-Z]{2}$","x-known-values":["AK","AL","AR","AZ","CA","CO","CT","DC","DE","FL","GA","HI","IA","ID","IL","IN","KS","KY","LA","MA","MD","ME","MI","MN","MO","MS","MT","NC","ND","NE","NH","NJ","NM","NV","NY","OH","OK","OR","PA","RI","SC","SD","TN","TX","UT","VA","VT","WA","WI","WV","WY"]},"example":"NJ"}],"responses":{"200":{"description":"Sportsbook ids licensed in the state (possibly empty).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StateSportsbooks"},"example":{"sportsbooks":["draftkings","fanduel","betmgm","caesars"]}}}},"400":{"description":"`state` is missing or not a string.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded for this client IP. Wait for the number of seconds in Retry-After before retrying.","headers":{"Retry-After":{"description":"Seconds until the current window resets.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":true,"url":"https://dawbets.com/api/sportsbooks","statusCode":429,"statusMessage":"Too many requests. Try again in 42s."}}}},"500":{"description":"The state list could not be loaded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rate-limit":{"max":60,"windowSeconds":60,"keyedBy":"client IP","exceeded":"429 with a Retry-After header (seconds) and an Error body"},"x-cache":{"maxAgeSeconds":86400,"description":"Served from a shared server cache; a change upstream can take this long to appear."}}},"/api/prices":{"get":{"operationId":"getPrices","summary":"Current subscription prices","description":"Current Plus and Pro subscription prices in US dollars, pre-formatted for display: `$` followed by a whole-dollar amount or two decimals. `annual` is the monthly-equivalent price of the annual plan (annual total divided by 12, rounded down to the dollar); `annualTotal` is the full annual charge, empty when `hasAnnual` is false. Read from Stripe on a cache miss, so a price change can take up to the cache TTL to appear.","tags":["pricing"],"responses":{"200":{"description":"Prices for both paid tiers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Prices"},"example":{"hasAnnual":true,"plus":{"monthly":"$19","annual":"$15","annualTotal":"$190"},"pro":{"monthly":"$30","annual":"$25","annualTotal":"$300"}}}}},"429":{"description":"Rate limit exceeded for this client IP. Wait for the number of seconds in Retry-After before retrying.","headers":{"Retry-After":{"description":"Seconds until the current window resets.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":true,"url":"https://dawbets.com/api/sportsbooks","statusCode":429,"statusMessage":"Too many requests. Try again in 42s."}}}},"500":{"description":"Stripe could not be reached or a price id is not configured.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-rate-limit":{"max":30,"windowSeconds":60,"keyedBy":"client IP","exceeded":"429 with a Retry-After header (seconds) and an Error body"},"x-cache":{"maxAgeSeconds":86400,"description":"Served from a shared server cache; a change upstream can take this long to appear."}}},"/api/methodology":{"get":{"operationId":"getMethodology","summary":"The EV methodology version and its parameters","description":"The version, name and parameters of the expected-value methodology DawBets scores and sizes bets with. Pin `version`: it changes only when a number a bet is scored or sized by changes, so a stored value that no longer matches means the math moved, not the site. `kelly.fractions` are fractions of full Kelly; `kelly.playerPropReduction` is the extra multiplier on player props. Badge tiers are ordered best to worst.","tags":["methodology"],"responses":{"200":{"description":"The current methodology.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Methodology"},"example":{"version":"1.0.0","name":"DawBets expected-value methodology","description":"DawBets estimates a fair win probability for every selection by removing the vig from sharp-sportsbook odds, using multiplicative, additive and power devig methods and defaulting to whichever implies the smallest edge. Expected value is the offered price at a sportsbook measured against that fair probability, stored as a decimal (0.05 = 5%). Recommended wagers use fractional Kelly — 1/2, 1/4 or 1/8 of full Kelly by risk tolerance (medium is the default) — with a further 50% reduction on player-prop markets. Each bet is labeled with one of 5 badge tiers by its expected value.","lastUpdated":"2026-05-27","documentationUrl":"https://dawbets.com/about/methodology","kelly":{"fractions":{"high":0.5,"medium":0.25,"low":0.125},"playerPropReduction":0.5},"badgeTiers":[{"value":4,"label":"Must Bet","description":"≥ 7% EV · highest confidence"},{"value":3,"label":"Strong Bet","description":"3.5–7% EV · reliable edge"},{"value":2,"label":"Good Bet","description":"0–3.5% EV · small but real edge"},{"value":1,"label":"Fan Bet","description":"−2 to 0% EV · small cost for the fun"},{"value":0,"label":"Caution Bet","description":"< −2% EV · odds are against you"}]}}}},"429":{"description":"Rate limit exceeded for this client IP. Wait for the number of seconds in Retry-After before retrying.","headers":{"Retry-After":{"description":"Seconds until the current window resets.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":true,"url":"https://dawbets.com/api/sportsbooks","statusCode":429,"statusMessage":"Too many requests. Try again in 42s."}}}}},"x-rate-limit":{"max":60,"windowSeconds":60,"keyedBy":"client IP","exceeded":"429 with a Retry-After header (seconds) and an Error body"},"x-cache":{"description":"Not cached at the edge; computed from constants on every request."}}}},"components":{"schemas":{"Sportsbook":{"type":"object","required":["id","name","logo","fee_percentage","desktop_link_cta","mobile_link_cta","is_prediction_market"],"additionalProperties":false,"properties":{"id":{"type":"string","description":"Stable slug; the key used across DawBets.","examples":["bet365"]},"name":{"type":["string","null"],"description":"Display name."},"logo":{"type":["string","null"],"description":"Cloudinary public id, or null when no logo is on file."},"fee_percentage":{"type":["number","null"],"description":"Fee the book deducts from winnings, as a percentage (2.5 = 2.5%); null or 0 when none. Applied to the win amount, not the stake."},"desktop_link_cta":{"type":["string","null"],"description":"Label for the outbound link on desktop."},"mobile_link_cta":{"type":["string","null"],"description":"Label for the outbound link on mobile."},"is_prediction_market":{"type":"boolean","description":"True for prediction-market exchanges."}}},"StateSportsbooks":{"type":"object","required":["sportsbooks"],"additionalProperties":false,"properties":{"sportsbooks":{"type":"array","description":"Sportsbook ids licensed in the requested state, in no guaranteed order.","items":{"type":"string"}}}},"TierPrices":{"type":"object","required":["monthly","annual","annualTotal"],"additionalProperties":false,"properties":{"monthly":{"type":"string","description":"Monthly plan price per month, USD, formatted.","examples":["$19"]},"annual":{"type":"string","description":"Annual plan price expressed per month, USD, formatted."},"annualTotal":{"type":"string","description":"Annual plan total charge, USD, formatted; empty string when no annual plan."}}},"Prices":{"type":"object","required":["hasAnnual","plus","pro"],"additionalProperties":false,"properties":{"hasAnnual":{"type":"boolean","description":"Whether annual plans are configured."},"plus":{"$ref":"#/components/schemas/TierPrices"},"pro":{"$ref":"#/components/schemas/TierPrices"}}},"BadgeTier":{"type":"object","required":["value","label","description"],"additionalProperties":false,"properties":{"value":{"type":"integer","minimum":0,"maximum":4,"description":"Tier score; 4 is the best."},"label":{"type":"string","examples":["Must Bet"]},"description":{"type":"string","description":"The expected-value band the tier covers."}}},"Methodology":{"type":"object","required":["version","name","description","lastUpdated","documentationUrl","kelly","badgeTiers"],"additionalProperties":false,"properties":{"version":{"type":"string","description":"Semantic version of the methodology. Pin this.","examples":["1.0.0"]},"name":{"type":"string"},"description":{"type":"string","description":"One paragraph, plain text."},"lastUpdated":{"type":"string","format":"date","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"ISO-8601 calendar date, UTC."},"documentationUrl":{"type":"string","format":"uri","description":"The prose methodology page."},"kelly":{"type":"object","required":["fractions","playerPropReduction"],"additionalProperties":false,"properties":{"fractions":{"type":"object","required":["high","medium","low"],"additionalProperties":false,"description":"Fraction of full Kelly per risk tolerance (0.5 = half Kelly).","properties":{"high":{"type":"number","minimum":0,"maximum":1},"medium":{"type":"number","minimum":0,"maximum":1},"low":{"type":"number","minimum":0,"maximum":1}}},"playerPropReduction":{"type":"number","minimum":0,"maximum":1,"description":"Multiplier applied to player-prop wagers on top of the fraction."}}},"badgeTiers":{"type":"array","items":{"$ref":"#/components/schemas/BadgeTier"},"description":"Best to worst."}}},"Error":{"type":"object","description":"The body every non-2xx response carries (the Nitro JSON error shape). `statusCode` and `statusMessage` are always present; `data` holds validation detail when there is any.","required":["statusCode","statusMessage"],"properties":{"error":{"const":true},"url":{"type":"string","description":"Absolute URL of the failing request."},"statusCode":{"type":"integer","minimum":400,"maximum":599},"statusMessage":{"type":"string","description":"Short, human-readable reason; safe to show."},"message":{"type":"string"},"data":{"description":"Optional detail; for a 400 an object with an `issues` array."}}}}},"x-changelog":[{"date":"2026-09-03","version":"1.0.0","changes":["Published the OpenAPI 3.1 document at /openapi.json.","Added GET /api/methodology.","Documented GET /api/sportsbooks, GET /api/state-sportsbooks and GET /api/prices, and put a per-IP rate limit on each."]}],"x-mcp":{"description":"Odds, expected value and a signed-in user's own bets are available to AI agents through the DawBets MCP connector (OAuth, paid plans, 21+ attestation), not through this API.","documentation":"https://dawbets.com/connect-claude","resource":"https://dawbets.com/api/mcp","protectedResourceMetadata":"https://dawbets.com/.well-known/oauth-protected-resource"}}