---
name: draftkings-odds
description: Use this skill EVERY time the user wants live betting odds or a moneyline from DraftKings — "what's the moneyline on <team/game>", "DraftKings odds for <matchup>", "pull the DK line", "what are the odds on the <team> game", "current moneyline", "spread/total on <game>", "betting odds". Scrapes DraftKings DIRECTLY (reads DK's own sportscontent markets API through a stealth browser) for Moneyline, Run Line/Spread, and Total across MLB/NBA/NFL/NHL/WNBA/NCAA. Works for PREGAME and LIVE in-game odds, from any US location. Read-only — never logs in, never places a bet.
---

# draftkings-odds skill

Pulls **current DraftKings odds** straight from DraftKings — the same numbers shown on sportsbook.draftkings.com — for any game in the supported leagues. Returns Moneyline (+ Run Line/Spread + Total) with correct home/away mapping, live status, and a fetch timestamp.

## Why direct-scrape (not an aggregator)

Aggregators like ESPN's API expose a "DraftKings" feed, but it **freezes at the pregame closing line** — for a live in-game game it is stale and wrong. Validated 2026-06-14: a live game read ARI −111/CIN −109 on ESPN while DraftKings' own site showed ARI −263/CIN +194. This skill reads DraftKings' own market feed, so it is correct pregame **and** live.

## Surface

```
node scripts/dk_moneyline.mjs --league <mlb|nba|nfl|nhl|wnba|ncaaf|ncaab> [--team "<name>"] [--json] [--headful] [--raw <file>]
```

- `--league` (default `mlb`): which league's slate to pull.
- `--team "<name>"`: filter to games involving a team (matches city or nickname, case-insensitive).
- `--json`: machine-readable output (full structure: moneyline/spread/total per side, eventId, startTime, status, marketsUrl, fetchedAt).
- `--headful`: show the browser (debugging).
- `--raw <file>`: dump DK's raw markets JSON to a file (for inspection).

Default output is a human-readable table. American odds are normalized to ASCII (`-263`, `+194`).

## How it works

1. Stealth Chromium (patchright) opens `sportsbook.draftkings.com/leagues/<sport>` and lets the page establish its Akamai session (waits for the page's own markets XHR to land = "warm").
2. Reads DraftKings' own `…/sportscontent/controldata/league/leagueSubcategory/v1/markets` feed — preferring a fresh in-page re-fetch (no credentials, which avoids the CORS-with-cookies block), falling back to the passively captured response.
3. Parses Moneyline / Run Line·Spread / Total, mapping selections to home/away via `outcomeType` + `participants[].venueRole`.

Exit codes: `0` ok · `2` no games listed (incl. a league that is out of season / has no slate today — reported cleanly, not as an error) · `3` fetch/parse failure or unknown league · `4` geo/region block.

**Seasonal behavior:** MLB and WNBA are in season in summer and return live data; NBA, NHL, NFL, and the college leagues return a clean "no games listed (may be out of season)" message out of season — they are NOT broken. The parser is sport-agnostic (keys on market name: Moneyline / Run Line / Puck Line / Spread / Total), so a league starts working automatically once DraftKings lists games for it.

## Reliability notes (validated 2026-06-14, re-verified 2026-06-15 adversarial pass)

- **On-screen match:** API values render on DraftKings' own event page (DOM-verified + screenshot).
- **Freshness:** consecutive fetches 75s apart show live games' lines moving → data is live, not cached.
- **Vig sanity:** every priced game has a positive book hold (≈4.5% pregame, ≈6.5% live), favorites negative / dogs positive, implied probabilities sum >100%.
- **Repeatable:** 3/3 consecutive runs returned the full slate.
- **Geo:** works from non-betting states (e.g. Texas) — DraftKings lets you browse odds; only bet *placement* is geo-gated, which this skill never does.
- **Live edge case:** during a blowout DK may suspend one side; that side prints `(suspended)` rather than a bogus number.

## Dependencies

- `patchright` (installed in this folder; reuses the shared `ms-playwright` Chromium cache). The script also falls back to the patchright in `gemini-engine`/`linkedin`/`pinterest` if the local install is missing.

## Scope

Read-only odds retrieval. Does NOT log in, place bets, manage a bankroll, or give betting advice. Adding a league = add its slug + numeric `leagueId` to the `LEAGUES` map in `scripts/dk_moneyline.mjs`.
