Classic Chess · REST API

Study archive

The public archive is the Classic Chess hand-curated collection of player and event memberships over shared game records. The inventory endpoints expose every player and event archive, while the shared game list includes both. Player-backed results retain a readable player_slug/game_slug token for compatibility; event-only results use their canonical game_slug; the returned URLs always identify the shared canonical game record.

Christian J. Walls' personal over-the-board games at /christian_walls/games/ are deliberately not part of the API. They stay on the website only.

GET /api/v1/public/players/

List all curated study players with at least one game. This catalog is not paginated. JSON includes approved bios, portraits, counts, and profile, bio, notable-game, archive, and PGN links.

ParameterRequiredDescription
qnoFilter players by name, slug, or source alias.

Optional format=txt returns only names; bucket selects an era key from archive_buckets.

Examples · complete JSON catalog, then a filtered result

curl -fsS "https://classicchess.com/api/v1/public/players/"
curl -fsS "https://classicchess.com/api/v1/public/players/?q=tal"

Response

{
  "source": "public",
  "query": "tal",
  "count": 1,
  "results": [
    {
      "name": "Mikhail Tal",
      "slug": "mikhail-tal",
      "game_count": 2431,
      "criteria": "World Champion 1960-1961",
      "urls": {
        "api_games": "/api/v1/public/games/?archive_player=mikhail-tal",
        "html_games": "/players/mikhail-tal/games/",
        "html_about": "/players/mikhail-tal/about/"
      }
    }
  ]
}
GET /api/v1/public/events/

List every curated study event in one unpaginated response, including canonical metadata, series, game count, and event-scoped API links. Use format=txt for names only.

ParameterRequiredDescription
qnoFilter events by name, slug, series, site, source label, or year.

Example

curl "https://classicchess.com/api/v1/public/events/?q=London"

Response

{
  "source": "public",
  "query": "London",
  "count": 1,
  "results": [
    {
      "name": "London 1851",
      "slug": "london-1851",
      "event_type": { "key": "tournament", "label": "Tournament" },
      "year": 1851,
      "game_count": 85,
      "expected_game_count": 85,
      "series": null,
      "urls": {
        "api_games": "/api/v1/public/games/?archive_event=london-1851",
        "html_games": "/events/london-1851/games/",
        "html_about": "/events/london-1851/about/"
      }
    }
  ]
}
GET /api/v1/public/games/

Search every public archive game, including event-only games. Returns a paginated list of game summaries whose navigable URLs target the shared canonical game record.

ParameterRequiredDescription
qnoFree-text query matched against players, event, site, date, ECO, and opening.
archive_playernoRestrict to one archive by player slug, name, or alias.
archive_eventnoRestrict to one event archive by the slug returned from the events endpoint.
search_modenoall (default) searches every field. players searches players, event, site, and date. openings searches opening name and ECO.
sincenoInclude games from this year or later.
untilnoInclude games from this year or earlier.
sortnoasc (default) or desc by game date.
pagenoPage number (default 1).
page_sizenoItems per page (default 50, max 100).

Example

curl "https://classicchess.com/api/v1/public/games/?archive_player=mikhail-tal&since=1960&until=1965&sort=asc"

Response

{
  "source": "public",
  "query": "",
  "archive_player": "mikhail-tal",
  "search_mode": "all",
  "since": 1960,
  "until": 1965,
  "sort": "asc",
  "count": 42,
  "page": 1,
  "page_size": 50,
  "page_count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "token": "mikhail-tal/tal-vs-larsen-1965",
      "player": { "name": "Mikhail Tal", "slug": "mikhail-tal" },
      "white": "Tal, Mikhail",
      "black": "Larsen, Bent",
      "display_white": "Tal, Mikhail",
      "display_black": "Larsen, Bent",
      "result": "1-0",
      "result_key": "win",
      "event": "Candidates",
      "site": "Bled",
      "date": "1965.07.20",
      "played_on": "1965-07-20",
      "round": "5",
      "white_elo": null,
      "black_elo": null,
      "eco": "B33",
      "opening": "Sicilian, Sveshnikov",
      "move_count": 41,
      "urls": {
        "api_detail": "/api/v1/public/games/tal-vs-larsen-1965/",
        "api_pgn": "/api/v1/public/games/tal-vs-larsen-1965/pgn/",
        "gif": "/games/tal-vs-larsen-1965/gif/",
        "html": "/games/tal-vs-larsen-1965/",
        "pgn_download": "/games/tal-vs-larsen-1965/download/"
      }
    }
  ]
}
GET/POST /api/v1/public/games/export/

Export up to 300 player- or event-backed public archive games per request as PGN or newline-delimited JSON. Query exports stop at the first 300 matches; follow paginated game results and batch their tokens to retrieve a larger archive. Canonical game slugs and the legacy player-scoped token form are both supported.

