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.

  1. Determine the data you want, and compose the URL based on the endpoint URL pattern.
  2. Request that URL in your browser, program, Postman, cURL, or pigeon.
  3. 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

200Success — enjoy your JSON
301Redirect — URL is bad but Chess.com knows the correct one; update future requests accordingly
304Not Modified — cached version is still current (ETag / If-None-Match or Last-Modified / If-Modified-Since)
404Not Found — URL is malformed or the data does not exist (e.g., a non-existent username)
410Gone — no data will ever be available at this URL; do not request it again
429Too Many Requests — rate limit exceeded; see Rate Limiting above

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

https://api.chess.com/pub/player/{username}

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

https://api.chess.com/pub/titled/{title-abbrev}

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

https://api.chess.com/pub/player/{username}/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

https://api.chess.com/pub/player/{username}/is-online

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

https://api.chess.com/pub/player/{username}/games

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

https://api.chess.com/pub/player/{username}/games/to-move

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

https://api.chess.com/pub/player/{username}/games/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

https://api.chess.com/pub/player/{username}/games/{YYYY}/{MM}

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

https://api.chess.com/pub/player/{username}/games/{YYYY}/{MM}/pgn

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

https://api.chess.com/pub/player/{username}/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

https://api.chess.com/pub/player/{username}/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

https://api.chess.com/pub/player/{username}/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

https://api.chess.com/pub/club/{url-ID}

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

https://api.chess.com/pub/club/{url-ID}/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

https://api.chess.com/pub/club/{url-ID}/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

https://api.chess.com/pub/tournament/{url-ID}

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

https://api.chess.com/pub/tournament/{url-ID}/{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

https://api.chess.com/pub/tournament/{url-ID}/{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

https://api.chess.com/pub/match/{ID}

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

https://api.chess.com/pub/match/{ID}/{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

https://api.chess.com/pub/match/live/{ID}

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

https://api.chess.com/pub/match/live/{ID}/{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

https://api.chess.com/pub/country/{iso}

Get additional details about a country.

Data Format
{
  "@id": "URL",
  "name": "string",
  "code": "string"       // the ISO-3166-1 2-character code
}

Country Players

https://api.chess.com/pub/country/{iso}/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

https://api.chess.com/pub/country/{iso}/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

https://api.chess.com/pub/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

https://api.chess.com/pub/puzzle/random

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

https://api.chess.com/pub/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

https://api.chess.com/pub/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

CodeDescription
winWin
checkmatedCheckmated
agreedDraw agreed
repetitionDraw by repetition
timeoutTimeout
resignedResigned
stalemateStalemate
loseLose
insufficientInsufficient material
50moveDraw by 50-move rule
abandonedAbandoned
kingofthehillOpponent king reached the hill
threecheckChecked for the 3rd time
timevsinsufficientDraw by timeout vs insufficient material
bughousepartnerloseBughouse partner lost