propline-cli
v0.36.0
Published
Command-line interface for the PropLine player props betting odds API. Wraps the propline SDK with pretty-printed tables and JSON output.
Downloads
1,944
Maintainers
Readme
propline-cli
Terminal interface for the PropLine player props betting odds API. Wraps the propline Node SDK with pretty-printed tables and a --json opt-out.
npx propline-cli live
# or, for repeated use:
npm install -g propline-cli
propline liveAuth
Set your API key once:
export PROPLINE_API_KEY=your_key_herePaid plans: Hobby $9/mo (5,000 req/day, full analytics), Pro $19/mo (25,000/day + CSV exports), Streaming Lite $39/mo (250,000/day + webhooks/websocket), Streaming $79/mo (1,000,000/day), Enterprise (unlimited).
Or pass --api-key per-invocation. Get a free key at https://prop-line.com/?ref=cli.
Quick examples
# Every game in progress, across every sport
propline live
# Today's MLB slate
propline events baseball_mlb
# Cross-book odds for one event
propline odds baseball_mlb 12345 --markets h2h,spreads,totals,player_points
# First-quarter NBA totals only (game-period filter on every odds command)
propline odds basketball_nba 12345 --markets totals --period q1
# Only DraftKings + FanDuel lines (bookmaker filter on every odds command)
propline odds baseball_mlb 12345 --markets pitcher_strikeouts --bookmakers draftkings,fanduel
# Add per-book event-page URLs (click out to the book) — also on best-line
propline best-line baseball_mlb 12345 --links
# Scores from the last 3 days
propline scores basketball_nba
# Game context — probable pitchers, umpire, first-pitch weather (free)
propline context baseball_mlb 12345
# Cross-book +EV plays (Pro tier)
propline ev baseball_mlb 12345 --plus
# ...priced only at the books you hold accounts at. This narrows the
# prices, never the fair-line anchor — DK is still measured against
# Pinnacle.
propline ev baseball_mlb 12345 --plus --bookmakers draftkings,fanduel
# ...with Shin's de-vig instead of multiplicative (corrects the
# favourite-longshot bias on longshot props like anytime TD)
propline ev baseball_mlb 12345 --plus --devig shin
# ...anchored on Polymarket, falling back to Pinnacle
propline ev baseball_mlb 12345 --plus --fair-source polymarket,pinnacle
# Find a player's stable player_id (free)
propline players baseball_mlb judge
# Player prop history (Pro tier) — by name or player_id; --main-line-only drops alt rungs
propline player-history baseball_mlb "Aaron Judge" --market batter_home_runs
propline player-history baseball_mlb mlb:592450 --market batter_total_bases --main-line-only
# Aggregated hit-rate trends per market (Pro tier)
propline player-trends baseball_mlb "Aaron Judge"
propline player-trends baseball_mlb "Aaron Judge" --market batter_total_bases
# Scope the trend to a PrizePicks flavor's line (standard | goblin | demon)
propline player-trends baseball_mlb "Aaron Judge" --dfs-odds-type goblin
# Bulk CSV export of resolved props (Pro tier)
propline export-resolved-props --sport baseball_mlb --since 2026-04-01T00:00:00Z --out mlb-resolved.csv
# Manage webhook subscriptions (Streaming tier)
propline webhooks list
propline webhooks create --url https://example.com/hook --events line_movement,resolution --sport baseball_mlb
# Hear when 3+ books pull the same player pregame (a late scratch); drop --min-books-agreeing for every drop
propline webhooks create --url https://example.com/hook --events market_suspended --sport baseball_mlb --min-books-agreeing 3
propline webhooks deliveries 42
propline webhooks deliveries 42 --limit 200 --before-id 123456 # page backwards
# Catch up after an outage: replay from the last X-PropLine-Sequence you
# processed. Oldest-first, and it warns on stderr if anything after your
# cursor has already aged out of retention.
propline webhooks replay 42 --since-seq 4180
propline webhooks replay 42 --since-seq 4180 --all --json
# Or stream it live over a websocket instead of receiving POSTs.
# Line-delimited JSON on stdout with --json, so it pipes into jq.
# Reconnects and resumes from the last seq automatically.
propline stream 42 --since-seq 4180
propline stream 42 --json | jq -r '.data.player_name'
# NOTE: global flags (--json, --api-key, --base-url, --timeout) were silently
# ignored by every `webhooks <sub>` command before v0.31.1.Player game log / head-to-head
# Every raw box-score stat, per game — build L5/L10/L20 from these.
propline player-games baseball_mlb "Aaron Judge" --limit 10
# Last 5 MEETINGS with Boston (not the Boston games among his last 5).
propline player-games baseball_mlb "Aaron Judge" --limit 5 --opponent BOS \
--stat-type hits,home_runs,rbisCommands
| Command | Description |
| --- | --- |
| propline sports | List available sports |
| propline events <sport> | List upcoming events for a sport |
| propline odds <sport> [event_id] | Bulk odds (no event_id) or per-event (with). --period q1 (or h1/p1/f5/…) filters to game-period markets; --bookmakers draftkings,fanduel filters to specific books; --links adds each book's public event-page URL (Bovada/DK/FanDuel/BetMGM/Kalshi/Polymarket/Smarkets — also on best-line). |
| propline history <sport> <event_id> | Historical line movement; supports --from/--to, --relative-from/--relative-to, --interval, --changes-only, --period (Hobby+) |
| propline closing <sport> <event_id> | Opening and closing line per (book, market, outcome) — CLV helper. Table shows OPEN / OPEN PRICE beside LINE / PRICE. --period accepted (Hobby+) |
| propline clv <file> | Grade placed bets against their closing lines. Takes a JSON array of bets (or - for stdin) and prints TOOK / CLOSE / CLV / VS DEVIG / ANCHOR / RESULT per bet plus a portfolio summary (Hobby+) |
| propline sgp <sport> <event_id> <file> | Price a same-game parlay at the book's own correlated odds (FanDuel, DraftKings, BetOnline, LowVig — --bookmaker all prints every book side by side). Takes a JSON array of legs named as /odds names them (or - for stdin); prints the SGP price beside the independent product and the correlation factor, then one row per leg with its stored / live price and the book's accept/refuse status. --bookmaker (Hobby+) |
| propline scores <sport> | Recent scores + status |
| propline futures <sport> | Season-long futures — championship/division/conference winners, MVP + awards, season win totals across Bovada/FanDuel/DraftKings/Pinnacle (free) |
| propline context <sport> <event_id> | Game conditions a prop settles under — probable pitchers, lineup, home-plate umpire, first-pitch weather (free) |
| propline movement <sport> <event_id> | Line movement + steam detection across books — sharp-money signal (Hobby+) |
| propline resolution-summary | Graded-prop volume + per-sport breakdown (free) |
| propline live | Every in-progress game across the major sports |
| propline ev <sport> <event_id> | Cross-book +EV vs no-vig fair line (Pro) |
| propline projections <sport> <event_id> | Market-implied consensus projection per (market, player) — the line where no-vig P(over) crosses 50%, median across books (Hobby+) |
| propline best-line <sport> <event_id> | Cross-book line shopping — best price per (market, player, line) across all comparable books. --markets + --bookmakers filters (Hobby+) |
| propline players <sport> <search> | Search players by name fragment — stable player_id + every spelling the books use (free) |
| propline player-history <sport> <player> | Recent prop history for a player on a market. Accepts a name or player_id; --main-line-only drops alt-ladder rungs; the MAIN column marks the main line (M) and in-play line moves (*) |
| propline player-games <sport> <player> | Game log — a player's recent games with every raw box-score stat per game, one call instead of one per event. --opponent BOS for head-to-head (the limit applies after the filter, so it's the last N meetings); --stat-type to narrow. Raw-stat archive, so it includes games no book priced; accepts a player_id in place of the name (free) |
| propline player-trends <sport> <player> | Aggregated hit-rate trends per market — L5/L10/L20/L50 over/under splits + current streak. --market <key> to filter, --dfs-odds-type <flavor> to scope to a PrizePicks flavor (Pro full, Free redacted) |
| propline export-resolved-props --sport <key> | Bulk CSV export of resolved props (Pro) |
| propline webhooks list / create / delete / test / deliveries | Webhook management (Streaming) |
Run propline <cmd> --help for the full flag set on any command.
Global flags
--api-key <key>— overridesPROPLINE_API_KEY--base-url <url>— point at a self-hosted / staging deployment (defaulthttps://api.prop-line.com/v1)--timeout <seconds>— request timeout (default 15)--json— emit raw JSON instead of a table; pipe-friendly withjq
Links
- Website: prop-line.com
- Player props API (markets, books, sports covered): prop-line.com/player-props-api
- API Docs: prop-line.com/docs
- Recipes (code for common jobs): prop-line.com/recipes
- Odds API by sport and market (live line, books, graded hit rate): prop-line.com/odds-api
- Prop resolution (every prop graded against the box score): prop-line.com/prop-resolution-api
- Cross-book +EV: prop-line.com/ev
- Pricing: prop-line.com/pricing
- Dashboard: prop-line.com/dashboard
- OpenAPI reference: api.prop-line.com/docs
- Node SDK (what this wraps):
npm install propline - Python SDK:
pip install propline
License
MIT
Grade your bets against the close
cat > bets.json <<'JSON'
[
{"ref": "b1", "sport_key": "baseball_mlb", "event_id": 150791,
"market": "batter_hits_runs_rbis", "bookmaker": "lowvig",
"selection": "Drake Baldwin", "side": "Under", "point": 0.5,
"price": 145, "stake": 1}
]
JSON
propline clv bets.json1/1 matched
avg CLV +6.52% · vs de-vigged close +0.08% · beat the close 100% · -1u
REF SELECTION TOOK CLOSE CLV VS DEVIG ANCHOR RESULT
b1 Drake Baldwin Under 0.5 +145 +130 +6.52% +0.08% pinnacle lostRead the VS DEVIG column, not CLV. CLV is price-vs-price — familiar,
but vig-blind, so it flatters a bet taken on the juicy side of a wide
market. VS DEVIG scores your price against the de-vigged close and is the
honest number; above they differ by 6.4 points on the same bet.
ANCHOR is the book whose closing pair the de-vig came from — the sharpest
book quoting that line, not the book you bet at. It reads pending when
the event has not started, in which case the "closing" price is just the
latest price and that row is excluded from the summary averages.
Unmatched bets show the reason in the CLOSE column rather than being dropped — matching is fail-closed, so a bet that cannot be pinned to exactly one stored outcome is refused instead of guessed at.
JSON in, JSON out: pipe with - and pass --json to keep it machine-readable.
CSV is deliberately not parsed — a naive split mangles quoted names like
"Tatis Jr., Fernando", and grading the wrong bet is the failure this
endpoint exists to avoid. Convert with jq/csvkit first.
