Skip to content

Sleeper API: Free Fantasy League, Matchup and Player Endpoints

Sleeper's official read-only fantasy API, no key needed: every endpoint below answered on 2 November 2026.

Last updated:

What is the Sleeper API?

The Sleeper API is the official read-only HTTP API of Sleeper, the fantasy sports app. It's free for non-commercial use, it needs no API key or token, and Sleeper documents it at docs.sleeper.com. It serves a user's leagues, rosters, weekly matchups, transactions, drafts and the full NFL player map, as JSON from api.sleeper.app/v1.

We called every endpoint on this page on 2 November 2026, with curl's default headers and no account. Sleeper gives you league data: who started whom and what each player scored. For live NFL scores, use the free ESPN API scoreboard; for betting lines, see our NFL odds API guide.

Base URLs

Three hosts cover everything. The API answers with access-control-allow-origin: *, so a browser app can call it directly.

HostWhat it serves
https://api.sleeper.app/v1Users, leagues, rosters, matchups, drafts, players and the season state
https://sleepercdn.com/avatars/{avatar_id}Full-size avatar images for users and leagues
https://sleepercdn.com/avatars/thumbs/{avatar_id}Avatar thumbnails
https://docs.sleeper.comThe official docs

Avatar ids come from the avatar field on a user or league. The docs' league avatar, efaefa889ae24046a53265a3c71b8b64, came back as a 120 by 120 PNG and an 80 by 80 thumbnail. API responses come through Cloudflare with a cache-control header: 60 seconds for the NFL state, 600 for players and 86,400 for a finished league's matchups.

What It Covers

Leagues are NFL only. On the sport parameter, the docs say: "We only support "nfl" right now." Two other paths answered for the NBA in our test: /v1/state/nba (week 3 of the 2026 season) and /v1/players/nba/trending/add.

Old leagues stay online: the docs' example league from 2018 answered with full rosters, matchups, brackets, transactions and draft picks.

The docs list no endpoint for live scores, play-by-play, season stats, projections or odds. For NFL play-by-play, use the nflverse files on our free sports datasets page.

Key Endpoints

Every path starts with https://api.sleeper.app/v1. Each one below returned HTTP 200 on 2 November 2026 with the docs' own example ids.

EndpointWhat it returnsExample
/state/nflCurrent season, week and season typeweek 8, season "2026", season_type "regular"
/user/{username} or /user/{user_id}One user: user_id, username, display_name, avatar/user/sleeperuser
/user/{user_id}/leagues/nfl/{season}Every league a user plays in that season/user/12345678/leagues/nfl/2026 returned []
/league/{league_id}Name, status, settings, scoring and roster slots/league/289646328504385536: "Sleeper Friends League", 2018, 12 teams
/league/{league_id}/rostersEach team's players, starters and season record12 rosters
/league/{league_id}/usersMembers with display_name and metadata.team_name14 users for 12 rosters
/league/{league_id}/matchups/{week}One row per team for the week, with points/matchups/1: 12 rows
/league/{league_id}/winners_bracket, /losers_bracketPlayoff bracket, one row per game7 rows each
/league/{league_id}/transactions/{week}Waiver claims, free agent moves and tradesWeek 1: 154 transactions
/league/{league_id}/traded_picksDraft picks that changed hands4 picks
/league/{league_id}/draftsThe league's drafts1 draft
/draft/{draft_id}Draft settings, order and slot_to_roster_id/draft/289646328508579840
/draft/{draft_id}/picksEvery pick with the player and the roster180 picks
/players/nflEvery NFL player, keyed by player_id12,229 entries
/players/nfl/trending/add, /trending/dropMost added or dropped players25 rows by default

From a username to a league

/user/sleeperuser, the docs' example, returned 200 with display_name "SleeperUser" and an 18-digit user_id string. Pass that id to /user/{user_id}/leagues/nfl/2026; the same path with the username returned 404. Each league in the list carries a league_id. Usernames can change, so store the user_id.

The docs' example users have no 2026 leagues, and the docs give no current league id. So every league call here uses the docs' 2018 example league, 289646328504385536. Swap in your own league id and the paths stay the same.

The Matchups Endpoint

The matchups endpoint returns a league's scores for one week: one row per team, and the two rows that share a matchup_id played each other.

URL
https://api.sleeper.app/v1/league/{league_id}/matchups/{week}

Week 1 of the docs' example league returned 12 rows with matchup_id 1 to 6. Roster 1 had matchup 2 and scored 148.04. Roster 3, its opponent, scored 146.52.

