Booking flow examples: seven shapes, and the prompt that builds each one

Stanislav TyshchenkoTutorialUse Case14 min read
A wooden shape-sorter lid with seven cut-out holes labelled barber, clinic, class, padel, studio, car and villa, under the headline Every business books a different shape, with a yellow one-size widget peg lying beside it

Ask Lovable, v0 or Claude Code for "a booking site" and you get the same three screens almost every time: pick a service, pick a date, pick a time. For a barber that's right. For a padel club it's wrong, because players choose a court on a grid. For a car rental it's wrong, because the unit is a day and the car is gone from Tuesday to Friday. For a Pilates studio it's wrong, because a slot is a seat in a room that fills up.

The flow follows what the business sells, and in practice there are about seven shapes. This article walks through each one: the order of the screens, the Opencals Storefront API calls behind it, the mistake AI builders make with it, and a prompt you can paste. Six of the seven have an MIT-licensed Next.js template you can click through before you build anything.

Five questions decide a booking flow: what is booked (a person, a unit, a seat), one-to-one or group, fixed or variable length, where it happens, and what extras come with it. Those answers produce seven common shapes: staff-first, guided intake, class timetable, unit grid, hourly room with extras, day-range rental and nightly stay. On Opencals all seven run on the same API with one API key, and the AI builder only changes the screens. You can build and test any of them on a free development store; it runs in test mode and can't take real payments until you switch it to production.

Five questions decide the flow before any design does

A booking flow is the order of screens a customer goes through to reserve something and pay for it. Its shape comes from the business, not from the design: what's being booked, how many people share it, how long it lasts, where it happens and what's sold with it. Answer those five questions first and the screens mostly follow. Restyling a booking page is cheap. Changing its flow after launch isn't.

  1. What is booked? A person's time (a stylist, a physio, a tutor), a unit (a court, a room, a car, a villa), or a seat in something that runs anyway (a class).
  2. One-to-one or group? A group product has a capacity, so the page needs "4 spots left" and a party size.
  3. Fixed or variable length? A 45-minute cut is fixed. A studio session of one to four hours isn't, and neither is a three-day rental.
  4. Where? Several locations usually means picking the location first. An online location means a video link after booking. A mobile service means asking for an address at checkout.
  5. What comes with it? Add-ons such as a beard oil, a second camera or an airport transfer, priced per booking or per hour or day.

Here's how the answers combine:

Booked byScreen orderThe call that mattersLive example
1. Staff-first (salon, barber, coach)A person's timeService → person or "anyone" → day → time → extrascurrent-availabilities with staffMemberIdHaar, Frisor
2. Guided intake (clinic, therapy)A practitioner, after triageWho it's for → what's wrong → clinic or video → clinician → time → notesCheckout questions and file uploadsClear Care
3. Class timetable (school, studio)A seatTimetable → class → party sizemaxAttendees − attendeesFluently, Tensile
4. Unit grid (courts, bays, lanes)A unit for a lengthClub → day → units × time grid → lengthOne merged availability read per unit, cachedVOLT
5. Hourly room with extras (podcast, photo studio)A room by the hourRoom → length → start time → extrasduration on availability, per-hour add-onsNo template yet
6. Day-range rental (cars, boats, gear)Whole daysItem → pick-up and return → deliver or collect → extrasMerged ranges without duration, checked on the clientNOIR Drive
7. Nightly stay (villas, cabins)Nights, fixed check-inVilla → check-in and check-out → guests → extrasFixed times the server enforcesBali Villa Rentals

Every prompt below leaves out services, prices, staff and opening hours on purpose. Those live in the Opencals dashboard and come back from the API, so when the business adds a treatment or a court it shows up on the site without anyone prompting again. The prompt's job is to name the shape and the look.

1. A barber books a person, so the person comes early

At a barbershop the regulars want their barber, and everyone else wants the soonest chair. So the flow is: service, then a barber or "Anyone available", then a day, then a time, then extras, then checkout.

