Snooker Data API documentation
Every frame and every final since 1927, one call awayThe Snooker API holds 64,396 matches in 1,192 events from 1927 to this week, with frame-by-frame scores for 1,082 matches, every century and maximum we can verify, and the world rankings over 49 seasons. Results reach us within minutes of being published, and every record carries our own stable id.
It is built for apps and sites that show results and draws, for researchers and journalists who need the history, and for assistants and agents that answer snooker questions. Everything is JSON over HTTPS, with one key in a header.
Start here
Three steps from nothing to your first answer. The free key needs no card.
Get a free key
Sign up with your email and the key is shown once in your account. It is filled into these pages for you.
Get a free keyMake the first call
Send the key in the Authorization header and ask for yesterday's results. Run it on its page or copy the curl.
Read the answer
Every answer is data plus meta. Lists page with a cursor, ids link records together, and errors say what to fix.
Every subject
One guide per subject of the data, each with its calls and the jobs people do with it.
Events and draws
Tournaments, their draws, champions and prize money.
/eventsEvents: every tournament and championship, newest first./events/{event_id}One event: its dates, venue, champion, final, prize fund and its own figures (frames played, deciding frames, whitewashes, centuries)./matchesMatches: results and draws, newest first, by event, player, season or dates.
Results and frames
Match results, rounds and frame-by-frame scores.
/matchesMatches: results and draws, newest first, by event, player, season or dates./matches/{match_id}One match, with its status, its frames where they are known (points and breaks of 50 and over), and every change to it since it entered our record./results/yesterdayEvery match finished yesterday (UTC): those our live tracker saw finish yesterday, and those whose own day is yesterday.
Player records
Finding players and reading their records.
/playersPlayers: everyone who has played in an event we hold, from 1927 on./players/{player_id}One player: nationality, birth date and place, the year they turned professional, their ranking, minor-ranking and world titles, the first season they were ranked, their highest world ranking, matches played and won, titles, and the seasons they span.
World rankings
The ranking lists of each season.
/rankingsWorld rankings: a season's list, position by position, with ranking points where they are known.
Breaks
Century breaks and maximums.
/centuriesCentury breaks: every break of 100 or more in the events we hold, by event, player or season./maximumsMaximum breaks: every officially recognised 147, newest first, with the player, the opponent and the event.
Plans and limits
What each plan reads, its limits and the headers that report them.
/usageYour key: its plan, calls today, limits, when they reset, and the data window the plan covers.
Every endpoint
28 calls. Every call works on the free key from yesterday on; the archive back to 1927 is on the paid plans.
| Endpoint | What it returns | Plan | MCP tool | Calls, 14 days | |
|---|---|---|---|---|---|
| Events | |||||
| GET /v1/events | Events: every tournament and championship, newest first. | Free key | find_events | 1 | Open |
| GET /v1/events/{event_id} | One event: its dates, venue, champion, final, prize fund and its own figures (frames played, deciding frames, whitewashes, centuries). | Free key | get_event | 0 | Open |
| GET /v1/events/{event_id}/points | The world ranking points each player earned at a ranking event, as the season's rankings publish them, and whether our own results for the event give the same points. | Free key | event_ranking_points | 0 | Open |
| Matches | |||||
| GET /v1/matches | Matches: results and draws, newest first, by event, player, season or dates. | Free key | find_matches | 0 | Open |
| GET /v1/matches/{match_id} | One match, with its status, its frames where they are known (points and breaks of 50 and over), and every change to it since it entered our record. | Free key | get_match | 0 | Open |
| GET /v1/results/yesterday | Every match finished yesterday (UTC): those our live tracker saw finish yesterday, and those whose own day is yesterday. | Free key | yesterdays_results | 0 | Open |
| Players | |||||
| GET /v1/players | Players: everyone who has played in an event we hold, from 1927 on. | Free key | find_players | 8 | Open |
| GET /v1/players/{player_id} | One player: nationality, birth date and place, the year they turned professional, their ranking, minor-ranking and world titles, the first season they were ranked, their highest world ranking, matches played and won, titles, and the seasons they span. | Free key | get_player | 0 | Open |
| GET /v1/head-to-head | Two players' meetings: how many, who won, frames won by each, their finals, and every match between them, newest first. | Free key | head_to_head | 0 | Open |
| Rankings and breaks | |||||
| GET /v1/rankings | World rankings: a season's list, position by position, with ranking points where they are known. | Free key | world_rankings | 0 | Open |
| GET /v1/centuries | Century breaks: every break of 100 or more in the events we hold, by event, player or season. | Free key | century_breaks | 0 | Open |
| GET /v1/maximums | Maximum breaks: every officially recognised 147, newest first, with the player, the opponent and the event. | Free key | maximum_breaks | 0 | Open |
| Bulk export | |||||
| GET /v1/export/{part} | Bulk export: one part of the whole record as a gzip file of JSON lines, one record a line, in the same shape as the API, rebuilt daily. | Free key | none | 0 | Open |
| Your key | |||||
| GET /v1/usage | Your key: its plan, calls today, limits, when they reset, and the data window the plan covers. | Free key | none | 0 | Open |
| Live | |||||
| GET /v1/matches/{match_id}/live | One match as it stands: whether it is under way, the frames won, every frame known, and its latest change. | Free key | live_match | 0 | Open |
| GET /v1/live/events | The live feed: every score change, frame won, result and century in the events being played, oldest first after since. | Free key | none | 0 | Open |
| GET /v1/stream/token | A token for the stream, for a browser: EventSource cannot send a header, so it opens /v1/stream?token=... instead of sending the key. | Free key | none | 0 | Open |
| GET /v1/stream | The live feed as Server-Sent Events, sent as it happens: one connection holds for five minutes, then reconnects by itself from the last event. | Free key | none | 2 | Open |
| Yesterday's statistics | |||||
| GET /v1/stats/yesterday | Yesterday (UTC) in one answer: matches, walkovers, frames, deciding frames, whitewashes, average match length, centuries and the highest break, in all and by stage. | Free key | yesterdays_stats | 1 | Open |
| GET /v1/stats/yesterday/players | Every player who played yesterday: matches won and lost, frames won and lost, frame difference and frame win rate, centuries and their highest. Most wins first. | Free key | yesterdays_player_stats | 0 | Open |
| GET /v1/stats/yesterday/deciders | Yesterday's matches settled in the deciding frame (won by one frame at full length), as the matches list gives them. | Free key | yesterdays_deciders | 0 | Open |
| GET /v1/stats/yesterday/whitewashes | Yesterday's matches won without losing a frame, as the matches list gives them. | Free key | yesterdays_whitewashes | 0 | Open |
| GET /v1/stats/yesterday/upsets | Yesterday's wins over a higher-ranked player, on the newest world ranking list, biggest ranking gap first. An unranked winner counts as one place below the list. | Free key | yesterdays_upsets | 0 | Open |
| GET /v1/stats/yesterday/top16 | How the world's top 16 on the newest ranking list fared yesterday: each one who played, their matches, wins, losses and frames, and every result. | Free key | yesterdays_top16 | 0 | Open |
| GET /v1/stats/yesterday/nations | Yesterday by nation, as the draws flag each player (ENG, CHN, WAL ...): players in action, matches won and lost, frames won and lost, centuries. Most wins first. | Free key | yesterdays_nations | 0 | Open |
| GET /v1/stats/yesterday/events | Yesterday by event, and within each event by round: matches, frames, deciding frames, whitewashes and average match length; centuries and the highest by event. | Free key | yesterdays_events | 0 | Open |
| GET /v1/stats/yesterday/scorelines | How often each scoreline came up yesterday, by match length: 4-0, 4-1, 4-2, 4-3 in best of 7, and so on, with each one's share. | Free key | yesterdays_scorelines | 0 | Open |
| GET /v1/stats/yesterday/centuries | Every century break we had yesterday, highest first, with the player, the event and the stage. | Free key | yesterdays_centuries | 0 | Open |
Popular calls
The calls asked for most, each as one line you can paste.
Players: everyone who has played in an event we hold, from 1927 on.
curl -H "Authorization: Bearer $KEY" "https://api.snookerapi.net/v1/players?q=Sullivan&per_page=2"GET /v1/players
The live feed as Server-Sent Events, sent as it happens: one connection holds for five minutes, then reconnects by itself from the last event.
curl -H "Authorization: Bearer $KEY" "https://api.snookerapi.net/v1/stream?types=frame.won,match.finished"GET /v1/stream
Events: every tournament and championship, newest first.
curl -H "Authorization: Bearer $KEY" "https://api.snookerapi.net/v1/events?q=World+Snooker+Championship&per_page=2"GET /v1/events
Yesterday (UTC) in one answer: matches, walkovers, frames, deciding frames, whitewashes, average match length, centuries and the highest break, in all and by stage.
curl -H "Authorization: Bearer $KEY" "https://api.snookerapi.net/v1/stats/yesterday"GET /v1/stats/yesterday
One event: its dates, venue, champion, final, prize fund and its own figures (frames played, deciding frames, whitewashes, centuries).
curl -H "Authorization: Bearer $KEY" "https://api.snookerapi.net/v1/events/ev_80r2d1px"GET /v1/events/{event_id}
The world ranking points each player earned at a ranking event, as the season's rankings publish them, and whether our own results for the event give the same points.
curl -H "Authorization: Bearer $KEY" "https://api.snookerapi.net/v1/events/ev_gceh5m87/points?per_page=5"GET /v1/events/{event_id}/points
For assistants and agents
The same API, shaped for AI. Each is generated from the registry, so it always matches these pages.
MCP server
Add the Snooker API to Claude, ChatGPT, Cursor or Claude Code as tools. The assistant calls the API with your key.
Agent skill
One file that teaches an agent the calls, limits and errors. Save it as ~/.claude/skills/snookerapi/SKILL.md or upload it in Claude's settings.
The manual
The whole API in one Markdown file, for an agent or a model that reads documentation in one go.
llms.txt
The index language models look for: what the site is, and where the manual, the skill and the pages are.
Plans in short
Read from the site's own settings. The full comparison is on Pricing.
Free key
30 a minute. Yesterday, today and what is scheduled ahead, on every endpoint. Real data, never samples.
Paid plans
Every event, match, frame, ranking list and break back to the first World Championship, with higher limits.
What is new
- Seeds: GET /v1/events/{event_id} lists the seeded players, as the event's main draw writes them.
- GET /v1/events/{event_id}/points: the world ranking points each player earned at a ranking event, with whether our results give the same.
- Fixtures: the matches of an event not yet finished are held as soon as its draw pairs the players, with status scheduled; GET /v1/matches?status=scheduled lists what is coming.
The rest
Questions people ask
How far back does the data go?
To the first World Championship in 1927. Frame scores exist where they were recorded, mostly finals; the World Championship final has them every year from 1982. See Coverage.
How fast do results arrive?
Checked every five minutes while an event or its qualifying is being played. The usual delay from publication to our copy is under a minute.
Why does a match have a window instead of a date?
Where the day is not recorded we give the round's, stage's or event's days, and date_known_to says which. See Dates.
Can I use the free key in production?
Yes, within its limits. It reads real data from yesterday on; the archive needs a paid plan.