{
  "openapi": "3.0.1",
  "info": {
    "title": "Lichess Games Export: Moves, Openings, Ratings, Tournaments",
    "description": "Export a chess player's games from Lichess as rows: result, ratings, time control, opening, move list, clocks and accuracy, filtered by speed, rated flag, colour, opponent and date. Also player profiles with every variant rating, rating history for charts, arena standings and top-player boards.",
    "version": "0.1",
    "x-build-id": "b2RnOy3hExSh0ctUy"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/yadroo~lichess-games/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-yadroo-lichess-games",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/yadroo~lichess-games/runs": {
      "post": {
        "operationId": "runs-sync-yadroo-lichess-games",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/yadroo~lichess-games/run-sync": {
      "post": {
        "operationId": "run-sync-yadroo-lichess-games",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "mode": {
            "title": "What to fetch",
            "enum": [
              "games",
              "player",
              "ratingHistory",
              "tournament",
              "leaderboard"
            ],
            "type": "string",
            "description": "Five questions, five row shapes, one per run. `games` is the export the other four support: every finished game of the accounts you name, newest first, with the filters below applied by the source. `player` answers \"how strong is this account and how much has it played\". `ratingHistory` returns the daily rating points behind those numbers, one row each, so a chart needs no post-processing. `tournament` turns a tournament id into its final standing. `leaderboard` is the current top list of one speed or variant. Open the dataset view that carries the mode's name; the other views stay empty.",
            "default": "games"
          },
          "usernames": {
            "title": "Lichess usernames",
            "type": "array",
            "description": "Accounts to read, as they appear after the @ in a profile URL (`lichess.org/@/DrNykterstein` -> `DrNykterstein`). Case does not matter - the source matches accounts by their lower-case id. Used by the `games`, `player` and `ratingHistory` modes; ignored by `tournament` and `leaderboard`. Accounts are processed in the order given, one request at a time. An account that does not exist, is closed or was renamed yields a single row with `found: false` and the reason in `notFoundReason`, so a typo in a long list never disappears silently.",
            "items": {
              "type": "string"
            }
          },
          "perfTypes": {
            "title": "Speeds and variants",
            "type": "array",
            "description": "Keep only these speeds or variants. Empty = everything the account has played. Several values = OR, and the filter is sent to the source, so games outside it are never fetched or charged. `puzzle` is not a game type: it exists only as a rating curve, so it is accepted in `ratingHistory` mode and ignored in `games` mode.",
            "items": {
              "type": "string",
              "enum": [
                "ultraBullet",
                "bullet",
                "blitz",
                "rapid",
                "classical",
                "correspondence",
                "chess960",
                "crazyhouse",
                "antichess",
                "atomic",
                "horde",
                "kingOfTheHill",
                "racingKings",
                "threeCheck",
                "puzzle"
              ],
              "enumTitles": [
                "UltraBullet - 30 seconds or less",
                "Bullet - under 3 minutes",
                "Blitz - 3 to 8 minutes",
                "Rapid - 8 to 25 minutes",
                "Classical - over 25 minutes",
                "Correspondence - days per move",
                "Chess960",
                "Crazyhouse",
                "Antichess",
                "Atomic",
                "Horde",
                "King of the Hill",
                "Racing Kings",
                "Three-check",
                "Puzzles (rating history only)"
              ]
            }
          },
          "rated": {
            "title": "Rated or casual",
            "enum": [
              "any",
              "rated",
              "casual"
            ],
            "type": "string",
            "description": "Rated games move the account's rating and are what rating analysis needs; casual games include warm-ups, odds games and games against friends. Titled players often have thousands of casual games, so this is usually the first filter to set.",
            "default": "any"
          },
          "color": {
            "title": "Colour played",
            "enum": [
              "any",
              "white",
              "black"
            ],
            "type": "string",
            "description": "Restrict the export to the games in which the named account played that colour. Useful for opening work, where the repertoire question is asked per colour.",
            "default": "any"
          },
          "opponent": {
            "title": "Only against this opponent",
            "type": "string",
            "description": "A second username: keep only the games the named accounts played against this one account, in either colour. That is the head-to-head record two players ask for before a match. Leave empty for all opponents. If the two accounts never met, the run returns no rows and says so in the status message rather than widening the search."
          },
          "sinceHours": {
            "title": "Games started in the last N hours",
            "minimum": 1,
            "maximum": 87600,
            "type": "number",
            "description": "Rolling window in hours, counted in UTC from the moment the run starts: 24 for the last day, 168 for a week, 720 for a month. The source compares it with the moment a game started, so a game begun just before the window and finished inside it is not included. This is the input to use on a schedule - it needs no date editing between runs. It takes precedence over `dateFrom`; empty = no lower bound."
          },
          "dateFrom": {
            "title": "Games started on or after (YYYY-MM-DD)",
            "type": "string",
            "description": "Fixed lower bound of the date window, as a calendar date (`2026-01-01`) or a full UTC timestamp (`2026-01-01T00:00:00Z`). Ignored when `sinceHours` is set. The source compares it with the moment a game started."
          },
          "dateTo": {
            "title": "Games started before (YYYY-MM-DD)",
            "type": "string",
            "description": "Fixed upper bound of the date window, exclusive, compared with the moment a game started. Combine it with `dateFrom` to pull one season, one month or one tournament week out of a long career."
          },
          "analysedOnly": {
            "title": "Only games with a server analysis",
            "type": "boolean",
            "description": "Keep only games for which a full computer analysis exists, which are the games that carry accuracy, average centipawn loss and the blunder counts. Most bullet games have none, so switching this on can shrink a run to a handful of rows - raise the row limit or widen the date window when you use it.",
            "default": false
          },
          "onlyNew": {
            "title": "Skip games seen in earlier runs",
            "type": "boolean",
            "description": "Remember the game ids of this run in a named key-value store of your account and, on the next run of the same actor or task, write only games that were not written before. Only games really written (and charged) are remembered, so a run stopped by your spending limit or the timeout loses nothing. Made for schedules: with newest games first every run holds just the games played since the last run, and an empty run means the player has not played; with `sortDescending` off, each run continues the career forwards from the newest game the previous runs wrote. The memory is per task (runs started by hand share one), so two tasks watching two players do not interfere.",
            "default": false
          },
          "sortDescending": {
            "title": "Newest games first",
            "type": "boolean",
            "description": "On by default, which is what a row limit should be combined with: 50 rows then means the 50 most recent games. Switch it off to walk a career forwards from its first game, together with `dateFrom` - and with `onlyNew`, so that each run picks up where the previous one stopped.",
            "default": true
          },
          "includeMoves": {
            "title": "Include the move list",
            "type": "boolean",
            "description": "Add the moves of the game in standard algebraic notation as one space-separated string (`e4 e5 Nf3 Nc6 ...`), plus the move count. This is what an engine, a parser or a language model reads. Switch it off for a table of results only, which makes rows much smaller.",
            "default": true
          },
          "includeOpening": {
            "title": "Include the opening name and ECO code",
            "type": "boolean",
            "description": "Add the opening as the source classifies it: the ECO code (`B90`), the full name with variation (`Sicilian Defense: Najdorf Variation`) and the number of plies the classification covers. Short games and non-standard variants are left unclassified.",
            "default": true
          },
          "includeClocks": {
            "title": "Include the clock after every move",
            "type": "boolean",
            "description": "Add the remaining time of both players after each move, in centiseconds, as an array in move order. That is the raw material for time-trouble and time-management analysis; it makes a bullet game row several kilobytes long.",
            "default": false
          },
          "includeEvals": {
            "title": "Include engine evaluations per move",
            "type": "boolean",
            "description": "Add the per-move evaluation of the server analysis, when one exists: the score in centipawns or the mate distance, plus the move the engine preferred. Present only for analysed games; combine with `analysedOnly` so you do not pay for rows that come back empty.",
            "default": false
          },
          "includeAccuracy": {
            "title": "Include accuracy and blunder counts",
            "type": "boolean",
            "description": "Add each side's accuracy percentage, average centipawn loss and the counts of inaccuracies, mistakes and blunders from the server analysis. Empty for games that were never analysed, which the `analysed` column marks.",
            "default": true
          },
          "sinceDays": {
            "title": "Rating points of the last N days",
            "minimum": 1,
            "maximum": 7300,
            "type": "number",
            "description": "In `ratingHistory` mode, keep only points from the last N days: 365 for a year of form, 30 for a month. Empty = the whole history, which for an account opened in 2010 can be a few thousand points across all variants. The source records one point per day on which the rating changed, so gaps in the output are days without games, not missing data."
          },
          "tournamentIds": {
            "title": "Tournament ids",
            "type": "array",
            "description": "The ids from tournament URLs: `lichess.org/tournament/ayELljKv` -> `ayELljKv` for an arena, `lichess.org/swiss/<id>` -> that id for a swiss. Finished tournaments stay readable, so an id keeps working long after the event. Several ids in one run produce one dataset with a `tournamentId` column. An unknown id yields one row with `found: false`.",
            "items": {
              "type": "string"
            }
          },
          "tournamentKind": {
            "title": "Tournament format",
            "enum": [
              "arena",
              "swiss"
            ],
            "type": "string",
            "description": "The two formats live under different URLs and different endpoints, and an arena id is not a swiss id. Arena rows carry the running score and the streak sheet; swiss rows carry points and the tie-break number instead.",
            "default": "arena"
          },
          "leaderboardPerf": {
            "title": "Leaderboard speed or variant",
            "enum": [
              "ultraBullet",
              "bullet",
              "blitz",
              "rapid",
              "classical",
              "chess960",
              "crazyhouse",
              "antichess",
              "atomic",
              "horde",
              "kingOfTheHill",
              "racingKings",
              "threeCheck"
            ],
            "type": "string",
            "description": "Which top list `leaderboard` mode reads. Correspondence and puzzles have no public top list, which is why they are missing here. Each row carries the rating, the recent progress and whether the account is online, so the list doubles as a source of active strong accounts to feed back into `games` mode.",
            "default": "blitz"
          },
          "topCount": {
            "title": "How many top accounts",
            "minimum": 1,
            "maximum": 200,
            "type": "number",
            "description": "Length of the top list, up to the 200 the source publishes. The row limit below still applies, so the smaller of the two wins.",
            "default": 20
          },
          "maxItems": {
            "title": "Maximum rows",
            "minimum": 1,
            "maximum": 2000,
            "type": "number",
            "description": "Hard cap on the rows this run writes, and therefore on what it costs. Reading stops as soon as the cap is reached - the games stream is closed early instead of being downloaded and thrown away. In `games` mode the cap is divided over the accounts you named. The run also stops at your maximum cost per run, and shortly before the run timeout, saving what it has read and saying so in the status message.",
            "default": 50
          },
          "fields": {
            "title": "Only these columns",
            "type": "array",
            "description": "Keep only the named columns, in the order you list them - for example `gameId, opponent, result, openingName, createdAt`. The mode's key columns are always kept, so a row still says what it is about: `gameId` and `player` in games mode, `username` and `found` in player mode, `username` and `perfType` in rating-history mode, `tournamentId` and `found` in tournament mode, `perfType` and `rank` in leaderboard mode; a row with `found: false` also keeps `found` and `notFoundReason`. Empty = every column of the mode. Letter case does not matter, and the words of a name may be joined or separated by spaces, `_` or `-` (`GameID`, `game_id` and `Game ID` all mean `gameId`; `opening_name` means `openingName`); a name that is not a column is reported in the status message with the closest column, and a list in which no name is a column stops the run before any request.",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}