UCP Lodging Is Merged: What Changed on the Way to the Spec
On 24 September the Lodging Technical Council's PR #780 was merged into the Universal Commerce Protocol repository, and on 25 September the council announced it: dev.ucp.lodging.booking, plus a cancellation-policy extension, is now part of the spec as a draft.
It's the first capability from a vertical other than shopping to make it into the spec. Four weeks ago we read the PR as filed. This post covers what it looks like now, what changed in review, and what it still leaves to later.
What "merged" means here, and what it doesn't
The capability page opens with a banner:
This capability is in draft status. Implementers are cautioned that data models, protocol bindings, and operational flows are under active iteration and may undergo breaking changes as the specification evolves.
So be precise about where it stands:
- In the spec repository: yes. Schemas, REST and MCP bindings, and docs are published at ucp.dev/draft.
- In a release: no. The latest release is still v2026-08-25, which ships only
dev.ucp.shopping.*anddev.ucp.common.*. Shopping Tech Council minutes target the next release for early December 2026 or January 2027. They don't say whether lodging will be in it. - Stable: no. Two design questions were explicitly deferred to issue #858, and one of them is about naming.
The merge is still a milestone. A vertical has gone from a charter (June), to a council (August), to a merged spec (September) in three months, and it did so by building on the shared common/ layer instead of writing its own.
What merged
| Capability | dev.ucp.lodging.booking |
| Extension | dev.ucp.lodging.policy.cancellation |
| Operations | create, get, update, complete and cancel_booking_session |
| Transports | REST (OpenAPI) and MCP (OpenRPC) |
| Size | 35 files, about 6,000 added lines |
Reused from common/ |
payment terms, split payments, payment authentication (3DS), AP2 mandates, totals, policies, messages, actions |
New in common/ |
a date_interval type and a totals_changed warning |
The flow will be familiar to anyone who has implemented checkout. A platform opens a booking session using the property, stay, rate plan and dates it found upstream. It adds guest and payment details over one or more updates. When the session reaches ready_for_complete, it completes it to create a confirmed reservation. The status values match checkout's, including requires_escalation with a continue_url for handing off to a human.
The business stays merchant of record. It doesn't need to become PCI DSS compliant to accept cards this way. And unless the AP2 mandates extension is in play, the spec says the user finalises the booking in a trusted UI: the agent prepares the booking, and a person confirms it.
Five things that changed in review
The version that merged isn't the one filed on 28 August. The review was long and public, and some of what changed matters beyond lodging.
1. Rooms became stays
The filed draft talked about hotel rooms: room_rates[], room_details, itinerary. The merged schema is generic: a property, one or more stays[], each binding an accommodation_type, a rate_plan, stay_dates and occupancy. The compound binding we highlighted last time is still the heart of it; only the vocabulary moved away from hotels. The same schema can now describe a villa, a cabin or a campsite pitch as well as a hotel room.
It doesn't yet say which of those a stay is. Whether to add an explicit accommodation type, and how strict to make it, is the first question in #858. That issue's example is a hotel needing a check-in desk while a vacation rental needs lockbox details.
2. Totals mean price; payment terms mean timing
This is the most important change, and it came from reviewers checking the arithmetic. Early drafts gave lodging its own meaning for the total, the amount due now, with extra types for money due at the property and later. That clashed with UCP's shared totals type, where total is the grand total everywhere else: in cart, checkout and order. It also made a stay paid entirely at the property awkward to express.
The merged version separates the two questions. totals describes what the stay costs. When it's paid goes in payment terms: each term has schedules[], which can be immediate, deferred or at_property, and the schedules in the selected term MUST add up to the total. The total itself is the all-in cost of the stay, and the spec says the guest MUST see it before the booking is confirmed. A deposit today and the balance at check-in is now two schedule entries against one total, not two totals.
For anyone checking conformance, this is the best kind of rule: one a machine can verify.
3. Payment at completion, even when nothing is charged
payment is required when a booking completes. But for a pay-at-property or deferred reservation with no card guarantee, an empty payment: {} satisfies it. The payment term is chosen during update, not at completion, because choosing a term can change the price, and the price has to be settled before the session can be ready_for_complete.
4. Guests are private until the booking needs them
The booker, who contracts and pays, is still separate from the guests who stay. Guest IDs are minted by the platform, scoped to one booking session, and MUST NOT carry personal data or cross-merchant tracking identifiers. Businesses MUST NOT link guests across sessions. Platforms SHOULD NOT send guest identity beyond the ID until the booking reaches ready_for_complete, and then only the fields the business asks for. Guest roles are now primary and accompanying.
5. expires_at became a price-hold promise
The session's expires_at now covers "session state, quoted pricing, and any temporary inventory holds". Its description carries a rule we've wanted since our expiring-inventory study: businesses MUST NOT complete a booking at a changed price without first returning updated totals to the platform. It doesn't make agents check the clock, but a silent price change at completion is no longer allowed.
One thing that deliberately didn't change
Shopping names its tools with short verb-noun pairs like create_checkout and cancel_checkout. Lodging kept a _session suffix: create_booking_session, cancel_booking_session. The council's reason is agent safety. In hotels, "booking" means both a draft in progress and a confirmed reservation. A tool called cancel_booking invites an agent to confuse throwing away a draft with cancelling a non-refundable stay.
A reviewer asked for consistency with shopping. The council kept the suffix and moved the question to #858, where it will be settled before the naming is frozen. Anyone implementing now should expect these names might change.
What we said in May, and what the draft does
When Google opened its lodging waitlist in May, we listed what UCP for Lodging would need to specify and promised a side-by-side when the spec landed. Here it is against the merged draft:
| We said it needed | The merged draft |
|---|---|
| An offer that binds room type, rate plan, dates and occupancy | Yes. A stay binds accommodation_type, rate_plan, stay_dates and occupancy. |
| An all-in total, taxes and fees included | Yes. total is the all-in cost of the stay, and the guest must see it before confirming. |
| A clock on the offer | In part. expires_at holds the quoted price inside a session. How long a rate from search stays valid is out of scope. |
| Re-validation before booking | Yes. The session is authoritative, and a business can't complete at a changed price without returning updated totals first. |
| Machine-readable cancellation | In part. Refundability is structured; cutoffs and penalties are still text. |
| Servicing: modify, cancel, no-show | Not yet. Left to future post-purchase order extensions. |
| Identity, loyalty and payment timing | Mostly. Deposits, balances and pay-at-property are payment-terms schedules. Identity linking and loyalty already exist in common/; the charter puts account linking and loyalty in Phase 1.5. |
A spec can't answer one thing on that list: whether agents use what it gives them. Our expiring-inventory study found frontier models didn't check an offer's clock. expires_at gives them one to check. Whether they do is something we'll only see once live endpoints exist.
What it leaves for later
The draft is scoped as the booking core, and the PR says so. Out of scope:
- Discovery and search. The session starts from rates found "upper-funnel". How a platform finds them isn't specified.
- Offer binding and quote lifetimes before a session exists. A rate seen in search is provisional; only the booking session is authoritative. The council said in review that these are for later.
- Managing a reservation after booking. Modifications, cancellations and check-in are left to future post-purchase order extensions.
- Booking on behalf of someone else. Dedicated fields for travel agencies, or for occupants who aren't people, beyond the standard booker and guest.
- Deterministic cancellation schedules. The extension classifies a policy as
refundable,partially_refundableornon_refundable, with a description that MUST NOT contradict it. Cutoffs, penalty tiers and no-show outcomes are still text. A separate open proposal would make them structured. It was filed as #808 against the lodging branch and re-filed as #861 after the merge.
Disclosure: we're running an independent lab study of how agents handle cancellation terms, using test fixtures published by that proposal's author. This post takes no position on that proposal; it's the Lodging Technical Council's call.
Who built it
The announcement credits the Lodging Technical Council, whose inaugural members are Amadeus, Booking.com, Expedia, Google, Hilton, Marriott and Trip.com, along with open-source contributors. The review drew in reviewers from outside the council too: Shopify's Ilya Grigorik (per his GitHub profile) requested changes on 10 September and approved on 24 September, hours before the merge. A new vertical has to fit the shared spine, and this review is where that was worked out.
What this means if you build for lodging
- Hotels and booking engines: there's now a concrete target to prototype against. Treat it as a draft: build against a pinned commit, keep your own namespace for anything the draft doesn't cover, and expect naming changes from #858. Getting totals right is the easiest thing to do now. Make sure your deposits and balances are schedules that add up to a total, not separate totals.
- Agent builders: the
_sessionnames and theexpires_atprice rule are both there for your benefit. Take advantage of them. Re-read totals after every update, and treat atotals_changedwarning as something to show the traveller, not to swallow. - Anyone building checkout-based lodging today: the council's answer in the review was direct:
dev.ucp.shopping.checkout"holds no architectural promise or semantic support for lodging concepts". The lodging capability is where hotel bookings are meant to live.
What we'll do
We track the vertical on our UCP for Lodging page, which is updated for the merge. When a business first declares dev.ucp.lodging.booking in a live manifest, we'll say so. We'll validate declarations against the spec once it's in a release. Until then, a declaration is a declaration against a draft.
If you're shipping lodging endpoints early and want to know how they look from outside, run them through the validator.
About UCP Checker
UCP Checker is the independent validation and observability layer for the Universal Commerce Protocol. We crawl, validate and grade every public UCP manifest we can find, run the merchant directory, the UCP Score, live adoption stats, the vertical guides and the authority-bound vendor map, and track the spec as it evolves so you don't have to — measured from two vantages (what a business declares, and what actually happens when an agent transacts), the same way for everyone, without picking winners.
Sources
- Announcing UCP Lodging: Booking Capability Draft Spec Release, UCP announcements, 25 September 2026
- PR #780: Introduce Lodging Booking Capability and Cancellation Policy Extension, merged 24 September 2026
- Lodging Booking capability (draft), ucp.dev
- Issue #858: Design TODOs from Lodging Booking Capability (#780)
- PR #861: Add deterministic schedules to lodging cancellation policies (open; re-filed from #808)
- Shopping Tech Council minutes, 4 September 2026
- UCP release v2026-08-25
- Issue #543: DTC Charter: Lodging
Check your domain's UCP status
See if your storefront is ready for agentic commerce in seconds.
Get the agentic commerce digest every Monday
Real adoption data, ecosystem trends, new spec versions, and the stores that broke or recovered this week. Read by founders and engineers building the next generation of commerce.

