About this project
This tool reads snooker scores aloud while you watch (or half-watch) a match. It was built primarily for blind and visually impaired viewers so they can follow live matches on television without needing to see the on-screen scoreboard, but it works just as well for sighted users who want to keep up with the score while doing something else, drifting in and out of the room, or following along on the radio.
It's designed with accessibility in mind: full keyboard navigation, semantic HTML, ARIA live regions for screen readers, and high-contrast colours throughout.
The idea came from a request on the Snooker Scene Podcast, presented by Dave Hendon, where a blind listener asked for commentators to call the score more often. This is a small, non-commercial answer to that — built using the open data feed from snooker.org, with the kind permission of its creator Hermund Ardalen.
Press Start at the top of the home page and the page will read out frame scores as they change, with a regular summary every couple of minutes. Use the settings on the home page to control how often scores are read and which matches to follow.
For World Championship semifinals and the final, the page announces additional detail when each frame ends — the frame number, the points scored by each player, and any breaks of 50 or higher with player attribution. For example: "Mark Selby took frame 16 with a maximum 147."
Got a hint, suggestion, or piece of advice that would make the tool better? Send a message — feedback from regular users (sighted or otherwise) is genuinely the best way to improve it.
Please note: the scoreboard updates at the end of each frame, not point-by-point during a frame. For the action while a frame is being played, the TV or radio commentary fills the gap. Point-by-point announcements during a frame are the long-term goal of this project. They are the original reason the tool was built. No public data feed currently provides them. If that ever changes, this page will be the first to use it.
Tournaments covered
This tool draws live data from snooker.org, which is currently the only public source of frame-by-frame scoring data for snooker. The snooker.org feed covers a wide range of events: anything that awards World Snooker Tour cards, either from single events or via tour rankings. In practice that includes:
- The Main Tour - ranking events (World Championship, UK Championship, World Open, Welsh Open and the rest), invitational events (Masters, Champion of Champions, Shanghai Masters), and qualifiers
- The World Seniors Tour - including the World Seniors Championship at the Crucible and the British Seniors Open
- The Women's Tour - all ranking events, including the Women's World Championship, UK Women's Championship, Australian Women's Open, British Women's Open and others
- Q Tour events worldwide (UK, Asia Pacific, Americas, Middle East) and Q School
- WSF Championships - the amateur world championships (WSF Open, WSF Junior, WSF Women's)
- The European Championship and European U-21 Championship
- Other events that award tour cards or feed into rankings: the World Games, the Pan American Championship, the Asia Pacific Open Championship
The full season calendar is at snooker.org/calendar, colour-coded by tour.
Tournaments organised outside the World Snooker Tour structure are not on the snooker.org feed, so they aren't covered here. The most visible example is Snooker 900.
Tips for using the tool
Keep this tab open in the background. Your browser must remain open for speech to work, and on mobile the screen may need to stay on.
Extra detail at the World Championship: for semifinals and the final only, the announcer reads out the frame number, the points scored, and any breaks of 50 or higher (with player attribution) when a frame ends. Other matches - including Seniors finals - get frame-by-frame match scores only, because that's the level of detail the data feed provides.
Found a bug or got a suggestion? Use the contact form.
Credits
Data: All match data is provided by snooker.org, maintained by Hermund Ardalen. This tool would not exist without his generosity in providing API access.
Hosting: The page and data proxy run on Cloudflare Workers, with a scheduled cron trigger refreshing the data each minute.
Speech: Browser-native Web Speech API — no third-party voice service involved. Announcements also go to an ARIA live region so they're read by screen readers if the synthesised voice is muted.
Version: v1.7.2
Service status
A scheduled job on the server fetches new data from snooker.org once a minute. The boxes below show the most recent successful refresh. In normal operation, data age stays under 90 seconds.
Recent changes
A short list of recent user-visible changes. Older history lives in the project's commit log.
-
- Fixed unticked matches still re-selecting themselves; the setting now reliably sticks across reloads, even when the source data changes a match's internal ID mid-tournament.
-
- Matches you've unticked now stay unticked when you return to the page, instead of all matches being re-selected.
-
- Reworked how scores are fetched behind the scenes to stay within snooker.org's updated limits, while keeping live scores refreshing every minute.
-
- Added support for the China Open and Wuhan Open qualifiers, and the Championship League, including their match formats and round-progression announcements (e.g. "has qualified for the China Open"). Any registered tournament now gets full coverage automatically when it's running.
-
- Brief tab-switches no longer cause score changes to be skipped; announcements are only paused after a genuinely long sleep (e.g. laptop lid closed).
-
- Round announcements now include the match format, e.g. "Round 2. Best of 7."
- The tournament name is now always announced before the round, even when only one tournament is in play.
- Fixed a duplicate-announcement bug where the same match would occasionally be read out twice, caused by the source data publishing two records for the same fixture.
- Fixed a missed-update bug where Q School score changes and finishes weren't being announced reliably.
-
- More efficient use of the snooker.org API: the worker now only polls events that are in their active window, and caches slow-changing data (event brackets, round metadata) between ticks rather than refetching every minute.
-
- Matches panel and picker now always show a tournament heading above each group, so a "Final" or "R1" is never unlabelled.
- Round badges on match cards now show the match format, e.g. "SF (9)" for a best-of-9 semifinal.
- The empty-picker message names the tournament of the next match.
- Future-scheduled matches with malformed result data on the source side no longer show as "finished" with a 0-0 score.
-
- More resilient to snooker.org's intermittent upstream errors. Match-started announcements no longer repeat when matches briefly disappear from the live feed.
- Matches panel and picker now group by tournament when multiple are running.
- Readouts no longer repeat the round before every match. Tournament and round are announced once per group.
-
- Women's World Championship knockout-phase support added.
- Q School support added (Asia & Oceania and UK, both editions).
-
- Player country flags now appear next to names in the matches list and picker.
- Fixed Read now not doing anything when the announcer wasn't started.
- Stop button now also stops a Read now readout mid-stream.
-
- Matches that briefly disappeared during an upstream outage no longer come back unticked.
- Match-finished announcements no longer fire twice when the live feed drops a match shortly after the result.
- The matches panel now shows every match regardless of picker selection. The picker only controls what gets read aloud.
- Added a heads-up notice on the home page about women's championship data being flaky this week.
- No more guessed match results when matches briefly vanish from the live feed.
-
- The "Follow these matches" picker now only shows matches currently in play (and matches between sessions). Tournaments with stacked sessions like the Women's WC group stage produced 30+ checkboxes under the previous "next 4 hours" rule. New matches are still auto-followed when they go live, so the picker is now purely a noise-filter for what's happening right now.
- Better pauses in multi-match readouts. Previously "Group A. Pui Ying Chu nil, Qingning Huang 2. Group B. Lu Zhao 1, Starry Chan nil." would run together with not enough breath between the round label and the score, nor between successive matches. Now the round/group label gets a beat before the score, and there's a longer pause between matches so the listener can register where one ends and the next begins.
- New "Start (no readout)" button for users who want score-change announcements without the initial "X matches in play" inventory. Useful when you already know what's running and just want updates from this point on. The stale-data warning is also suppressed in this mode.
- Dropped the "this is a preview - things may glitch while we settle in" line from the home, info and contact pages.
- Resilience against intermittent upstream errors. Previously, a single HTTP 500 from any of the five snooker.org API calls per minute would discard the whole minute's data and trigger the "trouble refreshing" warning to users. Now each call is handled independently - if four succeed and one fails, the snapshot is built from the four and the failure is logged silently. If a partial-success tick would produce an empty matches array, the previous snapshot's matches are reused so the page never goes blank mid-session.
- New "Tournaments covered" section on the Info page explaining the full range of events served by the snooker.org feed - Main Tour, Seniors, all women's ranking events, Q Tour worldwide, Q School, WSF Championships, the European and European U-21 Championships, the World Games and other amateur championships - plus a note on events like Snooker 900 that are outside the WST and so aren't covered.
-
- Added support for the Women's World Snooker Championship at Dongguan, China (12 to 19 May). The tournament starts with a group stage across sixteen groups (A to P), and the announcer now recognises group matches and labels them in announcements ("Group J: Ng On Yee versus Bai Yaru"). Hill-game-tied at 2 to 2 fires the decider phrase. Knockout-phase support will follow once those matches appear later in the week.
- The upcoming-matches readout no longer recites every player when a session has 5 or more matches starting at once. The headline ("eight matches coming up") and shared context ("Women's World Snooker Championship matches starting tomorrow at 2:30 am") still fire, but hearing eight unfamiliar names in a single sentence was overwhelming and not retainable. Use Read now once matches are live for the score detail.
- The Future section of the matches list (matches beyond the next 24 hours) is now capped at 12 entries with a "and X more later in the bracket" note. Multi-day events like the Women's World Championship were generating walls of 80+ named matches plus 30 to-be-decided placeholders - useful as a bracket reference but not what the page is for. The Coming up section (next 24 hours) is unchanged.
- Knockout-round placeholder matches with both players to-be-decided are now hidden from the list and the announcer entirely. These are scheduling slots before the bracket is drawn and have no useful information.
-
- Auto-off no longer fires its rapid-fire "1 minute warning / stopping now / stopped" sequence on wake when the deadline passed during sleep. Now stops silently in that case - the announcer was already silent through the sleep, so the spoken warning was confusing and out of date by hours.
- Moved the "extra detail for semifinals and finals" notice from the home page into Info > Tips, and reworded it to make clear it's a World Championship-only behaviour.
- Removed the "Crucible only" toggle. The snooker calendar runs one major event at a time, so the toggle did nothing useful in practice. Whatever event is on (World Championship, Seniors, Q School) is now shown automatically.
- Removed the "Announce when matches finish" and "Announce when matches start" toggles. They were redundant with the always-on score-change announcements - if you're hearing frame-by-frame updates, you should hear the bookend events too. Match starts and finishes now always announce. The per-match picker still lets you mute individual matches.
-
- Round labels (QF, SF, Final) now appear for the Seniors quarter-finals, semi-finals and final - the round numbers in the API turned out to differ from the assumed ones, so today's QFs at 7pm and 9pm were missing their labels until now.
- The "Follow these matches" picker now shows matches starting within the next 4 hours instead of 24, so the list stays focused on what's actually imminent. Matches further out are still in the data and will be auto-followed when their session gets within 4 hours.
- Scores now refresh on the page even when the announcer hasn't been started. Previously you had to press Start to see live updates - now the visual scores update every minute regardless, and the announcer just controls whether the updates are read aloud.
- Fewer false "trouble refreshing" announcements after waking the laptop or phone. The announcer used to read out a stale-data warning if the post-wake catch-up poll took longer than 15 seconds; the grace window now lasts until the catch-up poll actually completes, with a 60-second safety net for genuine cron problems.
- Hill-game-tied announcements are leaner. Now reads "...Steadman 3, Carter 3. Black-ball shootout for the match." instead of repeating the tied score three times. Same for World Championship deciders.
- Info and Contact links in the header now open in a new tab, so the announcer keeps running on the home tab while you read.
- Auto-off countdown now reads "Stops in 1 hr." straight after selecting 1 hour (was "Stops in 59 min." due to a rounding off-by-one). Same fix at minute and second granularities.
-
- The announcer now follows the World Seniors Snooker Championship at the Crucible (6 to 10 May), in addition to anything else that happens to be playing. The Crucible-only filter now points at the Seniors event instead of the World Championship that finished on Sunday.
- Streak follow-ups now use the player's surname instead of "he", so the announcer reads naturally regardless of the player.
- New player names load four times faster. When a fresh tournament starts, you used to see "Player 170 vs Player 38" for several minutes while names trickled in - the page now fills in everyone's names in a single update.
- Match cards and the "Follow these matches" list now show the round (R1, R2, QF, SF, Final) for Seniors matches, the same as for the World Championship.
- Round-aware announcements ("needs one to make the final", "is into the semi-finals", "Decider for the championship") now work for Seniors too, with shootout wording on tied matches since Seniors has no decider frame.
- The Start-button readout now names the tournament, so "Round 1 starting tomorrow at 7 pm" reads as "World Seniors Snooker Championship Round 1 starting tomorrow at 7 pm" - useful when a listener is opening the page cold and doesn't yet know which event is in play.
- The "Follow these matches" picker only shows matches starting within the next 24 hours. Matches further out are still in the data and will be auto-followed when their session approaches - they just don't clutter the picker until they're imminent.
- Match-win announcements now survive the case where snooker.org drops a finished match from the live feed before the page next polls. Previously the win could go unannounced if the match vanished too quickly (this happened in the World Championship final on Sunday, where "Yize Wu is the World Snooker Champion" was silent). The announcer now infers the winner from the last-seen score when a match was within one frame of victory and disappears - and for the harder case of a match that disappeared while tied at hill-game, the announcer now fires a single follow-up lookup to find the real winner.
- Reopening the laptop or unlocking the phone after a sleep no longer triggers any announcement. The announcer just resumes silently, ready for the next real frame change. This avoids the catch-up flood, and avoids surprising the user with an unprompted readout if they're in public.
- The "Follow these matches" empty state now mentions when the next session starts and which tournament it is ("No matches in the next 24 hours. World Seniors Snooker Championship R1 starts tomorrow at 7 pm."), so it's clear the page is healthy and just waiting for play to begin.
-
- Day 2 of the World Championship final now reads the correct welcome - "The World Championship final concludes today" - rather than repeating Day 1's wording.
-
- Daily welcome message on the day of the World Championship final - "It's the day of the World Championship final" on day one, "The World Championship final concludes today" on day two. First-time visitors hear "Welcome to Snooker Announcer", returning visitors hear "Welcome back to Snooker Announcer". Fires once per browser per day, the first time you press Start.
-
- Finished matches no longer appear in the "Follow these matches" checkbox list - they're still visible in the main score panel below, but cluttered the follow list since the announcer doesn't fire any further updates for them anyway.
- Match-win announcements now name what the win unlocks - "Shaun Murphy is into the final" at the SF, "John Higgins is the World Snooker Champion" at the F, "is into the semi-finals" at the QF - instead of the flatter "has won". When the second SF finishes and the other SF is already done, it'll also name the opponent in the final: "Allen is into the final, to face Murphy".
- When a player needs one more frame to win, the announcer now names the destination round - "Murphy needs one to make the final" at the semis, "Higgins needs one to win the championship" at the final, "needs one to make the semi-finals" at the QF. In hill-game (both players one frame away), it just says "Decider to make the final" or "Decider for the championship". More like how human commentary phrases the close-out moment.
- Fixed the "score not updated for N min" warning showing as soon as a session resumed - the timer was counting through overnight breaks, so a match that resumed after a 13-hour gap would falsely flag as stale. The clock now resets when a session restarts.
- Live score-change announcements now include the frame number - "Score update: Frame 15. Two frames in a row for Wu..." - so it's clear which frame just completed.
- Catch-up announcements (when frame-by-frame detail arrives after the running score) read more naturally - "More information on that last frame: Wu won it, 142 points to nil, including a break of 142" - rather than redundantly repeating the frame number and winner that you already heard.
- Auto-off (sleep timer) now offers 6 and 8 hour options too, in addition to 1, 2, 3, and 4 hours - more useful for keeping the announcer on through a full workday in the background.
-
- Frame-by-frame detail for a recently-announced score now reads as a follow-up - "More information on that last frame: Higgins took frame 24, 101 points to nil, with a break of 101" - rather than repeating the streak headline.
- "Resumes today at 7 pm" no longer shows when the time is more than 2 hours in the past - in those cases the source data hasn't yet been updated to the next session, so the card just says "Between sessions" rather than misleading you about timing.
- Pressing Start now only reads out matches in the most relevant state - currently in play if any, otherwise between sessions, otherwise upcoming, otherwise finished. Quicker to get to the live news.
- Streak announcements no longer repeat the player's name - "Two frames in a row for The Wizard of Wishaw. He took frame 14..." instead of saying "The Wizard of Wishaw" twice in a row.
- Favicon redesigned: a small triangle of three coloured balls (yellow, green, blue) instead of the previous red ball, to be visually distinct from snooker.org's site icon.
- An in-play match whose score has not moved for over 45 minutes now shows "score not updated for N min" on its card, so it's clear when the underlying data feed is slow rather than the match having a long frame.
- Fixed a bug where streak counts could go up by an extra step when frame-by-frame data caught up after the running score had already changed.
- Auto-off (sleep timer) added: stop the announcer automatically after 1, 2, 3, or 4 hours. Useful for listening before bed without it talking to itself overnight. A spoken warning fires one minute before stopping.
-
- Match groupings reworked: matches now sit under Currently in play, Between sessions, Coming up (within 24 hours), Future, or Past matches, with the right group decided automatically.
- Each match card shows a round pill (QF / SF / Final), and the round is read aloud in the full-scores readout.
- Match filter list now sorts chronologically within each group, so matches appear in the order they're due to play.
- Frame-by-frame announcements (semis and finals) now include streak headlines like "Three frames in a row for Murphy", matching the existing behaviour in earlier rounds.
- Player nicknames are now used for both single-frame wins and streaks (e.g. "Two frames in a row for The Pistol").
- Frame announcements now describe a break by the frame's losing player as a "consolation break" - standard snooker commentary phrasing.
- Frame announcements say "110 points to 1" rather than "110 to 1", making it clearer it's the frame's point total rather than a match score.
- Score announcements use "nil" instead of "zero" - the natural snooker phrasing.
- "TBD" placeholders for not-yet-determined players are read out as "to be decided" rather than spelled letter-by-letter.
- Score updates combine "X leads by N and needs M to win" into one sentence; dense announcements are split into shorter sentences with natural pauses.
- Timed readout preamble changed from "Latest score" to "Current score".
- The "trouble refreshing" banner is now more accurate: it stays quiet during long frames where nothing is changing, and during the moment a laptop or phone wakes from sleep.
- Older days in this list now collapse to one line each; click to expand.
-
- Pre-session pauses no longer mislabelled as "Mid-session break" — they now show the resume time.
- Settings (announcement frequency, speech speed, filters) persist between visits.
- "On score change" is now the default announcement mode, so you only hear something when something actually happens.
- Diagnostics panel added for service health and data freshness.