Score every add/drop a team could make from the waiver wire: for each of the most-rostered available players at each starting position, the best player to drop for them and how much the team's optimal starting lineup gains, week by week, using the league's own lineup optimizer (see best_roster()) and ESPN's per-week projections. The pickup counterpart to evaluate_trade().

waiver_upgrades(
  leagueId = ffl_id(),
  teamId,
  seasonId = ffl_year(),
  scoringPeriodId = ffl_week(),
  useScore = c("projectedScore", "actualScore"),
  limit = 10,
  cookie = ffl_cookie()
)

Arguments

leagueId

Numeric league ID or ESPN fantasy page URL. Defaults to getOption("fflr.leagueId"). Function fails if no ID is found.

teamId

The team ID looking for upgrades (see league_teams()).

seasonId

Integer year of the NFL season. Defaults to the current season (see ffl_year()) rather than ffl_api()'s fixed default, which is only right for the year of the fflr release.

scoringPeriodId

Integer vector of one or more weeks to score, or "rest" for the rest of the regular season. Defaults to the current week (see ffl_week()).

useScore

One of "projectedScore" (default) or "actualScore".

limit

The number of available players to consider at each position, most rostered first. Defaults to 10.

The alphanumeric espn_s2 cookie string from a signed-in session, defaulting to ffl_cookie(). Since 2025, this cookie is required by the leagueHistory endpoint. Past seasons can also be requested without a cookie by passing an explicit seasonId instead of using leagueHistory = TRUE.

Value

A tibble with one row per add that improves the lineup, best first: the player to add and their status ("FREEAGENT" or "WAIVERS"), the player to drop (NA with an open roster spot), the optimal starting score summed over the scored weeks without the move (scoreBefore) and with it (scoreAfter), their difference (delta), the number of weeks the move helps (weeksImproved), and the players the add takes a starting spot from in any of those weeks (startersOut). Player lists are comma-separated names, NA when empty; no rows if nothing helps.

Details

The pool is today's free agents and players on waivers (see status in the output), the top limit at each single-position starting slot by percent rostered – the same pool evaluate_trade() and best_roster() take their replacement-level stand-ins from. It's today's pool, not a forecast of who will be available in later weeks.

If the roster has an open spot (not counting IR), nobody is dropped. Otherwise each add is paired with the drop that costs the least: a player who wouldn't start in any scored week after the add costs nothing, and of those, the one with the lowest total score is chosen; if every player would start at some point, each is tried. Players on IR are never dropped, since dropping them frees no roster spot.

Examples

if (FALSE) { # \dontrun{
waiver_upgrades(teamId = 6)
waiver_upgrades(teamId = 6, scoringPeriodId = "rest")
} # }