Use cases · 10 min read · Updated 15 August 2026

Build a booking app with AI: slots, customers and what actually breaks

A booking app in NorthernGo is three collections — customers, services, slots — plus login and a delete-account button. Describe the rules in the prompt: unique slot, one booking per slot, confirmation e-mail. The first generation will look finished and still lose to double-booking, timezones and payments. Those three are ordinary engineering, not a better prompt.

A booking app is a calendar with rules, not a marketplace

"Build me a booking system" is the most common sentence people type into an AI app builder. What they need is smaller: a list of services, a grid of free slots, a customer record, and a rule that two people cannot take the same slot.

NorthernGo already gives you the shell. Every app gets a Supabase PostgreSQL database in the EU, e-mail and password login, and a PWA. You describe the salon, the clinic or the workshop in text, voice or a sketch. Architect, Builder and Critic write one HTML file in vanilla JavaScript and Tailwind. The code is yours. ZIP export is on Premium and Pro.

What this is not: a multi-location hospital system, or a payments product. Payments use your own Stripe account on Pro. The first version should take a name, a service and a time, and refuse a collision.

What the first generation gets wrong

Double-booking. The model draws a pretty calendar and a Save button. It does not, unless you say so, check that the slot is still free between the click and the write. Two customers on a slow mobile will take the same 14:00. The rule belongs in the prompt and in a test: open two tabs, book the same slot, confirm one fails.

Timezones. A slot stored as "14:00" without a timezone is a local string. A customer booking from another region, or a phone that switched to summer time, will show the wrong hour. For a single-site Swedish salon, store times in Europe/Stockholm and say so on the screen. Do not invent a world clock in version one.

Payments. "Add checkout" produces a fake button more often than a charge. Leave money out of the first prompt. Take the booking. Confirm by e-mail. Add Stripe when the collisions are gone.

Permissions. Staff and customers are different jobs. The generated app has one login type unless you invent a role field and then enforce it yourself. An "Admin" badge is paint.

Step 1: Name the records

Write the collections before the colours.

Say "e-mail is unique on customers" and "a slot may have at most one customerId". Those two sentences prevent most of the mess.

Step 2: Put login in front of the book action

A public catalogue of services can be open. Creating a booking should require an account, so you have someone to e-mail and someone who can delete themselves. Any app with login must include a working delete-account path — GDPR article 17. Put that in the first prompt. The platform will put the button back if a later edit removes it.

Staff who manage the grid should use a separate login you create by hand. There is no invite API and no magic "only @salongen.se".

Step 3: Generate, then attack the slot

Prompt for the three screens: list of services, week grid, my bookings. Generate locally if you are iterating on layout — unlimited on every plan — and spend a cloud generation when the data model is wrong.

Then open two browsers. Book 14:00 in both. If both succeed, the app is not a booking app yet. Add an explicit check: get('slots'), find the id, refuse if status is not free, then save with booked. There is no transaction API. The check-then-write can still race. For a one-chair salon that is usually acceptable. For twenty parallel chairs it is not — say so before you sell it.

Step 4: Confirm by e-mail, not by hope

window.NorthernGo.sendEmail(to, subject, html) sends a transactional message. Call it after a successful save, not before. Include the time in Europe/Stockholm, the service name, and a sentence that cancellations happen inside the app, not by replying.

Do not put other customers' e-mails in the page source. get('customers') is scoped to the signed-in user; do not build a "all bookings today" admin view that dumps everyone onto a public URL.

Step 5: Decide what version two is allowed to be

Version two can be Stripe deposits, SMS reminders (not a built-in SDK — you would webhook out), or a Fortnox pipe on Pro. Version two should not be "also a marketplace for ten salons". That is a different product.

Export the code on Premium or Pro before you depend on the live URL. The lock-in guide is the exit plan. Read the generated file for innerHTML and anything that looks like a key before the first real customer.

The write that actually takes the slot

Paste this shape into the prompt, or into the file after the first generation, so the agents are not inventing a second database.

async function bookSlot(slotId, customerEmail) {
  const slots = (await window.NorthernGoDB.get('slots')) || [];
  const slot = slots.find((s) => s.id === slotId);
  if (!slot || slot.status !== 'free') {
    throw new Error('That time is no longer free.');
  }
  await window.NorthernGoDB.save('slots', {
    ...slot,
    status: 'booked',
    customerId: customerEmail,
    bookedAt: new Date().toISOString()
  });
  await window.NorthernGo.sendEmail(
    customerEmail,
    'Your booking is confirmed',
    '<p>We booked you at ' + slot.startsAt + '. Cancel inside the app.</p>'
  );
}

Three things in that function are doing the work the pretty calendar will skip. It re-reads the slot. It refuses anything that is not free. It mails only after the save. It still cannot lock the row. Two phones that both passed the check will both write booked. Disable the button after the first click. For a one-chair salon in Lycksele that race is rare. For a drop of forty concert seats it is the product, and this API is the wrong tool.

Store startsAt with an offset (2026-09-03T08:00:00+02:00) and show Europe/Stockholm on the screen. A cabin in Ammarnäs booked from Berlin will otherwise slide by two hours. Models love locale-free date formatting. Read that part of the file.

The last twenty percent is this function, the two-browser test, the delete-account button, and the decision to keep money out until collisions are gone. The first eighty percent is the agents. A booking app that ignores the split looks finished on Monday and double-books on Friday.

A booking app is the fastest public use case this builder has. It is also the fastest way to learn that a finished-looking calendar is not a finished system. A first prompt that names customers, services, slots, login, delete-account and sendEmail will beat a prompt that only says booking app. Spend a cloud generation on that contract. Iterate locally on the colours. Then attack the slot in two browsers before you give anyone the URL. If the prompt never named deleteAccount, sendEmail and a free-or-booked status, the first generation will invent a calendar that writes to localStorage and congratulates you. That is a demo. A booking app is the function above, plus the two-browser test, plus a customer who can erase themselves. Free is five cloud generations and unlimited local ones. Use the local budget on the grid. Use one cloud generation on the contract. Do not spend the month polishing a calendar that still writes to localStorage.

Frequently asked questions

Can I build a booking app with AI without coding?

Yes for a first version: services, a week of slots, login and a confirmation e-mail. You still have to specify the no-double-booking rule and then test it in two tabs. The builder will not infer that rule from the word "booking" alone.

How do I stop double-booking in an AI-generated calendar?

Put a unique slot record in the prompt and a check-then-save in the app: read the slot, refuse if it is not free, then write booked. There is no database transaction API, so two simultaneous clicks can still race. Test with two browsers before you take real customers.

Can the booking app take payments?

Not reliably in the first generation. Add Stripe on Pro after the slot logic works, using your own Stripe account. Do not ask the first prompt to add checkout. A fake pay button is worse than no button.

Does a booking app with login need a delete-account button?

Yes. NorthernGo requires a working delete-account control in every generated app with login, as GDPR article 17. Customers who booked a haircut still have the right to be erased.

Build it yourself

NorthernGo turns a plain-text description into a working web app with a database, login and a live URL. Local AI generation runs on your own GPU, is unlimited, and is free on every plan.

Start building free