A headless booking platform for a luxury hotel, built around the limits of its PMS
Avenue Coral Gables
A custom Next.js and Sanity platform that replaces the rigid PMS booking widget for Avenue Coral Gables with a bespoke luxury interface, while keeping pricing, inventory, reservations and payments in sync with Cloudbeds.
Headless.
A booking journey that looks like the hotel, not like the PMS.
Room galleries, amenities and copy come from the CMS; live rates, inventory and reservations come from the PMS, merged on the fly.
High-resolution galleries, live availability.
Cloudbeds returns thumbnails and generic descriptions. The platform leads with the hotel’s own gallery and uses PMS images only as a fallback.

Custom booking and checkout
A fast React 19 interface with fluid motion, promo handling that tells the truth, and a partial-deposit checkout.
CMS-led control
Marketing and operations manage copy, galleries, promotions and tax rules in Sanity, with instant cache revalidation.
- Industry
- Luxury hospitality
- PMS
- Cloudbeds API v1.3
- CMS
- Sanity, GROQ
- Payments
- Cloudbeds SDK, Authorize.Net
The booking widget was the easy part to replace.
Going headless meant owning behaviour the PMS widget used to hide. Six limits of the API shaped the architecture.
Silent promo failures
Invalid codes return standard rates with no error.
Partial payments
A first-night deposit and a vaulted card had to land in the PMS folio.
Rigid tax model
Suite-specific fees and selective tax bases did not fit the PMS structure.
Occupancy truncation
Multi-room searches hid room types that could sleep the whole party.
Composite room IDs
Front-end keys like property-room caused authorisation errors in the API.
Thin room content
Low-resolution thumbnails and generic text fell short of a luxury brand.
Architecture
Next.js route handlers sit between the interface, the CMS and the PMS, each decision answering one specific limit of the PMS API.
Decision 01
The PMS silently ignores invalid promo codes.
Run two availability requests in parallel, one with the code and one without, then compare per-night rates and rate-plan names. A lower rate or an explicit promo rate plan returns applied; identical rates return invalid, so the interface can tell the guest instead of showing unchanged prices.
Architecture Narrative
A promo code enters the availability route, which runs a promo fetch and a baseline fetch in parallel. Both feed a per-night rate comparison, which returns a promo status of applied or invalid.
Architecture Narrative
A tokenized card is authorized for the deposit and logged to the Sanity audit ledger. The reservation is then posted. On success the deposit is captured and posted to the folio and the reservation is marked completed. On failure the card hold is voided.
Decision 02
A partial deposit and a vaulted card had to land in the PMS folio together.
Tokenize the card in the browser with the PMS payment SDK so card numbers never reach application servers, authorize the deposit, then post the reservation. Only after the reservation succeeds is the deposit captured and posted to the folio; if it fails, the hold is voided and the guest is not charged.
Decision 03
The PMS tax model could not express suite-specific fees.
Architecture Narrative
Cloudbeds taxes and fees flow through an automated sync route into Sanity site settings. The tax and fee engine combines those rules with the guest cart to produce suite-specific totals.
Move tax and fee rules into the CMS. Hotel managers set rates, bedroom-count rules and excluded fees in a custom Sanity Studio control, and a sync route imports baseline rates from the PMS so the two stay aligned.
Decision 04
Per-room occupancy checks hid room types that could sleep the whole party.
Search with a normalised occupancy of one adult to see all inventory, then split the real guest count across the selected cart lines when the reservation is posted, keeping each line within its capacity.
Architecture Narrative
A discovery query with one adult returns the full room inventory. Selected cart lines then receive a proportional split of the guests, which is sent with the reservation.
Content in one system, commerce in the other.
Sanity-first merging keeps the presentation luxurious. The PMS stays the system of record for everything that moves money.
Feature Showcase
High-resolution galleries and amenity copy from Sanity lead every room; PMS images are appended only as fallbacks.

- GalleriesCMS first, PMS fallback
- Searchlive rates + inventory
- Checkoutpartial deposit
Operations in the CMS
Managers control pricing rules, promotional copy and tax exclusions without a deployment, and new PMS room types appear as stubs ready for enrichment.

- Rulestaxes, fees, exclusions
- SyncPMS tax import route
- Roomsauto-created stub documents
What the platform makes possible.
A bespoke interface replaces the widget
The booking journey matches the hotel’s visual identity end to end.
Promo codes report their real effect
Guests are told when a code is invalid instead of seeing unchanged rates.
Partial payments with a vaulted card
The deposit posts to the folio and the balance stays due at check-in.
A failed reservation never charges the guest
Holds are voided automatically and every step is logged.
Staff manage rules and content themselves
Pricing rules, galleries and tax exclusions change without engineering.
The PMS limits no longer reach the guest
Promo, tax, occupancy and key issues are handled behind the interface.
A modern front end on a proven back office.
Decoupling lets each layer use the tool that suits it.
Experience
Server and client rendering with fluid motion.
Content
Structured content and custom Studio controls.
Hotel operations
System of record for rates, inventory and folios.
Media and quality
Rich media and tested pricing logic.
