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.
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.
curl -sS --compressed \ -H 'Authorization: Bearer YOUR_API_KEY' \ 'https://api.stat-api.com/api/v1/dfs/contests?limit=100&slate_id=129036'2. Keep the single-entry contests
max_entries_per_user of 1 means every entrant submitted one lineup, so first place belongs to one person rather than to the best of somebody's 150 entries.
const single = contests.filter((row) => row.max_entries_per_user === 1)3. Take the smallest one
Lineups are paged one contest at a time, and a large tournament holds tens of thousands. Starting with the smallest keeps this recipe to a few requests.
const bysize = [...single].sort((a, b) => a.entry_count - b.entry_count)4. One contest
const contest = bysize.slice(0, 1)5. Page every lineup in that contest
One row per submitted lineup, carrying its rank, its score, and its payout.
curl -sS --compressed \ -H 'Authorization: Bearer YOUR_API_KEY' \ 'https://api.stat-api.com/api/v1/dfs/contest_user_lineups?contest_id=1'6. Keep the lineups that were scored
const ranked = lineups.filter((row) => row.rank !== null && row.rank !== undefined)7. First place first
const byrank = [...ranked].sort((a, b) => (a.rank ?? 0) - (b.rank ?? 0))8. Take the winner
const winner = byrank.slice(0, 1)9. Show the winning entry
winnings is in cents, so divide by 100 for dollars.
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')) }10. Read the nine players it rostered
Entries reference the slate player, not the person — slate_player_id points at the pool row, which carries the salary that lineup paid.
curl -sS --compressed \ -H 'Authorization: Bearer YOUR_API_KEY' \ 'https://api.stat-api.com/api/v1/dfs/contest_user_lineup_player_entries?contest_user_lineup_id=1'11. Page the player pool to resolve names
curl -sS --compressed \ -H 'Authorization: Bearer YOUR_API_KEY' \ 'https://api.stat-api.com/api/v1/dfs/slate_players?slate_id=129036'12. Index the pool by its own id
Entries join on slate_players.id, not on player_id.
const players = new Map<number, DFSSlatePlayer>() for (const row of pool) players.set(row.id, row)13. 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')) }