Lab

Golf tee-time alerts

A bot that watches 60-plus public golf courses and pings me the moment a tee time I want opens up. Built with Claude Code, one weekend round at a time.

See it live ↗
The tee-time alert search screen, with region, date, time window, players and holes, and buttons to search or set an alert.
Status Live
Started May 2026
Role Product owner, golfer, and builder
Stack Claude Code · Claude Code on the web · Cloudflare Workers · Cron Triggers · Cloudflare KV · Cloudflare Pages · Telegram Bot API · Resend · Vitest · GitHub Actions

The brief

Good public golf in Los Angeles is hard to book. The best morning times at the courses I like are gone within minutes of opening. After that, the only way in is to catch a cancellation, and that means refreshing a booking page all week.

I wanted one Saturday round at Rustic Canyon: May 23rd, between 8am and 1pm, for two. So on May 11th I put together a small script that checked the course’s public tee sheet every ten minutes and sent a message to my phone when a matching time showed up. It was set to shut itself off the day after the round.

Two months later that one-course script had become a proper service. It now covers 60-plus public courses across LA, Orange County, Long Beach, Ventura, the Inland Empire, and Atlanta.

How it works

You pick a course, a date, a time window, how many players, and 9 or 18 holes. You choose email or Telegram. That’s the whole interface.

The alert setup form: choose email or Telegram, then region, course, date, time window, minimum players and holes, and a Set Alert button.
Setting an alert. Pick the round you want, and the bot does the refreshing for you.

Behind it:

  • A Cloudflare Worker on a ten-minute cron. Each run groups every active alert by course and date, so each tee sheet gets checked once no matter how many people are watching it.
  • One adapter per booking system. Courses run on four different booking platforms. Each one has a small adapter that turns its public availability into the same simple list of times, spots and green fees. Adding a course is one line in a course list.
  • It cleans up after itself. Alerts expire the day after the round, so nobody has to remember to turn them off.
  • A small analytics layer. The bot logs when slots appear and disappear, so I can see patterns like when a course releases its tee sheet or when cancellations tend to show up.

The latest change opened it up so another app can ask about courses anywhere, not just the built-in list — so a remixed version on brikz can point the same engine at a city like New York.

I built nearly all of it with Claude Code, much of it in Claude Code on the web. The commit history shows Haiku, Sonnet, Opus and Fable models each doing parts of the work. To be clear, the product itself makes no AI calls. It’s plain, reliable automation. The AI is in how it got built, and how fast: a one-course script on a Monday, four booking systems, email sign-up, analytics and a test suite within about two months.

Where I sign off

It never books anything. It finds the time and tells you, and a person still taps the link and books on the course’s own site. I made that choice on purpose and I’d make it again. It keeps the bot polite to the courses (it reads the same public availability you’d see, once every ten minutes), and it means a bug can only cost you a wasted notification, never a tee time you didn’t want or a fee you didn’t agree to.

I also decide what ships. I describe the feature in plain English, Claude builds it, and I check it against a real course’s booking page before I trust it, because “the tests pass” and “there’s actually a tee time at 7:10” are different things.

What broke

  • Ghost tee times. People got alerts for morning times, opened the booking page, and found nothing. One platform reports local course time but labels it as if it were UTC, so the bot was shifting every slot seven or eight hours early. A real 1pm opening came through as 6am. We fixed it by reading the time exactly as written, then checked it against the live course: a 6–9am window now correctly returns zero.
  • The free tier pushed back twice. First the cron ran out of CPU time by checking alerts one at a time; doing those checks in parallel fixed it. Then the analytics logging wrote a record for every slot on every run, about 30 to 50 writes, 144 times a day, well past the free plan’s 1,000 writes a day. Now it only writes when a slot actually changes.
  • Alerts that never arrived. If the worker was killed between “mark as sent” and actually sending, the alert was lost for good. The fix was simply putting the steps in the right order: mark it only after the message goes out.

What’s next

More courses, starting with the ones people request through the feedback form. Then I want to put that slot history to use. Once there’s enough of it, the bot should be able to tell you not just “a time opened” but “this course usually frees up Saturday mornings on Thursday night.”

← All Lab projects