Skip to main content
DoneThat

AI Adoption GuideHospitalityBook

Competitor rate intelligence

Automated scraping plus LLM summary of comp set pricing produces a daily rate briefing for revenue teams.

Hospitality processBookConfirmPrepareArriveStayDepartReviewReturn

By Don, DoneThat’s AI coach · updated

A briefing line is only usable when it names property, stay date, and vintage

A competitor rate you cannot cite is not a briefing. It is a rumor. The daily artifact a revenue manager needs is a set of observations from a licensed shop: which competitor property, which stay date, what the shop returned, and when that return was captured. If the feed is missing, the cell stays blank. Nobody invents a competitor rate. The manager still sets the hotel's own rate.

Quality here is citation, not completeness. A usable line names the competitor property, the stay date (and length of stay if the shop returned it), the rate product the shopper was asked to collect, the amount if one arrived, and the rate-source vintage: shop timestamp plus the licensed feed or approved shopper that produced it. Drop vintage and the number cannot be defended in a rate meeting. Drop the property or the stay date and it cannot be mapped to a night you actually sell.

This briefing sits beside the hotel's own pricing stack. Property and revenue platforms such as Duetto, IDeaS, Oracle Hospitality, and Mews already hold BAR, restrictions, and inventory. Comp-set shops are a separate licensed input. They do not replace dynamic demand-based pricing. They tell you what the locked set showed on a given vintage, so demand logic is not arguing with an unattributed screenshot.

Freeze the competitive set before the first shop

Lock the competitive set in writing before any shop runs. Name each competitor property the way the licensed feed identifies it. Record the channel and rate product you intend to compare (for example public BAR on the same length of stay you sell as your lead-in). Record who may add or remove a hotel, and how often that list is allowed to change.

An unlocked set produces noise. A suburban limited-service hotel that appears in one night's shop and vanishes the next is not a peer. It is a feed artifact. If last week's set included an airport property and this week's set swapped it for a resort, a "moved with the market" reading is comparing two different markets. The briefing should show the set ID and the date that set was frozen so a manager can see whether today's lines are comparable to yesterday's.

Stay dates on the shop request must match the dates the hotel is pricing. Shopping tonight for a Saturday arrival three weeks out, then applying that number to a Tuesday next week, is not competitor intelligence. Length of stay, party composition of the shop (adults, children, rooms), and refundability all change what a licensed shopper returns. Those parameters belong on the briefing header, not in a footnote someone reads after they have already moved a rate.

Ingest licensed shops, attach vintage, and refuse unlabeled rates

Load only a licensed rate-shopping feed or an approved shopper the hotel has contracted. The job is to attach vintage to every returned amount, then refuse anything that arrives without it.

Vintage is the shop's clock, not the manager's memory. A line that says "Competitor A, 12 September, 189" with no shop time and no feed name cannot be used. It might be this morning's public BAR. It might be yesterday's mobile-only rate. It might be a cached package. Without vintage, treat the amount as missing. Do not backfill from last week's file, from a colleague's recollection, or from a public website visited outside the approved shopper.

The ingest step is mechanical. Map each competitor in the frozen set to the feed's property identifier. Request the stay dates and rate product you locked. Store the raw return, the feed name, and the shop timestamp. Normalize currency and taxes the way your own BAR is expressed, and record that convention on the line. If the feed returns no rate, write nothing in the amount field. If the feed returns a rate with a broken or empty timestamp, discard the amount and leave the line blank. A rate with no source vintage is a failure mode, not a near miss.

Summarization, if you use a language model at all, may only restate fields that already exist: property, stay date, amount, vintage, and any restriction the feed actually returned. It may not interpolate a missing competitor, round a blank into a "likely" figure, or borrow a sister-property rate. Empty stays empty.

One stay night with a cited rate and a blank

Consider a Wednesday briefing for Friday 18 October, one night, public BAR, two adults, refundable, shopped through the hotel's licensed feed at 06:10 local time.

The frozen set has four hotels. The feed returns 214 for Harbor Court with vintage 06:10 and feed identifier SHOP-LIC-04. It returns 198 for River Park with the same vintage. It returns no row for Station Inn. It returns 205 for Dockside with an empty shop timestamp.

The briefing prints two usable lines:

  • Harbor Court, 18 Oct, public BAR one night, 214, vintage 06:10 from SHOP-LIC-04
  • River Park, 18 Oct, public BAR one night, 198, vintage 06:10 from SHOP-LIC-04

Station Inn stays blank. There is no licensed observation, so there is no number. Dockside also stays blank. An amount without source vintage is not entered, not footnoted as "205 unverified," and not averaged with Harbor Court. The manager sees two cited peers and two empty cells. That is a complete briefing for those four properties.

The manager does not owe the market a reaction. Harbor Court may be holding a group wash. River Park may have opened a discount the feed labeled as BAR. The hotel's own pickup, remaining capacity, and overbooking risk scorer output still belong in the same morning pass. The briefing only answered what the licensed shop returned, for whom, for which night, and when.

The manager sets BAR; the briefing does not

Treating the briefing as a published BAR is the second failure mode that wrecks quality. The briefing is an observation log. Publishing the midpoint of two cited competitors, or matching Harbor Court because the cell was filled, turns a shop into a rate strategy the hotel never chose. Restrictions, closed-to-arrival flags, and package fences on the hotel's own side still live in the PMS and RMS. The briefing does not write those systems.

The third failure mode is inventing a competitor rate when the cell is empty. Filling Station Inn from last Friday, from Dockside's unlabeled 205, or from a walk-by of the brand.com calendar is fabrication. It trains the next briefing to look complete when it is not. It also poisons any later comparison of whether the hotel "followed the set," because the set was never fully observed.

Use the briefing as one input among others. If cited peers are lower on a stay date where your own demand signals are soft, the manager may lower BAR, hold, or tighten restrictions. If peers are higher, the manager may raise, or may not, if guest segment intent classifier output says the remaining demand is a contracted negotiated rate that will not see public BAR. If a shop shows a competitor open while your own site is leaking abandoned carts, send that problem to booking abandonment recovery. Do not fix it by copying an uncited competitor number.

Hand-off is a sentence, not a file dump: which stay dates had cited observations, which competitors were blank and why (no feed row versus unlabeled vintage), and that BAR was left unchanged unless the manager recorded a decision. Quality is a briefing line that a second person can audit against the licensed shop. If they cannot, the line should have been empty.

Is this worth automating for you?

Whether this pays back depends on how much time it takes your team today. Most teams estimate that from memory, and the estimate is usually wrong in one direction or the other.

DoneThat reconstructs where the time actually went, with no timers to forget, so you can measure the baseline before committing to a project and check the gain afterward.

Measure the baseline first