# How to build a booking system with AI (owned product path)

> Day-1 path for an owned booking product: roles, availability, confirmations with Stripe hooks, then the agent loop — faster than Cal-only or a sandbox MVP.
> By Dave · 2026-09-14
> Source: https://otf-kit.dev/blog/how-to-build-a-booking-system-with-ai

Building a booking system with AI usually stalls in one of two places. You paste a scheduling link into a landing page and call it done — until clients need discovery, priced services, live slots, and payment at confirm time inside your app. Or you spin a sandbox prototype that looks bookable in a chat preview, then discover you still own none of the availability rules, double-book checks, or checkout webhooks.

This post is the day-1 build path for the third option: an owned booking product. The order that sticks is roles, then availability, then confirmations (including payment hooks), then the agent loop that keeps extending the same repository. It is not a scheduling-link versus product-kit shootout — that contrast lives at [/blog/otf-vs-cal-calendly-booking](/blog/otf-vs-cal-calendly-booking). It is also not a pure “own the repo” kit tour; for agent-doc ownership and handoff files see [/blog/booking-kit-own-the-repo](/blog/booking-kit-own-the-repo). Here the job is how to build the product outcomes faster than either Cal-only or a throwaway MVP.

## What you should have working on day 1

OTF lists the Booking Kit (Cadence) on https://otf-kit.dev/templates/booking-kit and in the kit table on https://otf-kit.dev/docs/templates/overview. Standalone price is $99. It is also in the Everything Bundle on https://otf-kit.dev/pricing. Live proof before checkout: https://booking-preview.otf-kit.dev.

Public product claims that matter for a day-1 booking build:

- Client path: home dashboard, provider discovery, service detail with scarcity, month calendar, realtime slots, session packages, Stripe checkout, QR booking ticket, and my-bookings
- Provider path: weekly hours and time off on the same product surface
- Data plane: auth, row-level security, realtime on bookings, and a Postgres gist exclusion constraint that blocks double-booking in the database
- Privileged work: Stripe checkout, webhook confirmation, and email reminders on a typed server path — not client-trusted
- Delivery: one product tree for phone and web; commercial source after purchase
- Agent handoff: `CLAUDE.md`, `.cursorrules`, `AGENTS.md`, and `ai/prompts/` so Cursor or Claude Code already know the map

