First Class Modules
Reservations
Turns a bookable product purchase into one secured workflow: contact identity, capacity-protected reservation, protected charge, calendar event, tenant-user assignment, resource booking, and scheduled before/after-service follow-up.
module.reservationsUse Reservations for appointments, classes, tours, consultations, rentals, services, and other products that must be paid for, placed on a calendar, assigned to a tenant user, connected to a customer contact, and followed up consistently.
The bundled renderer key is module.reservations. First-class means BuildWithHQ supplies a native, typed, secured runtime experience inside normal app provisioning and the signed-in user's existing permissions.
What it does
Turns a bookable product purchase into one secured workflow: contact identity, capacity-protected reservation, protected charge, calendar event, tenant-user assignment, resource booking, and scheduled before/after-service follow-up.
Key capabilities
- Define bookable products with duration, price/currency, party limits, concurrent capacity, buffers, hold time, and default location, resource, assignee, and follow-up timing.
- Create or safely reuse an authorized Contact and preserve the purchaser's name, email, phone, and notes.
- Create a capacity-protected Reservation and linked Calendar event, with an optional Resource booking and an active tenant user assigned to deliver the service.
- Queue the existing idempotent charge-intent pipeline using a protected payment-method reference; the API never receives card numbers, security codes, processor credentials, or raw payment tokens.
- Keep paid bookings pending and private until the charge worker reports success, then promote the reservation, event, resource, and follow-ups transactionally.
- Track Pending Payment, Requires Action, Confirmed, Checked In, Completed, Cancelled, No Show, and Payment Failed with optimistic concurrency and an audit timeline.
- Schedule separate pre-service and post-service follow-up date/time, recipient email, subject, message, delivery state, attempts, sent time, and outbound-message reference.
- Use idempotency keys to make checkout retries safe and prevent duplicate contacts, charges, calendar events, and reservations.
- Let the tenant account owner choose disabled, optional, or required collection; creation, manual, or completion timing; full or deposit collection; partial-payment rules; currency; minimum charge; and paid-before-completion enforcement.
- Give users with the existing billing capability a secured balance, payment history, charge history, and protected charge action for the reservation record.
Reservation purchase flow
| Step | Canonical result | Important behavior |
|---|---|---|
| Choose product and time | Product + UTC window | Duration, buffers, party size, location, and capacity are validated inside the transaction. |
| Identify customer | Contact | An authorized exact email match may be reused; otherwise one Contact is created and linked. |
| Reserve service | Reservation + Calendar event + optional Resource booking | A paid event stays a private payment hold until the charge succeeds. |
| Charge | Billing charge intent | The existing worker uses a protected method; retries use the same idempotency key. |
| Confirm and serve | Lifecycle + audit events | Calendar, resource, and follow-up state remains synchronized. |
| Follow up | PreService and PostService jobs | Each has its own time, email, message, attempts, result, and evidence. |
Tenant API
GET/POST /api/modules/reservations/productslists and manages the catalog.GET /api/modules/reservationslists a secured schedule window;GET /api/modules/reservations/{recordId}returns detail and history.POST /api/modules/reservations/purchaseperforms idempotent contact, calendar, reservation, and charge orchestration.PUT /api/modules/reservations/{recordId}/statusapplies a lifecycle transition.PUT /api/modules/reservations/{recordId}/followupscreates or reschedules a before/after-service follow-up.GET/PUT /api/modules/payments/settingsreads or changes the tenant-owned Reservations and Work Orders policies.GET /api/modules/payments/records/{recordId}returns the secured balance/history;POST /api/modules/payments/records/{recordId}/chargesqueues an idempotent protected charge.GET /api/modules/payments/methodslists display-only metadata for active consented methods; connector endpoints accept external secret references, never reusable credentials.
Common uses
- Paid consultations and professional-service appointments.
- Tours, classes, lessons, events, and capacity-limited sessions.
- Installations, inspections, salon/wellness visits, rentals, and service calls.
- Free appointments that still need contact, calendar, assignment, capacity, and follow-up.
How it connects
Reservations reuse Contacts, Calendar, Resources, the billing charge-intent/payment ledger, Record Relations, and the communications worker boundary. The Reservation owns lifecycle; payment, contact, calendar, and message records remain canonical and linked instead of copied into a shadow subsystem.
Where applicable, its records use the universal RecordId conventions so they can participate in secured relationships, activity history, favorites, dynamic fields, notifications, Inbox attention, and global search without copying the source record.
Security and data boundary
List/detail access is inherited from secured universal Records. Product management and mutations require current DataRole capability. Locations and contact targets are revalidated in the user's scope, assignees must be active tenant users, capacity is fenced transactionally, and identity comes from verified server context. The tenant account owner controls payment policy and connector references; collection requires the existing CanBillRecords capability plus record scope. Raw card data and provider credentials are never accepted or persisted by Reservations.
- The authenticated service derives the SaaS app, tenant account, user, DataRole, and location scope; browser identifiers are never authorization proof.
- The page editor composes React components with validated data bindings. Those bindings call typed runtime APIs, whose application services execute reviewed stored procedures.
- List, search, detail, relation, activity, favorite, and write operations reapply their required server-side permissions.
Add it to an app
- As the tenant account owner, configure an external payment-connector secret reference and choose separate Reservations and Work Orders collection policies; never add card fields to a page.
- Add
module.reservationsto an in-SaaS page and place that shared page in each intended user-type menu. - Create each product with duration, price, capacity/party rules, buffer, hold, location/resource/assignee, and follow-up timing.
- Grant existing DataRole,
CanBillRecords, and location access to users who may view, collect, sell, assign, check in, complete, cancel, or follow up. - Exercise free, disabled, optional, required, deposit, manual, and paid-before-completion paths plus idempotent replay, full capacity, payment success/failure/Requires Action, calendar/resource synchronization, and both follow-ups before publishing.
Start with one product and one assigned team. Decide whether capacity counts people or simultaneous services, set realistic buffers and hold time, configure payment separately, and test duplicate checkout, payment failure, Requires Action, cancellation, no-show, and both follow-ups.
A renderer being bundled in the tenant application does not make its data visible in every app. The server returns only components and records authorized for the current app and signed-in user; unavailable or unauthorized blocks fail closed.