Extend an existing CRM
Booking, waitlist and retention system for a fitness studio group
A class waitlist that fills cancelled spots automatically and follows up with members who've stopped coming, built on the CRM the studios already paid for.
- Role
- Architect and developer, via an agency partner
- Client
- Fitness studio group (anonymised), delivered through an agency partner
The problem
A group of fitness studios ran its bookings, contacts and messaging through GoHighLevel. Classes filled up, but there was no waitlist: when someone cancelled, the spot sat empty unless staff noticed and messaged people by hand. Members who stopped turning up drifted away without anyone following up.
The agency partner needed a build partner who could add this without migrating the client off the platform they were already paying for and trained on.
What they already had
- GoHighLevel as the CRM, calendar and messaging hub, with staff using it daily.
- Contacts, class calendars and conversation history already in GHL.
- A WhatsApp channel and GHL's Conversation AI bot.
The overbuilt answer would have been a new booking platform with its own database and a migration project. Everything the client needed already existed in GHL except the waitlist logic and the retention triggers.
What I built, and what I deliberately didn't
Built: a small Next.js service that sits beside GoHighLevel and talks to it through the GHL API.
- Class waitlists with automatic promotion: when a booking is cancelled, the next person on the list is promoted and the booking is written back to GHL.
- Retention messaging triggered by API, using the channels GHL already had.
- WhatsApp templates and a bot hand-off so the retention messages and the existing Conversation AI bot don't talk over each other.
Didn't build:
- A parallel member database. GoHighLevel stays the system of record. The service stores only what it needs to run a waitlist.
- A new front end for staff. They keep working in GHL.
- A new messaging stack. Messages go out through the channels the client already had approved.
For the technical readerUnder the hood: production details, architecture and stack
Production details
- Concurrency-safe promotion: two cancellations landing at the same moment must not promote the same person twice. Waitlist promotion runs under Postgres advisory locks so each class is processed by one worker at a time.
- WhatsApp template approval: retention messages go out as approved WhatsApp templates.
- Inbound collisions: the bot architecture is designed so that a reply to a retention message is routed correctly instead of being picked up by the Conversation AI bot as a new enquiry.
Architecture
- GoHighLevelCRM, calendar, messaging (system of record)
- Waitlist serviceNext.js + Postgres, advisory locks
- WhatsAppApproved templates, bot hand-off
Stack
Next.js, TypeScript, Supabase (Postgres), GoHighLevel API, WhatsApp Business API.