How it works · Schedule.software

Publish a window. Take a booking. Guarantee the seat. Hand back a calendar.

Every surface in this product — a parent-teacher conference evening, a picture-day morning, a facilities calendar, a crew dispatch board — runs the same four steps against the same engine. Learning it once is learning all of them.

The booking flow — four steps, the same four everywhere

Publish, book, guarantee, subscribe

  1. Step 1 — Publish availability

    A staff member, administrator, or studio owner publishes their availability: time windows, slot duration, and capacity per slot. For conferences, a teacher publishes their open hours. For picture day, the studio publishes session windows with per-slot capacity. For facilities, the booking administrator sets a resource’s available calendar. The availability is immediately visible as open-slot chips to whoever is entitled to book — not a public page, an authorized-only view.

  2. Step 2 — A family, lead, or staffer books an open slot

    A guardian opens the booking surface and sees open slots with real remaining capacity. They select a slot and confirm. The family wall holds throughout: the student ID comes from a hash-verified claim, not from the request body. A guardian may hold a slot for each of their claimed children independently — each child has their own claim and their own booking. For admissions tours, a prospective-family lead books through the same slot flow. For facilities, a booking-staff member reserves the room or field.

  3. Step 3 — The server guarantees capacity and no-double-book in one transaction

    The booking engine runs two server-side invariants in a single transaction: a SELECT … FOR UPDATE counts current live bookings against the slot capacity and rejects an over-capacity attempt before writing; a partial-unique index ensures no two live bookings share the same student and event. Both invariants are at the database, not in application-level conditional logic. A conflict returns a clean, retryable 409 with a machine reason (“already_booked” or “slot_full”) — never a 500, never a silent over-book.

  4. Step 4 — Subscribe to the .ics feed; reminders and fees queue against opt-in

    The confirmed booking appears in a subscribable .ics calendar feed with opaque labels: no student name, no teacher name, only a non-PII handle and timestamp. Staff see all appointments; a guardian sees only their own. Any reminder is queued against the family’s own channel opt-in — suppressed if the opt-in is absent. Nothing is sent through this surface. Any booking fee is a computed line, reserved in the ledger, never charged here. Both reminders and fees are honest-off: the infrastructure is in place, not enabled for live use today.

The reason the same four steps cover a conference evening and a field-service route is that there is only one availability engine underneath. A slot does not know whether it is a twenty-minute conference or a two-hour equipment reservation; it knows a window, a capacity and a rule about who may take it. Composition is what makes the surfaces different, not eight separate calendars that happen to look alike. You can read what each of those surfaces does on the surfaces page, and how the modules map across segments on the modules page.

The slot arithmetic — change a number and watch the day change

Four numbers decide the shape of a booking day. Here they are, live.

Every availability window in the product reduces to the same four inputs: how long the window is, how long one slot lasts, how many bookings a slot holds, and how much buffer sits between slots. Everything a scheduler feels difficult about — “can we get every family through in one evening?”, “is fifteen minutes enough?” — is that arithmetic, and it is worth being able to see it before anyone signs anything. Pick a combination below. The page recomputes on the server and the URL changes with it, so a grid you like is a link you can send to the person who has to approve it.

8:00am–8:20am4 bookings
8:20am–8:40am4 bookings
8:40am–9:00am4 bookings
9:00am–9:20am4 bookings
9:20am–9:40am4 bookings
9:40am–10:00am4 bookings
10:00am–10:20am4 bookings
10:20am–10:40am4 bookings
10:40am–11:00am4 bookings
11:00am–11:20am4 bookings
11:20am–11:40am4 bookings
11:40am–12:00pm4 bookings
12:00pm–12:20pm4 bookings
12:20pm–12:40pm4 bookings
12:40pm–1:00pm4 bookings
1:00pm–1:20pm4 bookings
1:20pm–1:40pm4 bookings
1:40pm–2:00pm4 bookings
2:00pm–2:20pm4 bookings
2:20pm–2:40pm4 bookings
2:40pm–3:00pm4 bookings
21Slots in the window
84Bookings the day holds
100%Of the window bookable
0Minutes left over

