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()
)Numeric league ID or ESPN fantasy page URL. Defaults to
getOption("fflr.leagueId"). Function fails if no ID is found.
The team ID looking for upgrades (see league_teams()).
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.
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()).
One of "projectedScore" (default) or "actualScore".
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.
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.
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.
Other roster functions:
best_roster(),
evaluate_trade(),
roster_score(),
start_roster(),
team_roster()
if (FALSE) { # \dontrun{
waiver_upgrades(teamId = 6)
waiver_upgrades(teamId = 6, scoringPeriodId = "rest")
} # }