Nowhere · Research brief

Acuity replacement UI · 13 August 2026

Can we build our own booking experience on top of Acuity?

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.

Research confidence: high for cart behavior and the documented API surface; medium for payments because the public API reference does not document a card-charge or hosted-checkout creation endpoint.

The direct answer about the widget

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.

Cart behavior, precisely

Customer actionWhat Acuity documentsWhat our UI should do
Same appointment type, same timeMultiple 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 typesClients 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.
ReschedulingRescheduling changes an existing appointment’s date/time. It is not new-booking cart behavior.Keep rescheduling as a separate flow.
Important distinction: this answer applies to the explicit “Select and add another time” action. A normal single-booking choice is still one appointment. The customer must enter the add-another-time path for the selection to become additive.

What the API gives us

Catalog

Appointment types and calendars

Read services/classes, duration, price, padding, type, and calendar IDs.

Availability

Dates, times, and validation

Read dates and times, then validate one or more requested slots before creating appointments.

Forms

Custom intake fields

Read assigned form fields, required status, types, and options, then send values with the appointment.

Booking

Appointment creation

Create the appointment with guest details, forms, add-ons, labels, and Acuity certificate codes.

Operations

Webhooks

Receive scheduled, changed, rescheduled, and canceled events. Acuity signs and retries webhook requests.

Server only

Credential boundary

The browser should call Nowhere. Only the server should hold the Acuity API credentials.

Where the hard parts are

Availability is validated, not held

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.

Multi-time carts are not atomic in the public API

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.

Payment is the biggest unknown. The reviewed public API documents appointment creation, certificates, forms, add-ons, and reading payment transactions. It does not document a public card-charge or hosted-checkout creation endpoint. Do not assume that an API-created appointment reproduces every payment behavior of the Acuity widget.

Do not reuse the staff admin route

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.

Why this fits Nowhere

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.

Already present

lib/acuity-appointments.ts, certificate handling, group-booking logic, webhook processing, raw/D1 sync, and staff appointment APIs.

New work

Customer service selection, time browsing, forms, review, certificate validation, safe public creation, idempotency, and payment strategy.

Three ways to approach it

Recommended

Thin custom scheduler

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.

More control

Custom scheduler plus our payment

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.

Not phase one

Replace Acuity entirely

Own availability, calendars, resources, forms, payments, reminders, calendar sync, cancellations, and migration.

Cost: this is a scheduling-platform project, not a widget replacement.

Suggested phase-one flow

  1. Choose a service. Show only the appointment types we intend to expose.
  2. Choose a time. Read live Acuity availability and refresh when the selection is stale.
  3. Enter guest details. Render the Acuity fields assigned to that appointment type.
  4. Validate a certificate. Check it against the appointment type and guest email when applicable.
  5. Review. Show date, time, calendar/location, duration, price, and certificate effect.
  6. Submit safely. Validate again, create the appointment, and handle a slot-race error without exposing API details.
  7. Reconcile. Use Acuity’s response and webhooks; keep a Nowhere booking-attempt record for support, not as a second availability source.

Recommendation

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.

Before implementation, confirm

Sources

  1. How clients book appointments — multiple spots, add-another-time, and the one-appointment-type transaction limit.
  2. Offering recurring appointments — previously selected times remain visible when adding another time.
  3. Let clients book multiple spots — quantity booking for one time slot.
  4. How to schedule with the API — the documented appointment-type, availability, and create flow.
  5. Availability dates, availability times, and check times — availability discovery and validation.
  6. Forms and create appointments — custom form rendering and appointment payloads.
  7. Appointment payments and webhooks — payment-history reads, signed events, and retries.