Behind it, the page loads the service by its slug. If the service has variants ("Skin fade", "Scissor cut"), the customer picks one first, and every later call uses the variant id. The date picker calls current-availability-ranges once to grey out days with nothing free, and nearest-availability to open on the first bookable day. The time grid calls current-availabilities for the chosen date. For "Anyone", a slot is bookable if its staffMemberIds list isn't empty, and you leave staffMemberId out of the booking so the engine assigns someone.

Where AI builders go wrong: they hard-code the barbers into a dropdown, or put the barber choice after the time, which means a regular finds a slot and then discovers it's with someone else.

text
Build a booking site for Hook & Blade, a three-chair barbershop in Manchester. Services, prices and barbers come from Opencals. Flow: service, then a barber or "Anyone available", then day, then time, then extras, then checkout. Dark and editorial: near-black, brass accents, a condensed serif for headings. Mobile first; most people book from their phone on the way home.

The Frisor template is this shape with add-ons in the same transaction, and Haar is the salon version with multi-location booking.

2. A clinic patient starts from what's wrong, not from a department

A salon customer knows they want a colour. A patient often doesn't know whether a sore knee is physiotherapy or orthopaedics, and making them choose a department on the first screen loses a lot of them there. The guided-intake shape asks who the visit is for (me, my child, someone else), what's going on, and in clinic or by video, then recommends visits with their next free times. After that it behaves like the staff-first flow: clinician or "first available", day, time.

What's different is the end. Pre-visit notes are checkout questions, answered per visit so a family booking keeps each patient's notes apart, and photos go up through a presigned upload URL. Departments are product collections, clinicians are staff members, and the video option is the store's online location, whose meeting link comes back on the booked appointment.

Where AI builders go wrong: they build a symptom checker. The Clear Care template deliberately doesn't: its Care Finder maps needs and keywords from a config file to visits, says plainly that it isn't a diagnosis tool, and shows an emergency notice on every booking screen. Opencals also isn't a medical record system. There's no charting, so a clinic that needs clinical notes and insurance billing keeps those in its practice software.

text
Build a booking site for Northside Physio, a two-location physiotherapy clinic in Leeds. Patients start from what's going on (back, knee, sports injury, not sure), then choose in clinic or video, then a physio or "first available", then a time. Show the store's pre-visit questions after the time is picked. Calm and clinical: white, soft blue, lots of space. Add an emergency notice to every booking screen.

3. A class sells seats, so the timetable is the booking page

For a language school or a reformer studio, nobody browses "services" and then looks for a time. They look at the week and pick a class that's on. The timetable is the catalogue: rows of sessions, each showing the teacher or instructor and how many places are left, and a click goes straight to party size and checkout.

Each availability slot for a group product carries maxAttendees and attendees, so places left is the difference. The booking sends numberOfAttendees, and if the product allows guests, friends' emails can go on the appointment without each needing an account. Fluently models a language as a collection and levels (A1, A2, B1) as variants of a group class. Tensile goes further for a Pilates studio: one variant per class, studio and instructor, capped at the number of reformer beds in that room.

The gotcha nobody expects: once a class is full, the API stops returning that slot. To the page, a full Tuesday class simply isn't there. Tensile handles it by learning each series' weekly pattern, showing the missing week as Full, and linking to the next class of the same type with space. You'll want the same, because a timetable with mysterious gaps reads as "the studio is closed".

That's also a real limit to know about: Opencals has no waitlist. When a class fills, the best the page can do is point people at the next one.

text
Build a booking site for Tensile, a reformer Pilates studio in Berlin with three studios. The home page is a weekly timetable across all studios: class, instructor, studio, and places left as small dots. A full class shows as Full and links to the next class of the same type with space. Clicking a class goes to party size, extras, then checkout. Warm plaster background, technical sans-serif, spring colours for intensity.

4. A padel club sells courts, and the grid is the product

Players don't want a list. They want to see every court at once and spot the free 19:30. So the club page is a grid: courts down the rows, half hours across, and a duration choice (60, 90, 120 minutes) when you tap a cell. VOLT adds a hall map, every court drawn from above and lit by whether it's free at the chosen time, over the same data.