ParameterRequiredDescription
qnoFree-text archive search.
archive_playernoRestrict to one archive.
archive_eventnoRestrict to one event archive.
search_modenoall (default) searches every field. players searches players, event, site, and date. openings searches opening name and ECO.
sincenoInclude games from this year or later.
untilnoInclude games from this year or earlier.
tokensnoComma-separated canonical game_slug or legacy player_slug/game_slug tokens, max 300 and up to 64 KiB.
formatnopgn (default) or ndjson.
pgnInJsonnoInclude PGN in NDJSON rows (default true).

For POST, send the same compatibility token list as comma- or newline-separated text/plain.

Example

curl "https://classicchess.com/api/v1/public/games/export/?archive_player=mikhail-tal&since=1960&until=1965" -o tal-1960-1965.pgn
GET /api/v1/public/games/{game_slug}/

Canonical full detail for one public archive game. It works for player-backed and event-only games, returns the same shared Game identity, archive memberships, full PGN, and board-ready mainline.

Example

curl "https://classicchess.com/api/v1/public/games/tal-vs-larsen-1965/"
GET /api/v1/public/games/{game_slug}/pgn/

The canonical public PGN as text/plain.

Example

curl "https://classicchess.com/api/v1/public/games/tal-vs-larsen-1965/pgn/" -o tal.pgn
GET /api/v1/public/games/{player_slug}/{game_slug}/

Player-context compatibility detail, retained for existing clients. New integrations should use the canonical game-slug endpoint above.

Example

curl "https://classicchess.com/api/v1/public/games/mikhail-tal/tal-vs-larsen-1965/"
GET /api/v1/public/games/{player_slug}/{game_slug}/pgn/

Player-context compatibility PGN. New integrations should use the canonical game-slug endpoint above.

Example

curl "https://classicchess.com/api/v1/public/games/mikhail-tal/tal-vs-larsen-1965/pgn/" -o tal.pgn
GET /api/v1/public/games/{game_slug}/gif/

Animated GIF of one public archive game. Needs a registered account: a personal API token of any scope, a device session, or a signed-in browser. Add orientation=black to flip the board, or format=mp4 for the same animation as an H.264 MP4 video. Exports share the per-account GIF limit; a 429 carries Retry-After.

GET /api/v1/public/imported-games/{username}/{game_slug}/

A game another account imported and made public, looked up by the username and slug in its page address. Returns the importer's username, PGN, board-ready mainline and links. Other accounts' imports are never listed, and private imports return 404 to everyone.

GET /api/v1/public/imported-games/{username}/{game_slug}/pgn/

The same PGN the public imported game page downloads.

GET /api/v1/public/imported-games/{username}/{game_slug}/gif/

Animated GIF of a public imported game, under the same registered-account rule and limit as the archive GIF. Accepts format=mp4 for an MP4 video.

GET /api/v1/public/chess-today/

Today's chess-history anniversaries, using the site's timezone. Returns all reviewed entries for the date, with the featured game or milestone first, followed by other events and study-player birthdays. No API key is required.

Each entry includes its historical year, text, additional details, sources, and public game, event, player, book or gallery links. A matching photograph includes its image URL, gallery URL, attribution and license. Unavailable related material has a null URL. Drafts and editorial review notes are never returned.

curl -fsS "https://classicchess.com/api/v1/public/chess-today/"

Read the response

FieldHow to use it
date, timezoneThe current date and IANA timezone used for daily selection. The current date appears only on the today endpoint.
month, day, urlThe anniversary date and its stable API URL. Save this URL to retrieve the same date later.
featured_entry_idMatch this to an entry's id to select the same fact used by the daily notification.
entriesThe complete list for that day; no pagination. Each entry has a stable id, category and historical year.
text, detailsThe concise fact and an array of supporting paragraphs. These are plain text; render them as text, not HTML.
sourcesCitations with id, title, publisher and URL. Keep these with the fact when displaying it.
target_url, relatedOpen target_url for the main game, event or other archive item. Related items have kind, identifier, label and URL; skip null URLs. Resolve relative URLs against the API origin.
photographNull when no matching photograph is available. Otherwise includes image_url, gallery_url, alt_text, artist, credit, source_name, source_url, license, license_url, width and height. Preserve the attribution and follow the stated license.
playerThe archive player the entry pictures, as the homepage card does: the first linked player with a portrait, a related game's player before a related player. Includes name, slug, a portrait with absolute image and thumbnail URLs, and api_detail and html_about links. The field is absent when no linked player has a portrait.

Read today's entries with Python

This uses Python's standard library. Change the request path to a month/day endpoint to retrieve another date.

import json
from urllib.parse import urljoin
from urllib.request import urlopen

base = "https://classicchess.com/"
path = "/api/v1/public/chess-today/"
with urlopen(urljoin(base, path), timeout=10) as response:
    data = json.load(response)