What you are looking at, stated precisely. This is arithmetic performed by the page you are reading, from the four values in the address bar. It is an illustration of the scheduling rules — it is not the booking engine, and it is not a recording of one. This marketing site holds no bookings, talks to no database, and has no account of yours to look up. A slot appears only when the whole slot fits inside the window: the leftover minutes at the end of the day are shown as leftover rather than rounded up into a slot that could not actually be sold. The concurrency guarantees described on this page — the partial-unique index, the capacity count under a lock — live in the product’s database, not here. We would rather show you the arithmetic we can honestly compute in a web page than stage a demonstration of a race we did not run.

The awkward questions — answered rather than avoided

What happens when it goes wrong

Scheduling software is judged on its bad days, not its good ones. Anyone can take a booking into an empty calendar. These are the six situations that decide whether a scheduler is worth running, and what this one does in each.

Two families click the last open slot at the same instant. What happens?
One booking is confirmed and the other is handed a clean, retryable conflict with a machine-readable reason — never a silent over-book, and never a 500. The reason it holds is that the check is not a conditional in application code that two threads can both pass: a partial-unique index makes a second live booking for the same student and event impossible at the database, and per-slot capacity is counted under a row lock inside the same transaction that writes the booking. The losing request gets told what happened and which slots are still open, which is a far better experience than the double-booked Tuesday you find out about on Tuesday.
A guardian cancels. Does the slot come back?
Immediately, and to everyone — the cancelled booking stops counting against capacity the moment it is cancelled, so the slot is re-bookable by the next family who looks. This is why the uniqueness constraint is a partial unique index rather than a plain one: it applies only to live bookings, so a cancelled row can sit in the table as history without blocking the seat it used to hold. A scheduler that makes you email the office to free a cancelled slot has quietly made cancellation expensive, and expensive cancellation is how a picture day ends up half-empty and fully booked at the same time.
A guardian has three children. Do they need three accounts?
No. A guardian holds a separate verified claim for each of their children, and each claim carries its own bookings. They can hold a conference slot for one child and a picture-day sitting for another without the system treating those as a conflict, because the uniqueness rule is scoped to a student and an event rather than to the adult doing the booking. What they cannot do is reach a child who is not theirs: the student identifier comes from a hash-verified server-side claim, never from anything the browser sent.
What does the family actually see? Is there a roster to browse?
There is no roster to browse, and that is a design decision rather than a permission setting. A guardian sees open slots and their own bookings. A cross-family or cross-school request returns the same uniform 404 as a path that does not exist, so the surface cannot be used as an oracle to test whether a given student is enrolled. Sign-up sheets that show you every other family’s name are a genuinely common pattern in school scheduling, and it is not one we were willing to copy.
Does subscribing to the calendar feed leak names into a personal calendar app?
No — the .ics feed carries opaque labels only. There is no student name and no teacher name in the SUMMARY or ORGANIZER fields, only a non-PII handle and a timestamp. This matters more than it first sounds: a calendar feed gets subscribed to on a personal phone, synced to a laptop, and occasionally shared with a spouse or an assistant, and every one of those hops is outside the school’s control. Staff see all appointments in their feed; a guardian sees only their own.
Do reminders go out? Are booking fees charged?
Neither, today, and we would rather say that plainly than leave it ambiguous. A reminder is queued against the family’s own channel opt-in and suppressed when that opt-in is absent — the queueing and suppression logic is built, and nothing is being sent through this surface. A booking fee is computed as a line and reserved in the ledger, and no money moves. Both are honest-off: the infrastructure exists, it is not enabled for live use, and this site has no checkout of any kind.

If the question you came with is not here, write to us — there is no form and no lead capture on that page, just an address and a plain description of who reads it. The privacy page covers what a booking record actually holds and what this product deliberately does not.