There's no endpoint that returns availability for several courts in one call, so the naive build asks for every court on every day from the browser and runs into the rate limit by Tuesday. VOLT reads each court's merged free ranges for the whole booking window once, from a server route, caches it for 60 seconds, and drops the cache after a booking, cancel or reschedule. The browser then draws the grid, the hall map and every "free from 18:00" from those spans, so changing day, sport or game length makes no API calls at all.

text
GET /storefront/products/{courtId}/current-availability-ranges?timezone=Europe/Madrid

When the player picks a length, the page asks that one court again with duration (in seconds) to confirm the block fits, then books the slot it gets back.

Where AI builders go wrong: they create a "60-minute court" and a "90-minute court" as separate products. Separate products don't block each other, so the same court gets sold twice for overlapping times. One court, one bookable unit, with variable length switched on.

text
Build a booking site for VOLT, a padel and squash club with three locations. Booking starts from one club (remember the last one). Show a courts × time grid for the chosen day, half-hour columns, a now-line, and a length picker (60/90/120) when a free cell is tapped. Read each court's availability ranges once on the server and cache them; don't fetch slots per cell. Then players, racket hire, details, payment. Dark, sporty, one hot orange accent.

5. A studio hour is sold with its extras attached

A podcast or photo studio sells a room by the hour, and the extras cost more the longer the session runs: a second camera, an engineer, editing. The flow puts length first, because it changes which start times are possible: room, then one to four hours, then a start time, then extras, then pay.

The studio is a single product with custom duration on: a one-hour base (3600 seconds), a maximum length, and an hourly price. Passing duration to the availability call means only start times with enough free room after them come back, so a three-hour session never offers 16:00 when the room is booked at 18:00. Add-ons come in two kinds: fixed (an on-screen logo, quantity one) and duration-multiplied, where a per-hour extra on a three-hour booking becomes three units without anyone doing the sum. The cart total is the price; the page can show an estimate but shouldn't calculate the bill itself.

What I haven't solved: if the base unit is an hour, nobody can start at half past. Make the base thirty minutes and it works, but every half hour is then priced separately, which may not match the studio's rate card. VOLT hits the same trade-off with courts. There's no template for this shape yet; the podcast studio API walkthrough covers the model in detail.

text
Build a booking site for a podcast studio group in London with five studios, each with its own hourly rate. Flow: studio (photo cards), then session length 1–4 hours, then a start time for that length, then extras (second camera, on-screen logo, cloud storage), then checkout. Show the cart total, not a price you calculate. Warm, low light, lots of photography.

6. A car is rented by the day, midnight to midnight

Rentals flip the picker. Instead of one day and a list of times, the customer chooses a pick-up date and a return date on a range calendar, and the car is blocked for the whole span. Then: delivered to an address or collected from the garage, a handover window, per-day extras like an excess waiver, a fixed extra like a child seat, a driving licence upload, and pay.

In NOIR Drive each car is its own product with a one-day base duration, variable length and a 24/7 schedule, so bookings can cross midnight. The calendar reads the car's merged availability ranges without a duration and checks on the client that pick-up to return fits inside one free range. The slot runs from 00:00 on the pick-up date to 00:00 on the return date in the store's timezone, sent as UTC: in Dubai, 10 to 13 November becomes 20:00 on the 9th to 20:00 on the 12th, three days at the daily rate. The handover window and flight number travel as custom attributes on the appointment, and the security deposit is a required checkbox question, taken at handover rather than charged online.

Where AI builders go wrong: they make one "Range Rover" product with each car as a variant. Variants don't block each other, so the same physical car can be booked twice. One car, one product.

text
Build a car rental site for NOIR Drive in Dubai, twelve cars. Each car page has a two-month range calendar on live availability. Flow: car, pick-up and return dates, deliver to my address or collect at the garage, a handover window, per-day extras and fixed extras, licence upload, then payment. Show days × daily rate + extras as an estimate; the cart total is the price. All black, cinematic, champagne accents.

