See where a player's fantasy points came from
A fantasy score is a sum, and the parts are what you can model. dfs.player_stats publishes every scoring category as its own column: passing_yds_fpts, rushing_td_fpts, reception_fpts, and 23 more. The raw box-score numbers sit beside them, so you can check the arithmetic yourself. Nothing is nested in JSON, and nothing needs parsing.
- What it is
- Splits a single fantasy score into the 26 scoring categories that produced it, next to the raw box-score numbers behind each one.
- When to use it
- Use it to reproduce an operator's scoring exactly, to explain a surprising score, or to compare how two operators pay for the same performance.
- What you get back
- One row carrying fantasy_pts, every *_fpts category column, and the raw yardage, touchdown, and reception counts on the same row.
1.Read one player's slate history
player_id is a standalone filter, so one player's rows across every slate come back in a single call. Player 301 is a quarterback, whose score splits across the most categories — take any id from the salary-board recipe.
const rows = (await api.dfs.player_stats.list({ player_id: 301, limit: 200 })).player_statsThe 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 } from '@stat-api/client'
const api = new StatApi() // reads STAT_API_KEY from the environment
// Read one player's slate history
const rows = (await api.dfs.player_stats.list({ player_id: 301, limit: 200 })).player_stats
// Keep the games that were played
const played = rows.filter((row) => row.fantasy_pts !== null && row.fantasy_pts !== undefined)
// Best game first
const best = [...played].sort((a, b) => (b.fantasy_pts ?? 0) - (a.fantasy_pts ?? 0))
// Take the single best game
const top = best.slice(0, 1)
// Split the score into its categories
console.log("Where the points came from")
console.log(["fantasy_pts", "passing_yds_fpts", "passing_td_fpts", "rushing_yds_fpts", "rushing_td_fpts", "receiving_yds_fpts", "reception_fpts"].join('\t'))
for (const row of top) {
console.log([String(row.fantasy_pts ?? ''), String(row.passing_yds_fpts ?? ''), String(row.passing_td_fpts ?? ''), String(row.rushing_yds_fpts ?? ''), String(row.rushing_td_fpts ?? ''), String(row.receiving_yds_fpts ?? ''), String(row.reception_fpts ?? '')].join('\t'))
}
// Compare against the raw box score
console.log("The raw stats behind those points")
console.log(["passing_yds", "passing_tds", "rushing_yds", "rushing_tds", "receptions", "receiving_yds", "receiving_tds"].join('\t'))
for (const row of top) {
console.log([String(row.passing_yds ?? ''), String(row.passing_tds ?? ''), String(row.rushing_yds ?? ''), String(row.rushing_tds ?? ''), String(row.receptions ?? ''), String(row.receiving_yds ?? ''), String(row.receiving_tds ?? '')].join('\t'))
}