Read the lineup that won a contest
Winning lineups are the record of what actually worked. This recipe walks the whole contest chain: pick a contest on a slate, page its lineups, take first place, and read the players it rostered. Each hop uses that endpoint's own required filter, so the chain is the only way through — there is no single call that returns a contest's rosters.
- What it is
- Walks the full contest chain to the roster that finished first — the nine players, their salaries, and the prize.
- When to use it
- Use it to study what actually won, to measure how much salary winners left unspent, or to build a corpus of winning constructions.
- What you get back
- The winning entry's rank, score, and payout in cents, then one row per roster slot naming the player and the salary that lineup paid.
1.List the contests on the slate
A main slate carries a few dozen contests, from single-entry qualifiers to mass-entry tournaments. entry_fee and prize_pool are integer CENTS — 3300 is $33.00 and 12500000 is $125,000.
const contests = (await api.dfs.contests.list({ slate_id: 129036, limit: 100 })).contestsThe complete program
Every step as one runnable file. It reads STAT_API_KEY from the environment, and is the same file that ships in the cookbook project for each SDK.
import { StatApi, type DFSContestUserLineup, type DFSContestUserLineupPlayerEntry, type DFSSlatePlayer } from '@stat-api/client'
const api = new StatApi() // reads STAT_API_KEY from the environment
// List the contests on the slate
const contests = (await api.dfs.contests.list({ slate_id: 129036, limit: 100 })).contests
// Keep the single-entry contests
const single = contests.filter((row) => row.max_entries_per_user === 1)
// Take the smallest one
const bysize = [...single].sort((a, b) => a.entry_count - b.entry_count)
// One contest
const contest = bysize.slice(0, 1)
// Page every lineup in that contest
const lineups: DFSContestUserLineup[] = []
for await (const row of api.dfs.contest_user_lineups.iter({ contest_id: contest[0].id })) lineups.push(row)
// Keep the lineups that were scored
const ranked = lineups.filter((row) => row.rank !== null && row.rank !== undefined)
// First place first
const byrank = [...ranked].sort((a, b) => (a.rank ?? 0) - (b.rank ?? 0))
// Take the winner
const winner = byrank.slice(0, 1)
// Show the winning entry
console.log("Winning entry")
console.log(["rank", "points", "winnings"].join('\t'))
for (const row of winner) {
console.log([String(row.rank ?? ''), String(row.points ?? ''), String(row.winnings ?? '')].join('\t'))
}
// Read the nine players it rostered
const roster: DFSContestUserLineupPlayerEntry[] = []
for await (const row of api.dfs.contest_user_lineup_player_entries.iter({ contest_user_lineup_id: winner[0].id })) roster.push(row)
// Page the player pool to resolve names
const pool: DFSSlatePlayer[] = []
for await (const row of api.dfs.slate_players.iter({ slate_id: 129036 })) pool.push(row)
// Index the pool by its own id
const players = new Map<number, DFSSlatePlayer>()
for (const row of pool) players.set(row.id, row)
// Print the winning roster
console.log("The winning lineup")
console.log(["display_name", "roster_position", "position", "salary"].join('\t'))
for (const row of roster) {
console.log([String(players.get(row.slate_player_id)?.display_name ?? row.slate_player_id), String(row.roster_position ?? ''), String(players.get(row.slate_player_id)?.position ?? row.slate_player_id), String(players.get(row.slate_player_id)?.salary ?? row.slate_player_id)].join('\t'))
}