FieldTypeWhat it holds
roster_idintegerThe team; owner_id in /rosters links it to a user
matchup_idinteger or nullThe pairing. Null for a team with no game: four of 12 rows in week 16
pointsfloatTeam total under the league's scoring: 148.04 for roster 1 in week 1
custom_pointsnull or numberA commissioner's manual override, per the docs. Null on every row we saw
startersarray of stringsThe lineup in slot order, as player ids. A team defence shows as its abbreviation, such as "PHI"
starters_pointsarray of floatsPoints for each starter, in the same order as starters
playersarray of stringsEvery player on the roster that week, starters and bench
players_pointsobjectPlayer id to points, for every id in players

On all 36 rows from weeks 1, 13 and 16, points equals the sum of starters_points, and players_points includes the bench. The bench is players minus starters: six players for roster 1. Its second starter, player 4035, scored 43.1, and the player map names him as Alvin Kamara.

The Players Endpoint and Player IDs

Rosters, matchups and picks carry player ids such as "4035", and /players/nfl turns them into names. On 2 November 2026 it returned 14,664,149 bytes (14.7 MB) with 12,229 players in 0.33 seconds, or 2.55 MB with gzip. The docs still give 5 MB as the average size.

Call it once a day

The docs say the player call "is intended only to be used once per day at most to keep your player IDs updated." The second Python sample below caches it for a day.

FieldTypeWhat it holds
player_idstringThe key, the same id that rosters and matchups use: "4881"
full_namestring or null"Lamar Jackson". Null for team defences, which use first_name and last_name ("Philadelphia", "Eagles")
position, fantasy_positionsstring, array"QB" and ["QB"]
teamstring"BAL"
status, injury_statusstring"Inactive" and "Out" for player 4881 on 2 November 2026
activebooleanTrue for 9,422 of the 12,229 entries
espn_id, yahoo_id, gsis_idinteger, integer, stringIds for the same player elsewhere: 3916387, 31002 and "00-0034796"

The 32 team defences are keyed by abbreviation, such as "CLE". ?position=QB&active=true returned 355 players in 435,090 bytes, one of them a tight end with QB in fantasy_positions. Don't copy ids from the docs' sample: it shows 3086 as Tom Brady, while today's map lists Brady under 167.

The nflverse players file uses the same gsis_id values (00-0034796 for Lamar Jackson in both), so Sleeper rosters join to nflverse data. Fantasy lineups and player prop odds share the same problem, since each source keys players its own way.

Trending players

/players/nfl/trending/add and /trending/drop return rows of player_id (string) and count (integer). On 2 November 2026 the top 24-hour add was player 11625, Adonai Mitchell (WR, NYJ), with 505,424 adds. The docs ask you to credit Sleeper when you show trending data.

Parameters, Weeks and Seasons

ParameterWhat it doesExample
week (path)Fantasy week for matchups and transactions/matchups/1; weeks 0, 18 and 99 returned [] for the 2018 league
season (path)Season year for a user's leagues and drafts/leagues/nfl/2026
sport (path)nfl for leagues; state and trending also answered for nba/state/nba
position (query)Players whose fantasy_positions include it?position=QB
active (query)true returns active players only; the docs say other values are ignored?active=true
lookback_hours (query)Trending window in hours, default 24?lookback_hours=48
limit (query)Trending rows, default 25?limit=5 returned 5 rows

The docs call the transactions parameter round, "The week you want to pull from". Week 1 of the 2018 league returned 154 transactions: 81 waiver claims, 69 free agent moves and 4 trades, 55 of them "failed". For the current week, read /state/nfl: week was 8 on 2 November 2026.

There are no date filters, and a new season gets a new league_id: the docs' 2018 league points to 2017 through previous_league_id 198946952535085056, which returned its own league object.

Code Examples

Each sample runs as is, with no key. The Python ones need requests.

One week of matchups

Python
import requests

league_id = '289646328504385536'  # the docs' example league, 2018 season
week = 1
url = f'https://api.sleeper.app/v1/league/{league_id}/matchups/{week}'
rows = requests.get(url, timeout=10).json()
for row in sorted(rows, key=lambda r: r['matchup_id'] or 0):
    print(row['matchup_id'], row['roster_id'], row['points'])

The first line it printed was 1 7 131.34.

The player map, cached for a day

Python
import json
import os
import time

import requests

path = 'sleeper_players_nfl.json'
if not os.path.exists(path) or time.time() - os.path.getmtime(path) > 86400:
    data = requests.get('https://api.sleeper.app/v1/players/nfl', timeout=60).json()
    with open(path, 'w') as f:
        json.dump(data, f)
with open(path) as f:
    players = json.load(f)
p = players['4881']
print(len(players), p['full_name'], p['team'], p['injury_status'])

It printed 12229 Lamar Jackson BAL Out.

A user's leagues

Python
import requests

base = 'https://api.sleeper.app/v1'
user = requests.get(f'{base}/user/sleeperuser', timeout=10).json()
leagues = requests.get(f"{base}/user/{user['user_id']}/leagues/nfl/2026", timeout=10).json()
print(user['display_name'], len(leagues))
for league in leagues:
    print(league['league_id'], league['name'])

