Appointment types and calendars
Read services/classes, duration, price, padding, type, and calendar IDs.
Acuity replacement UI · 13 August 2026
Yes for phase one. Keep Acuity as the system of record, put a branded Nowhere experience in front of it, and let our server mediate availability, forms, certificates, and appointment creation.
Acuity does not limit a customer to one time slot. It supports multiple spots in the same slot when quantity booking is enabled, and it supports adding another time for the same appointment type. When the customer uses “add another time,” Acuity says the previously selected times remain visible. A different time therefore appends; it does not remove the earlier selection.
| Customer action | What Acuity documents | What our UI should do |
|---|---|---|
| Same appointment type, same time | Multiple spots are possible when the account enables per-slot capacity and a quantity field. | Model as quantity or attendees, not as an unrelated second service. |
| Same appointment type, different time | “Add another time” keeps the earlier selected times visible while the customer chooses another start time. | Append the new slot. Do not silently replace the first slot. |
| Different appointment types | Clients cannot choose multiple appointment types in one Acuity transaction. | Keep phase one to one appointment type per checkout unless we deliberately own the extra complexity. |
| Rescheduling | Rescheduling changes an existing appointment’s date/time. It is not new-booking cart behavior. | Keep rescheduling as a separate flow. |
Read services/classes, duration, price, padding, type, and calendar IDs.
Read dates and times, then validate one or more requested slots before creating appointments.
Read assigned form fields, required status, types, and options, then send values with the appointment.
Create the appointment with guest details, forms, add-ons, labels, and Acuity certificate codes.
Receive scheduled, changed, rescheduled, and canceled events. Acuity signs and retries webhook requests.
The browser should call Nowhere. Only the server should hold the Acuity API credentials.
The reviewed API reference documents reading and validating slots, but not a temporary reservation or hold. A slot can disappear between display and submit. The final create call must be treated as the race check, with a clear “that time was just taken” recovery path.
The documented create endpoint creates one appointment per request. If our cart contains two times, we need multiple creates and an explicit partial-failure policy. For a first release, one appointment per checkout is safer. Add same-type multi-time carts after a tested compensation flow exists.
The current Nowhere staff create path uses admin=true, which Acuity documents as disabling availability and attribute validation. Public booking needs client-style validation or an equivalent server-side guard.
The repo already has much of the backend foundation: Acuity wrappers for appointment types, calendars, add-ons, creation, rescheduling, cancellation, certificate lookup, group-booking helpers, and webhook synchronization. The missing layer is a customer-facing flow plus a narrowly scoped public server route. We do not need to build a second availability database.
lib/acuity-appointments.ts, certificate handling, group-booking logic, webhook processing, raw/D1 sync, and staff appointment APIs.
Customer service selection, time browsing, forms, review, certificate validation, safe public creation, idempotency, and payment strategy.
Keep Acuity authoritative. Build the Nowhere customer experience and start with one appointment per checkout, especially for certificate-backed bookings.
Best trade-off: branded UX without duplicating the scheduling engine.
Own the full customer flow and charge through a payment processor we control, then create the Acuity appointment.
Cost: payment-before-booking failures, refunds, idempotency, and paid-state consistency become ours.
Own availability, calendars, resources, forms, payments, reminders, calendar sync, cancellations, and migration.
Cost: this is a scheduling-platform project, not a widget replacement.
Build a proof of concept for one certificate-backed appointment type and one appointment per checkout. Keep Acuity as the source of truth, put the API behind a Nowhere server route, and do not use admin=true for public bookings.
Once that path is reliable, add a same-type “add another time” cart. It is supported by Acuity’s documented widget behavior, but the custom implementation must solve multi-create consistency and payment behavior itself.