for entry in data["entries"]:
    print(entry["year"], entry["text"])
    for paragraph in entry["details"]:
        print(paragraph)
    print("Open:", urljoin(base, entry["target_url"]))
    for source in entry["sources"]:
        print("Source:", source["title"], source["url"])
    photo = entry["photograph"]
    if photo:
        print("Photo:", urljoin(base, photo["gallery_url"]))
        print("Credit:", photo["artist"], photo["credit"], photo["license"])

API reads do not send notifications or change account preferences. On-site delivery is enabled separately in Settings → Notifications → Chess Today.

GET /api/v1/public/chess-today/{month}/{day}/

The same history data for a specific month and day. February 29 is available every year. This is an anniversary lookup: each entry supplies the historical year. Invalid dates return 404 with error.code set to invalid_date; an unavailable catalog returns 503 with catalog_unavailable. Correct invalid dates before retrying; retry an unavailable catalog later.

The response contains month, day, timezone, a dated API URL, featured_entry_id, and entries. The today endpoint also includes the current site date in YYYY-MM-DD form. Relative URLs resolve against the API's origin. Daily account notifications use this same catalog and open the related archive item directly.

curl -fsS "https://classicchess.com/api/v1/public/chess-today/2/29/"
GET /api/v1/public/events/{event_slug}/

One event from the catalog, with the same fields and links as a catalog row. Unknown slugs return 404.

Example

curl -fsS "https://classicchess.com/api/v1/public/events/wcc-1972-fischer-spassky/"
GET /api/v1/public/events/{event_slug}/about/

The event about page as data: event, dates, location, computed auto_vitals, the curated bio write-up (tagline, lede, sections, numbers, quotes, sources, and photographs with absolute URLs, captions and credits), and the computed crosstable. bio and crosstable are null when unavailable. Cross-table rows carry player_slug when the player has a public archive.

Example

curl -fsS "https://classicchess.com/api/v1/public/events/wcc-1972-fischer-spassky/about/"
GET /api/v1/public/gallery/

Browse or search the historical photograph gallery, 48 per page by default. Each photograph has players (with archive slugs when linked), date, event, scene, an absolute image URL with dimensions, its source, and attribution: artist, credit, license, license URL, usage terms and whether attribution is required. Honor the attribution fields when reusing an image.

ParameterRequiredDescription
qnoPlayers, events, places, scenes, dates or sources; at most 120 characters and 8 terms.
pagenoPage number; pages past the end return 404.
page_sizenoDefault 48, max 100.

Example

curl -fsS "https://classicchess.com/api/v1/public/gallery/?q=tal&page_size=12"
GET /api/v1/public/gallery/{photo_id}/

One photograph by the ID the gallery returns.

Example

curl -fsS "https://classicchess.com/api/v1/public/gallery/67217590/"
GET /api/v1/public/beginner-games/

The ordered beginner games guide: stages, each with numbered entries that pair a study focus with a spoiler-free game summary. Fetch game.urls.api_detail for moves. Returns 503 with catalog_unavailable if the guide cannot be published.

Example

curl -fsS "https://classicchess.com/api/v1/public/beginner-games/"
GET /api/v1/public/daily/

Today's Game of the Day: the server date and a spoiler-free game summary whose descriptor names players, result and event. It is the same frozen pick the /daily/ page opens. game is null when no game can be published. portrait has absolute image and thumbnail URLs for the game's archive player, the face the homepage card shows. It is absent when there is no game or that player has no portrait.

Example

curl -fsS "https://classicchess.com/api/v1/public/daily/"
GET /api/v1/public/event-of-the-day/

Today's Event of the day, as the homepage card shows it: the server date and an event with its name, one-line tagline and the winner it pictures, with portrait and links. Follow urls.api_about for the full write-up. event is null when no event can be published.

Example

curl -fsS "https://classicchess.com/api/v1/public/event-of-the-day/"
GET /api/v1/public/todays-picks/

Every face of today's homepage card in one read: the server date, the player of the day with title and life years, the Game of the Day as game, the on_this_day game with its winner, verb, opponent and year, and the event of the day. Each is null when the homepage has no such pick. A portrait with absolute image and thumbnail URLs appears where the homepage pictures that face.

Example

curl -fsS "https://classicchess.com/api/v1/public/todays-picks/"
GET /api/v1/public/search/

The site search box as an API. Without kind it returns the grouped preview: intent (player, matchup, event or games), counts, and the first players, events and games. With kind it returns one 50-row page of that kind. Rows include API detail links.

ParameterRequiredDescription
qyesA player, two players, an event, or game terms, optionally with a year; at most 120 characters and 8 terms.
kindnogames, events, or players.
pagenoRequires kind.

Example

curl -fsS "https://classicchess.com/api/v1/public/search/?q=fischer+spassky"
curl -fsS "https://classicchess.com/api/v1/public/search/?q=fischer+spassky&kind=games&page=2"