7. A villa is booked by the night, and check-in time isn't up for discussion

A stay looks like a rental, but it's counted in nights and it starts and ends at fixed times. Check-in at 15:00, check-out at 11:00, and the day a guest leaves can be the day the next one arrives.

In Bali Villa Rentals each villa has a one-night base with variable length and fixed check-in and check-out times, and the server enforces them: a booking from the site that doesn't start at the fixed check-in or end at the fixed check-out gets a 400. A 15:00-to-11:00 stay of four nights is shorter than 96 hours and is still charged as four nights. Adults, children, infants, arrival time and flight number are custom attributes. Bookings the owner makes in the dashboard are exempt, so a guest can still be given an early check-in by hand.

text
Build a villa booking site for a resort of ten villas in East Bali. Each villa page shows nightly rate, a check-in/check-out calendar on live availability, and fixed times (check-in 15:00, check-out 11:00). Ask for adults, children, infants and arrival time before checkout, then offer airport transfer and floating breakfast. Changing dates keeps the same number of nights. Warm, quiet, rice-field photography, a serif for headings.

When one business is two shapes

Plenty of businesses sell two shapes at once, and the generated site usually only builds one. VOLT sells courts on the grid and coached sessions through the staff-first flow, both ending in the same checkout. NOIR Drive rents cars by the day and sells chauffeur packages with real drivers. Tensile has the class timetable plus private and duet sessions that share one private room.

The fix is to say so in the prompt: "Two ways in: book a court, or book a coach." Name both shapes and the builder will make two entry points into one checkout, instead of forcing coaching sessions into a court grid.

What none of these shapes should do in the browser

The shapes differ on screen. Underneath, the same handful of rules hold, and they're the ones a generated site breaks most often:

  • Nothing about the catalogue is hard-coded. Services, prices, durations, staff, locations and hours come from the API.
  • No availability, pricing, discount or tax logic in the app. Render what comes back; the cart's totals are the truth.
  • The slot is held, not just picked. Booking a slot puts it in a cart with an expiresAt. Show the countdown, extend the hold while the customer is typing, and start over cleanly if it runs out.
  • Times are UTC in the API. Convert for display and send back exactly what you received. Rentals and stays are where this slips most.
  • The API key stays on the server. Lovable keeps it in connector credentials, v0 in an environment variable, Base44 in an app secret, a Next.js app in server code.
  • Real errors reach the customer. "That time was just booked, please choose another" beats "Something went wrong". Show the API's message and keep the customer's selections.
  • Cache the catalogue and use availability ranges. Behind a builder's gateway every visitor can share one IP, and Lovable sites get about 120 requests a minute in total. The grid in shape 4 is where this matters most.

And the limits worth hearing before you pick: Opencals has no waitlist, the booking engine is hosted rather than open source (the templates, skills and SDK are MIT), and a development store is free for as long as you like but runs in test mode, so it can't take real money until you switch it to production.

Where to paste these prompts

The prompts work as written once the builder knows how to talk to Opencals. That's a one-time setup per builder: a custom connector with two knowledge files in Lovable, the open-source agent skills in v0, Claude Code, Cursor or Codex, and a backend function plus two skills in Base44. The guide to building a booking site with AI has the setup for each, and the skills and knowledge files already cover these shapes, so a short prompt is enough.

To test against real data without typing it in, create a development store and pick a seed dataset. Several match the templates above (salon, barbershop, padel club, medical clinic, villa resort, reformer studio), so the site your builder generates has services, staff and bookings on it from the first preview.

If you're building for a business that doesn't fit any of these seven, I'd like to hear what it is. The next shape I'm watching is a package builder, where choosing one thing changes which rooms or people are offered next, and I don't think any template does that well yet.

Frequently Asked Questions

Get started

Ready to transform your service business?

Join 150+ businesses already using Opencals. Start on a free development store with every feature unlocked, and only pay once you go live.

No credit card required
Setup in 10 minutes
Cancel anytime