Chess.com API
Overview
The PubAPI is a read-only REST API that responds with JSON-LD data. Its goal is to re-package all currently public data from the website. "Public Data" is information available to people who are not logged in — player data, game data, club/tournament information. Private information restricted to the logged-in user (game chat, conditional moves) is excluded.
This is read-only data. You cannot send game moves or other commands to Chess.com from this system.
- Determine the data you want, and compose the URL based on the endpoint URL pattern.
- Request that URL in your browser, program, Postman, cURL, or pigeon.
- Enjoy the JSON.
All time fields are Unix timestamps — the number of seconds since January 1, 1970 00:00:00 GMT.
General Use
Data Currency
About 3% of players still use the old "v2" website for some actions. When those players modify data you are requesting, the data may be out of date. This does not apply to mobile app users.
Default refresh: endpoints refresh at most once every 24 hours unless otherwise noted.
Language
URL responses are the same for everyone regardless of who or where they are. In cases where the data contain words (game-ending reasons, error responses), those words will be in English.
Rate Limiting
Serial access rate is unlimited — if you always wait for the previous response before making the next request, you should never encounter rate limiting.
Parallel requests (threaded apps, webservers handling multiple simultaneous requests) may be blocked. Be prepared to handle a 429 Too Many Requests response for any non-serial request.
Abnormal or suspicious activity may result in your application being blocked entirely. Supplying a recognizable user-agent with contact information gives Chess.com a way to reach you if a block is necessary.
How to Get the Data
The PubAPI endpoints can be called by any client or browser that supports HTTP.
- Browser: paste the endpoint URL directly into the address bar.
- cURL:
curl -v https://api.chess.com/pub/player/hikaru— returns response code, ETag, date, last-modified, and more. - Postman / Insomnia: a downloadable collection of all endpoints is available from Chess.com.
- jq: pair with cURL to filter and transform JSON on the command line.
HTTP Responses
JSON-LD
Each response includes a "linked data" context. JSON-LD is fully compatible with regular JSON. An HTTP Link header points to the JSON-LD context URL for the data format, helping the data describe its own meaning.
JSONP
A callback parameter in any query string is treated as a JavaScript function name to call with the data — useful for <script> tag usage.
Example: https://api.chess.com/pub/player/erik?callback=myFunction
Function names containing non-literal characters or exceeding 200 characters are stripped from the response.
Caching
Each response includes ETag and Last-Modified headers. Supply If-None-Match or If-Modified-Since in your request to receive a 304 Not Modified response when data has not changed.
If you request faster than the Cache-Control max-age, the CDN may respond directly with cached values. Response headers may indicate a cache HIT, MISS, EXPIRED, or REVALIDATED.
HTTP Compression & HTTP/2
Send Accept-Encoding: gzip to receive gzip-compressed responses for large payloads (generally >200 bytes) — saving up to 80% of download bandwidth.
HTTP/2 requests receive HTTP/2 responses: header compression, binary transfer, and multiplexed responses. Note the parallel rate-limiting caveats above.
Player Data
Player Profile
Get additional details about a player.
Data Format
{
"@id": "URL", // the location of this profile (always self-referencing)
"url": "URL", // the chess.com user's profile page
"username": "string",
"player_id": 41, // the non-changing Chess.com ID of this player
"title": "string", // (optional) abbreviation of chess title, if any
"status": "string", // closed, closed:fair_play_violations, basic, premium, mod, staff
"name": "string", // (optional) personal first and last name
"avatar": "URL", // (optional) URL of a 200x200 image
"location": "string",// (optional) city or location
"country": "URL", // API location of this player's country's profile
"joined": 1178556600,
"last_online": 1500661803,
"followers": 17,
"is_streamer": "boolean",
"twitch_url": "Twitch.tv URL",
"fide": "integer"
} The player_id is a convenience for detecting username changes. If a retrieved Profile has a player_id matching one you previously downloaded, the new Profile replaces the old. This ID will never change for a given account, though its future availability is not guaranteed.
Titled Players
List of titled-player usernames.
Valid title abbreviations: GM, WGM, IM, WIM, FM, WFM, NM, WNM, CM, WCM.
Data Format
{
"players": [
/* array of usernames for players with this title */
]
} Player Stats
Ratings, win/loss, and other stats about a player's game play, tactics, lessons, and Puzzle Rush score.
The response contains "stats objects" identified by rules code + underscore + time-class code (e.g., chess_daily, chess960_blitz). If a player has not played a particular game type, no stats object is present.
Data Format — Response Wrapper
{
"chess_daily": { /* stats object for chess / daily */ },
"chess960_daily": { /* stats object for chess960 / daily */ },
"chess_blitz": { /* stats object for chess / blitz */ },
/* additional game-type keys as applicable */
"tactics": {
"highest": { "rating": "integer", "date": "timestamp" },
"lowest": { "rating": "integer", "date": "timestamp" }
},
"lessons": {
"highest": { "rating": "integer", "date": "timestamp" },
"lowest": { "rating": "integer", "date": "timestamp" }
},
"puzzle_rush": {
"daily": { "total_attempts": "integer", "score": "integer" },
"best": { "total_attempts": "integer", "score": "integer" }
}
} Data Format — Each Game-Type Stats Object
{
"last": {
"date": 1509709165, // timestamp of the last rated game finished
"rating": 1642, // most-recent rating
"rd": 58 // Glicko "RD" value used to calculate ratings changes
},
"best": {
"date": 1256228875,
"rating": 2065, // highest rating achieved
"game": "URL" // URL of the best-win game
},
"record": {
"win": 177,
"loss": 124,
"draw": 21,
"time_per_move": 18799, // seconds per average move
"timeout_percent": 9.99 // timeout percentage in the last 90 days
},
"tournament": {
"count": 20,
"withdraw": 1,
"points": 39,
"highest_finish": 1
}
} Stats objects only contain information that has been collected and is not at a default value. Tactics, Lessons, and Puzzle Rush stats may be absent depending on player activity.
Player Online Status
Tells if a user has been online in the last five minutes.
Data Format
{
"online": boolean
} Player Games
Five endpoints cover a player's games: current, to-move, archive list, monthly archive, and PGN download. The current, to-move, and monthly archive endpoints all wrap their arrays in:
{ "games": [ /* Game objects in ascending game-end-time order */ ] } Shared game object fields: pgn, rules (chess, chess960, bughouse, kingofthehill, threecheck, crazyhouse), time_class (daily, rapid, blitz, bullet), time_control, last_activity.
Current Daily Chess
Array of Daily Chess games that a player is currently playing.
Data Format
{
"games": [
{
"white": "string", // URL of the white player's profile
"black": "string", // URL of the black player's profile
"url": "string",
"fen": "string", // current FEN
"pgn": "string", // current PGN
"turn": "black", // player to move
"move_by": 1501765498, // "0" if the player-to-move is on vacation
"draw_offer": "black", // (optional) player who has made a draw offer
"last_activity": 1509810789,
"start_time": 1254438881, // Daily Chess only
"time_control": "string",
"time_class": "string",
"rules": "string",
"tournament": "string", // URL pointing to tournament (if available)
"match": "string" // URL pointing to team match (if available)
}
]
} To-Move Daily Chess
Array of Daily Chess games where it is the player's turn to act.
Data Format
{
"games": [
{
"url": "string",
"move_by": 1254438881, // "0" if it is not this player's turn
"draw_offer": true, // (optional) this player has received a draw offer
"last_activity": 1509810789
}
]
} This list may sometimes include games where it is not the player's turn, if a draw offer has been made. In those cases move_by is "0" and the game is sorted to the top. Normal sorting is based on move deadline.
List of Monthly Archives
Array of monthly archives available for this player.
Data Format
{
"archives": [
/* array of URLs for monthly archives in ascending chronological order */
]
} Complete Monthly Archive
Array of Live and Daily Chess games that a player has finished. YYYY is the four-digit year and MM is the two-digit month of game-end.
Data Format — Each Game
{
"white": {
"username": "string",
"rating": 1492,
"result": "string", // see Game Results Codes
"@id": "string"
},
"black": {
"username": "string",
"rating": 1942,
"result": "string",
"@id": "string"
},
"accuracies": { "white": float, "black": float },
"url": "string",
"fen": "string",
"pgn": "string",
"start_time": 1254438881, // Daily Chess only
"end_time": 1254670734,
"time_control": "string",
"rules": "string",
"eco": "string", // URL pointing to ECO opening (if available)
"tournament": "string",
"match": "string"
} Multi-Game PGN Download
Standard multi-game PGN file containing all games for a month. Not JSON-encoded — follows the PGN standard directly.
Response headers: Content-Type: application/x-chess-pgn and Content-Disposition: attachment; filename="ChessCom_username_YYYYMM.pgn". Browsers handle these automatically.
Player's Clubs
List of clubs the player is a member of, with joined date and last activity date.
Data Format
{
"clubs": [
{
"@id": "URL",
"name": "string",
"last_activity": "timestamp",
"icon": "URL",
"url": "URL",
"joined": "timestamp"
}
]
} Player Matches
List of Team matches the player has attended, is participating in, or is currently registered for.
Data Format
{
"finished": [
{
"name": "string",
"url": "URL",
"@id": "URL",
"club": "URL",
"results": {
"played_as_white": "win", // see Game Results Codes
"played_as_black": "win"
},
"board": "URL"
}
],
"in_progress": [
{ "name": "string", "url": "URL", "@id": "URL", "club": "URL", "board": "URL" }
],
"registered": [
{ "name": "string", "url": "URL", "@id": "URL", "club": "URL" }
]
} Player's Tournaments
List of tournaments the player is registered for, is attending, or has attended in the past.
Data Format
{
"finished": [
{
"url": "URL", "@id": "URL",
"wins": 3, "losses": 5, "draws": 0,
"points_awarded": 0, "placement": 4,
"status": "eliminated", // winner, eliminated, withdrew, removed
"total_players": 5
}
],
"in_progress": [
{ "url": "URL", "@id": "URL", "status": "eliminated" }
],
"registered": [
{ "url": "URL", "@id": "URL", "status": "invited" }
]
} Clubs
All club-based URLs use the club's "URL ID": https://api.chess.com/pub/club/{url-ID}. The url-ID matches the club's URL on www.chess.com — for example, the url-ID for the Chess.com Developer Community is chess-com-developer-community.
Club Profile
Get additional details about a club.
Data Format
{
"@id": "URL",
"name": "string",
"club_id": 57796,
"icon": "URL", // (optional) URL of a 200x200 image
"country": "URL",
"average_daily_rating": 1376,
"members_count": 54,
"created": 1178556600,
"last_activity": 1500661803,
"visibility": "public", // "public" or "private"
"join_request": "URL",
"admin": [ /* array of URLs to player profiles for the admins */ ],
"description": "string"
} Club Members
List of club members (username and joined timestamp), grouped by club-activity frequency.
Cache: refreshes at most once every 12 hours.
Club activity includes: viewing the club homepage, news, or forums; changing club settings; viewing tournament, match, or votechess lists; viewing membership lists or leaderboards. Playing a club game does not count.
Data Format
{
"weekly": [ { "username": "string", "joined": "integer" } ],
"monthly": [ { "username": "string", "joined": "integer" } ],
"all_time": [ { "username": "string", "joined": "integer" } ]
} Lists are only updated when members join, leave, or are banned. A member may not move to the weekly list for up to 24 hours after their next club activity.
Club Matches
List of daily and club matches, grouped by status (registered, in progress, finished).
Data Format
{
"finished": [
{
"name": "string", "@id": "URL", "opponent": "URL",
"result": "win", "start_time": 1305324926, "time_class": "daily"
}
],
"in_progress": [
{ "name": "string", "@id": "URL", "opponent": "URL",
"start_time": 1305324926, "time_class": "daily" }
],
"registered": [
{ "name": "string", "@id": "URL", "opponent": "URL", "time_class": "daily" }
]
} Tournaments
All tournament-based URLs use the tournament's "URL ID": https://api.chess.com/pub/tournament/{url-ID}. The url-ID matches the URL on www.chess.com — for example, -33rd-chesscom-quick-knockouts-1401-1600.
Tournament
Get details about a daily, live, or arena tournament.
Data Format
{
"name": "string", "url": "URL", "description": "string",
"creator": "string", // username of creator
"status": "finished", // finished, in_progress, registration
"finish_time": 1251846528,
"settings": {
"type": "round_robin", "rules": "string",
"time_class": "daily", "time_control": "1/259200",
"is_rated": true, "is_official": false, "is_invite_only": false,
"initial_group_size": 5, "user_advance_count": 1,
"use_tiebreak": true, "allow_vacation": false,
"winner_places": 1, "registered_user_count": 5,
"games_per_opponent": 2, "total_rounds": 1,
"concurrent_games_per_opponent": 1
},
"players": [ { "username": "string", "status": "eliminated" } ],
"rounds": [ /* list of round URLs */ ]
} Tournament Round
Get details about a tournament's round.
Data Format
{
"groups": [ /* list of tournament round groups */ ],
"players": [
{ "username": "string", "is_advancing": false }
]
} Tournament Round Group
Get details about a tournament's round group.
Data Format
{
"fair_play_removals": [ /* usernames closed for fair play violation */ ],
"games": [
{
"white": "string", "black": "string", "url": "string",
"fen": "string", "pgn": "string", "turn": "black",
"move_by": 1501765498, "draw_offer": "black",
"last_activity": 1509810789, "start_time": 1254438881,
"time_control": "string", "time_class": "string",
"rules": "string", "eco": "string", "tournament": "string"
}
],
"players": [
{
"username": "string",
"points": 2, // adjusted in case of fair play recalculations
"tie_break": 6,
"is_advancing": false
}
]
} Team Matches
Daily team match URLs use the match ID: https://api.chess.com/pub/match/{ID}. The ID matches the URL on www.chess.com — for example, WORLD LEAGUE Round 5 has ID 12803.
Live team match URLs use: https://api.chess.com/pub/match/live/{ID}.
Daily Team Match
Get details about a daily team match and players playing that match. After the match is finished, a link to each player's stats endpoint is provided for up-to-date information.
Data Format — Registration Phase
{
"name": "string", "url": "URL", "description": "string",
"start_time": "timestamp",
"settings": {
"time_class": "daily", "time_control": "string",
"rules": "string", "min_team_players": "integer",
"max_team_players": "integer", "min_required_games": "integer",
"min_rating": "integer", "max_rating": "integer", "autostart": "boolean"
},
"status": "registration",
"boards": "integer",
"teams": {
"team1": {
"@id": "URL", "url": "URL", "name": "string", "score": "score",
"players": [
{ "username": "string", "board": "URL", "rating": 1355,
"rd": 25.12, "timeout_percent": 25.12, "status": "basic" }
]
},
"team2": { /* same structure as team1 */ }
}
} Data Format — In Progress / Finished
{
"name": "string", "url": "URL", "description": "string",
"start_time": "timestamp",
"settings": {
"time_class": "string", "time_control": "string", "rules": "string",
"min_team_players": 0, "max_team_players": 0,
"min_required_games": 0, "autostart": false
},
"status": "string", // finished or in_progress
"boards": "integer",
"teams": {
"team1": {
"@id": "URL", "name": "string", "score": "score",
"players": [
{
"username": "string", "board": "URL",
"stats": "URL", // URL to player's stats endpoint
"played_as_white": "string",
"played_as_black": "string"
}
],
"fair_play_removals": [ /* usernames closed during match */ ]
},
"team2": { /* same structure as team1 */ }
}
} Player statistics are not snapshotted during matches. After the registration phase, follow each player's stats link to get up-to-date statistics.
Daily Team Match Board
Get details about a team match board. Only in-progress or finished games are included.
Data Format
{
"board_scores": { "player1": 0.5, "player2": 1.5 },
"games": [
{
"white": { "username": "string", "rating": 1492, "result": "string",
"@id": "string", "team": "URL" },
"black": { "username": "string", "rating": 1942, "result": "string",
"@id": "string", "team": "URL" },
"accuracies": { "white": float, "black": float },
"url": "string", "fen": "string", "pgn": "string",
"start_time": 1254438881, "end_time": 1254670734,
"time_control": "string", "time_class": "string",
"rules": "string", "eco": "string", "match": "string"
}
]
} Live Team Match
Get details about a live team match and the players participating. After the match is finished, a stats link is provided for each player.
Data Format — When Scheduled
{
"@id": "https://api.chess.com/pub/match/live/5861",
"name": "Friendly 10|2 Rapid Open",
"url": "https://www.chess.com/club/matches/live/5861",
"start_time": 1579988425, "status": "scheduled", "boards": 0,
"settings": {
"rules": "chess", "time_class": "standard", "time_control": 600,
"time_increment": 2, "min_team_players": 1,
"min_required_games": 0, "autostart": false
},
"teams": {
"team1": {
"@id": "URL", "name": "string", "url": "URL",
"score": 0, "players": [], "fair_play_removals": []
},
"team2": { /* same structure */ }
}
} Data Format — When Finished
{
"@id": "https://api.chess.com/pub/match/live/5833",
"name": "Friendly 5+2",
"url": "https://www.chess.com/club/matches/live/5833",
"start_time": 1579471260, "end_time": 1579472487,
"status": "finished", "boards": 6,
"settings": { "rules": "chess", "time_class": "blitz", "time_control": 300,
"time_increment": 2, "min_team_players": 2,
"min_required_games": 0, "autostart": false },
"teams": {
"team1": {
"@id": "URL", "name": "string", "url": "URL",
"score": 7, "result": "win",
"players": [
{
"username": "string", "stats": "URL", "status": "premium",
"played_as_white": "win", "played_as_black": "resigned",
"board": "URL"
}
],
"fair_play_removals": []
},
"team2": { /* same structure */ }
}
} Live Team Match Board
Get details about a live team match board. Only in-progress or finished games are included.
Data Format
{
"board_scores": { "player1": 1.5, "player2": 0.5 },
"games": [
{
"url": "string", "pgn": "string", "time_control": "300+2",
"end_time": 1579471691, "rated": true,
"fen": "r7/p4pN1/1pn4k/8/2bP3R/2P3R1/6PP/6K1 b - -",
"time_class": "blitz", "rules": "chess",
"white": { "rating": 1351, "result": "win",
"@id": "URL", "username": "string" },
"black": { "rating": 1458, "result": "checkmated",
"@id": "URL", "username": "string" },
"eco": "URL"
}
]
} Countries
All country-based URLs use the 2-character ISO 3166 code (capitalized): https://api.chess.com/pub/country/{iso}.
Chess.com also supports regions not in the ISO list, using user-assigned codes: XA Canary Islands, XB Basque Country, XC Catalonia, XE England, XG Galicia, XK Kosovo, XP Palestine, XS Scotland, XW Wales, XX International.
Country Profile
Get additional details about a country.
Data Format
{
"@id": "URL",
"name": "string",
"code": "string" // the ISO-3166-1 2-character code
} Country Players
List of usernames for players who identify themselves as being in this country.
Cache: refreshes at most once every 12 hours.
Complete lists of all players are not available. Requesting once per day yields all new registrants and currently active players who identify with this country.
Data Format
{
"players": [ /* array of usernames for recently active players */ ]
} Country Clubs
List of URLs for clubs identified as being in or associated with this country.
The "country" of a club is self-reported and may indicate player location, meeting location, language spoken, or simply the country of the founder.
Data Format
{
"clubs": [ /* array of profile URLs for clubs in this country */ ]
} Daily Puzzles
Daily Puzzle
Information about the daily puzzle found on www.chess.com.
Data Format
{
"title": "string",
"url": "URL",
"publish_time": 1513584000,
"fen": "string",
"pgn": "string",
"image": "URL"
} If you publish the Daily Puzzle somewhere, please give credit to Chess.com with a clearly visible text link to the puzzle page URL.
Random Daily Puzzle
Information about a randomly picked daily puzzle.
The puzzle doesn't change with every request — there is a caching latency of around 15 seconds. If you publish it, credit Chess.com with a text link to the puzzle page URL.
Data Format
{
"title": "string", "url": "URL",
"publish_time": 1513584000,
"fen": "string", "pgn": "string", "image": "URL"
} Streamers
Streamers
Information about Chess.com streamers. Refreshes every 5 minutes.
Data Format
{
"streamers": [
{ "username": "string", "avatar": "URL",
"twitch_url": "Twitch.tv URL", "url": "string" }
]
} Leaderboards
Leaderboards
Top 50 players for daily and live games, tactics, and lessons. Refreshes when one of the leaderboards is updated.
Arrays: daily, daily960, live_rapid, live_blitz, live_bullet, live_bughouse, live_blitz960, live_threecheck, live_crazyhouse, live_kingofthehill, lessons, tactics.
Data Format — Each Entry
{
"player_id": "integer", "@id": "URL", "url": "URL",
"username": "string", "score": "integer",
"rank": "integer" // [1..50]
} Game Results Codes
| Code | Description |
|---|---|
| win | Win |
| checkmated | Checkmated |
| agreed | Draw agreed |
| repetition | Draw by repetition |
| timeout | Timeout |
| resigned | Resigned |
| stalemate | Stalemate |
| lose | Lose |
| insufficient | Insufficient material |
| 50move | Draw by 50-move rule |
| abandoned | Abandoned |
| kingofthehill | Opponent king reached the hill |
| threecheck | Checked for the 3rd time |
| timevsinsufficient | Draw by timeout vs insufficient material |
| bughousepartnerlose | Bughouse partner lost |