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.
| Host | What it serves |
|---|---|
https://api.sleeper.app/v1 | Users, 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.com | The 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.
| Endpoint | What it returns | Example |
|---|---|---|
/state/nfl | Current season, week and season type | week 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}/rosters | Each team's players, starters and season record | 12 rosters |
/league/{league_id}/users | Members with display_name and metadata.team_name | 14 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_bracket | Playoff bracket, one row per game | 7 rows each |
/league/{league_id}/transactions/{week} | Waiver claims, free agent moves and trades | Week 1: 154 transactions |
/league/{league_id}/traded_picks | Draft picks that changed hands | 4 picks |
/league/{league_id}/drafts | The league's drafts | 1 draft |
/draft/{draft_id} | Draft settings, order and slot_to_roster_id | /draft/289646328508579840 |
/draft/{draft_id}/picks | Every pick with the player and the roster | 180 picks |
/players/nfl | Every NFL player, keyed by player_id | 12,229 entries |
/players/nfl/trending/add, /trending/drop | Most added or dropped players | 25 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.
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.
| Field | Type | What it holds |
|---|---|---|
roster_id | integer | The team; owner_id in /rosters links it to a user |
matchup_id | integer or null | The pairing. Null for a team with no game: four of 12 rows in week 16 |
points | float | Team total under the league's scoring: 148.04 for roster 1 in week 1 |
custom_points | null or number | A commissioner's manual override, per the docs. Null on every row we saw |
starters | array of strings | The lineup in slot order, as player ids. A team defence shows as its abbreviation, such as "PHI" |
starters_points | array of floats | Points for each starter, in the same order as starters |
players | array of strings | Every player on the roster that week, starters and bench |
players_points | object | Player 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.
| Field | Type | What it holds |
|---|---|---|
player_id | string | The key, the same id that rosters and matchups use: "4881" |
full_name | string or null | "Lamar Jackson". Null for team defences, which use first_name and last_name ("Philadelphia", "Eagles") |
position, fantasy_positions | string, array | "QB" and ["QB"] |
team | string | "BAL" |
status, injury_status | string | "Inactive" and "Out" for player 4881 on 2 November 2026 |
active | boolean | True for 9,422 of the 12,229 entries |
espn_id, yahoo_id, gsis_id | integer, integer, string | Ids 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
| Parameter | What it does | Example |
|---|---|---|
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
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
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
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 '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
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:
/usersreturns 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.
Community Resources
- sleeper-api-wrapper on PyPI: a Python wrapper, version 1.2.2 (31 October 2026), MIT licence, Python 3.11 or later. Install it with
pip install sleeper-api-wrapper. - dtsong/sleeper-api-wrapper on GitHub: its source and docs, 102 stars, last commit 1 November 2026. Both answered on 2 November 2026.
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
loses_bracket, which returns 404./players/nfl at most once a day, as the docs ask.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.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.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.