It printed SleeperUser 0, because the docs' example user has no 2026 leagues.

cURL

cURL
curl 'https://api.sleeper.app/v1/state/nfl'
curl 'https://api.sleeper.app/v1/players/nfl/trending/add?lookback_hours=24&limit=25'
# the full player map, once a day, gzip on the wire
curl --compressed -o players_nfl.json 'https://api.sleeper.app/v1/players/nfl'

JavaScript

JavaScript
const url = 'https://api.sleeper.app/v1/players/nfl/trending/add?lookback_hours=24&limit=5';
const rows = await fetch(url).then(r => r.json());
for (const row of rows) {
  console.log(row.player_id, row.count);
}

Errors You Will See

404 with a body of null

/league/123, /league/abc and /draft/123 returned 404 with the body null. So did /matchups/abc and a username in the user_id slot. The league in the docs' draft sample, 257270637750382592, also returned 404, though its draft still answers.

200 with null

An unknown username returned 200 with the body null, and so did /state/xyz. Check for null before you read a field.

200 with an empty array

Weeks 0, 18 and 99 for the 2018 league, a user with no leagues and /trending/hold returned []. The calls worked; those weeks and that user had no data.

404 with an HTML page

Unknown paths such as /v1/leagues and /v2/state/nfl returned 404 with an HTML page that redirects to sleeper.com/404. So did /loses_bracket, a typo in the docs' request line; /losers_bracket works.

The docs' example user id

/user/12345678 returned 200 with an account whose username is the string "12345678". The endpoint read the number as a username, and the real user ids we saw ran 15 to 18 digits.

403 on avatars

sleepercdn.com returned 403 AccessDenied for an unknown avatar id. The avatar field can also be null.

429 Too Many Requests

The docs list 429. We made 54 calls in two minutes and got none, and no response carried a rate-limit header.

Limitations and Terms

Free for non-commercial use

The docs: "The Sleeper API is a read-only HTTP API that is free to use for non-commercial purposes and allows access to a user's leagues, drafts, and rosters." For commercial use, Sleeper asks you to email api@sleeper.app "to discuss licensing."

  • Rate limit: the docs say to "stay under 1000 API calls per minute, otherwise, you risk being IP-blocked."
  • Player map: once a day at most, per the docs.
  • Read only: you can't set a lineup or make a trade.
  • Sleeper's general terms: the General Terms of Use, last updated October 6, 2026, bar access to data "through any automated means" without "the express written consent of Sleeper". The terms don't name the API. We read the docs as that consent for non-commercial use; get anything else licensed in writing.
  • Other people's data: /users returns members' display names and team names. The same terms bar copying "information about or regarding other people that use our Services".
  • No SLA: the docs state no uptime commitment.

When your app needs NFL stats, live scores or odds with a contract behind them, compare licensed sports data providers or the odds APIs in our directory.

Browse API Providers →

Community Resources

We found no maintained JavaScript client: the two npm packages we checked have archived or idle repos. Plain fetch works, as the JavaScript sample shows.

Frequently Asked Questions

Yes, for non-commercial use. The docs at docs.sleeper.com say the API "is free to use for non-commercial purposes." Commercial use needs a licence: email api@sleeper.app. Every call on this page went out with no account.
Yes. Sleeper publishes and documents it, unlike the undocumented ESPN API. The docs have small gaps: they misspell the losers bracket path as loses_bracket, which returns 404.
No. The docs say "No API Token is necessary, as you cannot modify contents via this API." A plain GET with your HTTP client's default headers works. The API is read-only, so it can't set lineups or make trades.
NFL fantasy leagues: users, rosters, weekly matchups, brackets, transactions and drafts, plus the NFL player map and trending players. The state and trending endpoints also answered for the NBA. It has no live scores or odds.
The docs say to "stay under 1000 API calls per minute, otherwise, you risk being IP-blocked." We saw no 429 and no rate-limit header in 54 calls over two minutes. Call /players/nfl at most once a day, as the docs ask.
Call https://api.sleeper.app/v1/players/nfl once a day and save the result. On 2 November 2026 it returned 12,229 players keyed by player_id, 14.7 MB uncompressed. Add ?position=QB&active=true for a smaller list of 355.
Call https://api.sleeper.app/v1/user/{username} for the user_id, then https://api.sleeper.app/v1/user/{user_id}/leagues/nfl/2026. Each league in that list has a league_id. Pass the user_id in the second path, because a username there returned 404 in our test.
Only with a licence. The docs limit free use to non-commercial purposes, and Sleeper's general terms bar commercial use without written consent. For NFL data under a contract with support, compare licensed sports data providers or browse the API directory.

Need Licensed NFL Data?

The Sleeper API covers fantasy leagues for personal projects. Commercial apps need a licence, and live scores and odds come from other sources. Compare providers in our directory.