Chess Opponent Analyzer
Pricing
from $4.25 / 1,000 openings
Chess Opponent Analyzer
Analyzes a chess player's game history and opening repertoire from Lichess, Chess.com, or official tournaments. Extracts ECO statistics, opening trees, performance metrics, recent trends, and surprise detections. Export to PGN or JSON.
Pricing
from $4.25 / 1,000 openings
Rating
0.0
(0)
Developer
Trove Vault
Actor stats
1
Bookmarked
4
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Fetch a chess player's full game history from Lichess and Chess.com, analyze their opening repertoire, and get an actionable preparation report before your next game.
What Does the Chess Opponent Analyzer Do?
The Chess Opponent Analyzer fetches a player's game history from Lichess and Chess.com and produces a detailed opening repertoire report. You get win rates per opening, a full move-tree, and signals for recent preparation changes -- everything a coach or player needs the night before a tournament game.
Core capabilities:
- 📥 Fetches up to 1,500 games from Lichess (NDJSON API) and Chess.com (monthly archives API)
- ♟️ Builds a per-color opening tree (up to 30 plies deep) with win/draw/loss stats at every node
- 📊 Ranks top openings by ECO code with frequency and win rate
- 📈 Detects recent trends: openings the opponent started playing more or less in the last 30 days
- 🚨 Flags surprise openings: lines played recently but historically rare (< 3% of games)
- 🔁 Surfaces rare repeated lines (< 5% frequency, 3+ games) -- signature sidelines worth preparing
- ⏱️ Splits performance by time control: classical, rapid, blitz, bullet
- 🔗 Combines both platforms in a single merged analysis when platform is set to "all"
What Data Does the Chess Opponent Analyzer Return?
| Opening analysis | Performance data | Metadata |
|---|---|---|
| ♟️ ECO code and opening name | 📊 Win / draw / loss counts | 🗓️ Date range analyzed |
| 🌳 Full opening tree (configurable depth) | 📈 Win rate, draw rate, loss rate | 🕐 Time of analysis |
| 🎯 First-move frequency (White) | 🕐 Performance by time control | 🎮 Source platform (Lichess / Chess.com) |
| 🔄 Black responses vs 1.e4 / 1.d4 / 1.c4 / 1.Nf3 | 📉 Recent 30-day trends | 🆔 Game IDs and URLs |
| 🚨 Surprise openings (new preparation signals) | 🔁 Rare repeated sidelines | 🌐 Game count per platform |
Can I Use the Chess Opponent Analyzer to Study Magnus Carlsen, Hikaru Nakamura, or Any Other Player?
Yes. The Chess Opponent Analyzer works for any public Lichess or Chess.com profile. For Lichess, enter the username (for example, DrNykterstein for Magnus Carlsen or nihalsarin for Nihal Sarin). For Chess.com, enter the Chess.com username (for example, MagnusCarlsen or Hikaru). Set platform: "all" to merge both platforms into a single analysis.
How Does the Chess Opponent Analyzer Work?
The Process
- You provide a Lichess username, a Chess.com username, or both, plus optional filters (date range, time control, rated/casual, color, minimum opponent rating)
- The actor fetches games from the selected platform(s): Lichess via NDJSON streaming, Chess.com via monthly archive API
- Each game is normalized to a common format: result, ECO code, opening name, player color, opponent rating, and move list
- Games from both platforms are merged into a single pool (when using
platform: "all") - The move list is parsed into SAN tokens (clock annotations and move numbers stripped)
- An opening tree is built by traversing moves up to your chosen depth and counting wins/draws/losses at every node
- Statistical layers are added: ECO rankings, first-move frequencies, Black response maps, trend analysis, surprise detection, and rare-line surfacing
- The full analysis is pushed as a single JSON record to the Apify dataset
Think of it as running your own personal opening preparation team, except it processes 500 games in under 60 seconds.
Why Use the Chess Opponent Analyzer?
| Feature | Manual research | Chess Opponent Analyzer |
|---|---|---|
| Time to analyze 500 games | Several hours | Under 60 seconds |
| Opening tree depth | Limited by patience | Up to 30 plies (configurable) |
| Surprise detection | Hard to spot manually | Automatic: flags openings with < 3% historical rate |
| Trend analysis | Requires date-based sorting | Built-in 30-day vs 60-day comparison |
| Cross-platform coverage | Separate sessions per site | Lichess + Chess.com merged in one run |
| Multi-time-control split | Separate sessions | Automatic breakdown per time control |
| Structured output for pipelines | Not possible | Full JSON via Apify dataset API |
What Can You Do With Opening Analysis Data?
Tournament preparation
Import the opening tree JSON into your preparation workflow. The tree structure maps directly to standard repertoire formats -- you can see exactly what your opponent plays after 1.e4 e5 2.Nf3 Nc6 and how their win rate changes move by move. Filter to classical or rapid only when preparing for a classical event. Use platform: "all" to get the widest picture across both Lichess and Chess.com.
Coaching and training
Coaches can run the actor for every upcoming opponent of a student and store all results in a shared Apify dataset. Use the datasetId parameter to append all players into a single dataset for easy comparison. The structured JSON output integrates with any custom dashboard.
Opening research
The recentTrends and surprises arrays answer the key preparation question: "Has this player changed their opening approach lately?" An increasing trend in a line you haven't prepared is a concrete signal. A surprise opening with 3 recent games but near-zero historical rate means they may have specifically prepared it.
Scheduling
Run weekly in the month before a major tournament to catch preparation changes early. Run daily for rapid or blitz events where opponents may have evolved their openings recently. Use the Apify scheduler or connect via the API to trigger runs automatically.
How to Use the Chess Opponent Analyzer
- Go to the Chess Opponent Analyzer page on the Apify Store and click Try for free
- In the Input tab, select your platform (Lichess, Chess.com, or All) and enter the corresponding username(s)
- Set your filters: date range, time controls, rated/casual, minimum opponent rating
- Optionally increase Max Games (up to 1,500) for deeper statistical analysis
- Click Start and wait for the run to complete (usually 10--60 seconds)
- Open the Output tab to see the full analysis record
- Download as JSON, CSV, or use the Apify API to pull results into your own tools
Recommendation: start with timeControls: ["rapid"] and maxGames: 200. Rapid games reflect a player's real preparation better than blitz and contain more opening theory than bullet.
How Much Does the Chess Opponent Analyzer Cost?
The Chess Opponent Analyzer uses the pay-per-event model. A typical run analyzing 500 rapid games costs less than $0.05 in compute units. The main cost driver is the number of games fetched -- more games means more parsing and analysis.
Cost optimization tips:
- Use
maxGames: 200-500for most preparation needs -- diminishing returns above 500 for active players - Set
dateFromto limit to the last 12--18 months -- older games may not reflect current preparation - Set
minOpponentRating(e.g. 2300+) to filter out low-quality games and focus the analysis - Add a
lichessApiTokento reduce Lichess rate-limit delays -- reduces runtime, not cost
Input
The Chess Opponent Analyzer accepts the following input parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
lichessUsername | string | -- | Lichess username to analyze (e.g. DrNykterstein) |
chesscomUsername | string | -- | Chess.com username to analyze (e.g. MagnusCarlsen) |
platform | string | lichess | Source platform: lichess, chesscom, or all |
dateFrom | string | -- | Start date in ISO format: 2024-01-01 |
dateTo | string | -- | End date in ISO format: 2024-12-31 |
timeControls | array | ["all"] | One or more of: classical, rapid, blitz, bullet, all |
rated | string | rated | rated, casual, or all |
color | string | both | white, black, or both |
minOpponentRating | integer | 0 | Only include games vs opponents at or above this rating |
maxGames | integer | 500 | Maximum games to fetch (up to 1,500) |
openingTreeDepth | integer | 12 | Plies to include in opening tree (4--30) |
lichessApiToken | string | -- | Optional Lichess token to increase rate limits |
datasetId | string | -- | Append results to an existing Apify dataset |
runId | string | -- | Associate results with a pipeline run |
Example input -- Lichess tournament preparation:
{"lichessUsername": "nihalsarin","platform": "lichess","timeControls": ["rapid", "classical"],"dateFrom": "2024-01-01","rated": "rated","minOpponentRating": 2500,"maxGames": 500}
Example input -- Chess.com blitz analysis:
{"chesscomUsername": "Hikaru","platform": "chesscom","timeControls": ["blitz"],"maxGames": 500}
Example input -- cross-platform merged analysis:
{"lichessUsername": "DrNykterstein","chesscomUsername": "MagnusCarlsen","platform": "all","timeControls": ["rapid"],"maxGames": 500}
Output
The Chess Opponent Analyzer produces a single JSON record per run pushed to the Apify dataset.
Example output structure:
{"player": "nihalsarin","gamesAnalyzed": 312,"dateRange": { "from": "2024-01-15", "to": "2024-12-20" },"sources": { "lichess": 312 },"summary": {"games": 312,"wins": 180,"draws": 100,"losses": 32,"winRate": 0.577,"drawRate": 0.321,"lossRate": 0.103},"white": {"games": 156,"summary": { "wins": 95, "draws": 50, "losses": 11, "winRate": 0.609 },"firstMoves": {"e4": { "games": 96, "wins": 62, "draws": 28, "losses": 6, "frequency": 0.615, "winRate": 0.646 }},"topEcos": [{ "eco": "C65", "name": "Ruy Lopez Berlin Defense", "games": 42, "winRate": 0.69, "frequency": 0.269 }],"openingTree": {"e4": {"games": 96,"wins": 62,"draws": 28,"losses": 6,"winRate": 0.646,"continuations": {"e5": { "games": 48, "winRate": 0.625, "continuations": {} },"c5": { "games": 32, "winRate": 0.688, "continuations": {} }}}}},"black": {"games": 156,"firstMoves": {"vs1e4": { "e5": { "games": 42, "frequency": 0.41, "winRate": 0.571 } },"vs1d4": { "Nf6": { "games": 38, "frequency": 0.37, "winRate": 0.605 } },"vs1c4": {},"vs1Nf3": {}}},"performanceByTimeControl": {"rapid": { "games": 200, "winRate": 0.60 },"blitz": { "games": 112, "winRate": 0.527 }},"recentTrends": [{"eco": "B12","name": "Caro Kann Defense","trend": "increasing","last30Games": 8,"prev60Games": 3,"recentRate": 0.267,"prevRate": 0.05}],"surprises": [{"eco": "A00","name": "Larsen Opening","firstSeenRecently": "2024-11-01","recentGames": 3,"historicalGames": 1,"historicalRate": 0.008}],"rareRepeated": [{ "eco": "C10", "name": "French Defense", "games": 4, "frequency": 0.026 }],"scrapedAt": "2024-12-21T14:30:00.000Z"}
Results can be downloaded as JSON or CSV from the Output tab, or fetched programmatically via the Apify API.
Are There Other Chess Tools on Apify Store?
- Chess Ratings Aggregator -- Aggregate FIDE, Chess.com, and Lichess ratings for the top 100+ players side-by-side with 12-month progression and peak ratings
- Apify Store -- Browse hundreds of other scrapers and data tools
Frequently Asked Questions
Can I analyze any Lichess player with the Chess Opponent Analyzer?
Yes. Any public Lichess profile is available without authentication. Simply enter the username. For players with a large game history, add a Lichess API token in the lichessApiToken field to avoid rate limiting when fetching large game sets.
Does the Chess Opponent Analyzer work for Chess.com players?
Yes. Set platform: "chesscom" and enter the player's Chess.com username in the chesscomUsername field. The actor fetches games from Chess.com's public monthly archives API. No API key is required. Examples: MagnusCarlsen, Hikaru, FabianoCaruana.
Can I merge Lichess and Chess.com games into a single analysis?
Yes. Set platform: "all" and provide both lichessUsername and chesscomUsername. The actor fetches from both platforms, normalizes all games to the same format, and produces a single merged analysis. This gives the most complete picture of a player's repertoire when they are active on both platforms.
How many games can I analyze per run?
Up to 1,500 games per run, set via maxGames. For most players 200--500 games is sufficient for statistically reliable opening frequencies. Use higher values for players with rare sidelines or when preparing for very specific lines.
What is the opening tree depth setting?
Opening tree depth is measured in plies (half-moves). 12 plies = 6 full moves, which covers most standard opening theory. Use 20--24 plies for deep line preparation (for example, studying a player's handling of a specific 10-move variation). Higher depth produces larger output but gives more precise preparation signals.
How do I schedule regular analysis runs before a tournament?
Use the Apify scheduler to run the actor automatically. A recommended schedule for tournament preparation is once per week starting 4 weeks before the event, then daily in the final week. The recentTrends and surprises arrays are the key fields to monitor -- they will change if the opponent is actively preparing new lines.
Can I use the Chess Opponent Analyzer with the Apify API?
Yes. Every Apify actor is accessible via REST API. Send a POST request to https://api.apify.com/v2/acts/trovevault~chess-opponent-analyzer/runs with your input JSON and API token. Use the datasetId parameter to accumulate results for multiple players into a single dataset for comparison.
Can I use the Chess Opponent Analyzer through an MCP Server?
Yes. Apify provides a Model Context Protocol (MCP) server at mcp.apify.com that exposes all store actors as tools. Connect any MCP-compatible client (Claude, Cursor, etc.) to run the Chess Opponent Analyzer directly from your AI assistant. This is useful for automated preparation workflows where you ask your AI to analyze several opponents in one session.
Is this data analysis legal?
Yes. The Chess Opponent Analyzer only processes publicly available game data. Lichess explicitly provides a free public API for this purpose -- all games are public by default and the terms of use permit automated access. Chess.com exposes public game archives at api.chess.com/pub without authentication for published games. No private data, account credentials, or paid content are accessed.
What if the actor returns no results?
The most common cause is filters that are too strict. If gamesAnalyzed: 0 is returned, try: removing the minOpponentRating filter, expanding the date range, including more time controls, or using rated: "all". The error record includes a fix field with specific recommendations.
Your Feedback
Found a bug or have a feature request? Open an issue on the actor's Issues tab. Phase 3 (official tournament games via TWIC) is on the roadmap -- upvote or comment to help prioritize.