Purchase path matches other OTF kits: Stripe checkout, license email with a private GitHub invite, then clone and run locally (accept invite, clone, install, run, deploy per https://otf-kit.dev/docs/templates/overview).

## When an owned booking product beats Cal-only or a sandbox MVP

Stay on a hosted scheduling link when the primary object is a meeting, a vendor booking page is acceptable, and your app can treat booking as an integration. Stay in a sandbox generator when you only need a disposable preview.

Prefer an owned booking product when most of these flip true:

- Clients discover providers, pick priced services, and manage appointments inside your app
- Providers edit weekly hours and time off in-product, not only on a host calendar
- Double-booking must fail in the database under concurrent clients
- Payments and booking rows live in schema you can migrate
- Maintenance happens in Cursor or Claude Code on disk, with project memory that survives the next tool switch

Scheduling links remain useful for sales demos; sandbox previews for a weekend spike. Buy the kit when availability, confirmation, and the client loop belong in a repository you keep. This how-to assumes you already chose “own the booking product.”

## Roles first, then availability, then services

Anthropic’s Claude Code memory docs state the constraint plainly: each session starts fresh, and project `CLAUDE.md` files carry persistent architecture and conventions. OTF’s AI tool overview documents the same pattern — every kit ships `CLAUDE.md`, `.cursorrules`, and companion agent files (https://otf-kit.dev/docs/ai-tools/overview).

For a booking system, handoff starts at **roles**, not a calendar widget. Cadence already names the two sides: clients discover, book, pay, and review; providers manage schedule, weekly availability, and time off. Auth and row-level security keep those paths honest. Do not invent a second “admin calendar” in chat that bypasses provider schedule screens.

Next is **availability**. Weekly rules and time off feed server-side slot computation so the client never invents open times from a partial cache. Realtime updates drop a taken slot before another client pays. The hard guarantee is the database exclusion constraint — concurrent clients racing one slot fail in Postgres, not in a hope that the UI stayed in sync.

Then **services**. Priced offerings, duration, scarcity, and session packages live in your service model. Month calendar and slot picker are product screens, not an embedded third-party widget.

```text
booking-kit/
  app/                 # Client: discover, book, my bookings; provider schedule
  server/              # Privileged Stripe, webhook, reminders
  database/            # Schema, RLS, slot RPC, exclusion constraint
  CLAUDE.md            # Stack map, conventions, how to extend flows
  .cursorrules         # Cursor-facing mirror of the same rules
  AGENTS.md            # Universal agent notes when present
  ai/prompts/          # Bounded recipes: add a service field, tweak scarcity UI
  README.md            # Setup, env, local boot, deploy
```

Treat `ai/prompts/` as recipes for bounded jobs — add a service field, adjust discovery filters, swap ticket copy — not a license to redesign booking invariants from a blank chat. The free SDK at https://github.com/otf-kit/sdk is the shared component layer; the paid kit is the finished appointment product plus agent configs that keep the next session honest.

![Decision: rent a scheduling link, sandbox MVP, or own the booking product](https://cdn.otf-kit.dev/blog/how-to-build-a-booking-system-with-ai/inbody-01-decision-20260914a.jpg)

## Confirmations and payment hooks before you polish UI

Confirmation is where sandbox MVPs quietly die. A green “Booked” toast is not a booking if the slot was never re-validated and no payment row exists.

Cadence’s confirmation path is explicit:

1. Re-validate the slot on the privileged server path before issuing Stripe Checkout
2. Confirm the booking row from the Stripe webhook (not from the client alone)
3. Send reminders on the privileged path (Resend in the shipped kit)
4. Keep the QR booking ticket and my-bookings list reading from confirmed rows

UI can change under an agent. The double-book guarantee stays in Postgres. Checkout confirmation stays your webhook. If an agent wants to “simplify checkout,” point it back at that order — slot check, then payment session, then webhook write — before any screen polish.

Optional Stripe and reminder env vars fail soft so the demo still boots; production fills them in. Day-1 local work can prove roles and availability without live money; shipping a paid product means wiring those hooks for real.

## Agent loop last — extend, do not rebuild

The loop you own matches the build order: roles first, availability and services next, confirmations tied to payment and database checks, then agents on the same tree.

1. **Roles** — confirm client and provider paths before adding a third persona in the UI alone
2. **Availability** — weekly rules, time off, and the slot RPC stay the source of open times
3. **Confirmations** — Stripe checkout only after slot re-validation; webhook confirms the booking; reminders use the privileged path
4. **Agents** — every later change starts from `CLAUDE.md` and `ai/prompts/`; prefer a named recipe over “rebuild booking from scratch”

That order beats a Cal-only embed for this ICP because the hard seams are already named when the agent opens the repo. It beats a sandbox MVP because project memory sits beside the screens — the next Cursor or Claude Code session does not re-interview you about calendars.

![Confirmation pipeline: re-check slots, payment, webhook stamp, then ticket](https://cdn.otf-kit.dev/blog/how-to-build-a-booking-system-with-ai/inbody-02-confirm-20260914a.jpg)

## A concrete first session after purchase

After you accept the GitHub invite from checkout, the first hour should look boring on purpose. Templates overview documents clone, install, and local run. Booking-kit also needs the example env and a database reset before demo data and RLS policies are live:

```bash
git clone <your-private-booking-kit-repo>
cd <booking-kit>
bun install
cp .env.example .env
bun run supabase:reset
bun dev
```

Open the repo in Cursor or Claude Code. Do not start with a blank “rebuild a booking app from scratch” prompt. Point the agent at the shipped docs:

```text
Read CLAUDE.md and ai/prompts/. Then:
1) Keep roles: client book path + provider schedule — do not invent a second calendar
2) Keep availability → slot RPC → checkout → webhook order
3) Add a field to services only where schema + UI already pattern it
4) Do not bypass the exclusion constraint or slot re-validation
5) Prefer existing screens over inventing a parallel booking flow
```

That prompt works because the kit already names the hard seams. When local preview matches — inspect https://booking-preview.otf-kit.dev first if you have not bought yet — follow the README deploy section. The live URL should serve your repository; the next availability or service tweak is another agent session on the same tree.

## What “owned product path” means operationally

Ownership here is operational: roles, services, availability, bookings, and payments live in Git and Postgres under your org; double-booking fails in the database; checkout confirmation is your webhook; `CLAUDE.md` and companion files reload every session so swapping Cursor for Claude Code does not rebuild project memory in a vendor UI; commercial rights are a one-time kit purchase (Bundle includes booking-kit — confirm limits on https://otf-kit.dev/pricing). Keep a scheduling link for sales or a sandbox for spikes if useful — neither replaces the product repository when the appointment is the product.

Booking-kit is the appointment product lane — not a $9 landing template, and not the SaaS dashboard or fitness kits. For scheduling-SaaS versus product-repo, read [/blog/otf-vs-cal-calendly-booking](/blog/otf-vs-cal-calendly-booking). For agent-doc ownership, see [/blog/booking-kit-own-the-repo](/blog/booking-kit-own-the-repo). To build day-1 outcomes — roles, availability, confirmations, agents — start on https://otf-kit.dev/templates/booking-kit, open the live preview, and buy when the client path matches.

## Sources

Booking Kit product page: https://otf-kit.dev/templates/booking-kit

Templates catalog: https://otf-kit.dev/templates

Templates overview (purchase → invite → clone → deploy): https://otf-kit.dev/docs/templates/overview

Pricing: https://otf-kit.dev/pricing

AI tool integration (`CLAUDE.md`, `.cursorrules`, `AGENTS.md`, `lovable.md`): https://otf-kit.dev/docs/ai-tools/overview

OTF SDK (shared component layer): https://github.com/otf-kit/sdk

Live booking preview: https://booking-preview.otf-kit.dev

Anthropic Claude Code memory: https://docs.anthropic.com/en/docs/claude-code/memory

Related: [/blog/booking-kit-own-the-repo](/blog/booking-kit-own-the-repo), [/blog/otf-vs-cal-calendly-booking](/blog/otf-vs-cal-calendly-booking)
