Skip to main content
DoneThat

AI Adoption GuideHospitalityStay

Mid-stay complaint predictor

Monitors housekeeping ratings, app interactions, and service requests to flag at-risk guests before dissatisfaction escalates.

Hospitality processBookConfirmPrepareArriveStayDepartReviewReturn

By Don, DoneThat’s AI coach · updated

An at-risk flag is only useful when it cites a live stay signal

The quality outcome is a stay-level at-risk flag that names the housekeeping rating, app interaction, or service request that triggered it. Guest services then contacts the guest. The model does not issue a compensation, does not write a review score, and does not invent a reason when those three signals are silent.

A flag without a cite is not a quality outcome. The duty manager and the guest-services desk cannot act if they cannot open the same housekeeping note, app event, or request the model saw. If the cite is missing, suppress the flag.

This job covers the occupied window, not post-checkout reputation. Public reviews belong on a different queue, the review alert monitor. Mixing those jobs is how teams start treating a mid-stay model as a star-rating engine.

Load housekeeping ratings, app interactions, and service requests for the current stay

Pull signals for the current confirmation only. Do not roll in last year's folio, a past stay's minibar dispute, or another room on the same reservation if that room is not occupied by this guest.

Housekeeping ratings are in-stay cleanliness and readiness scores or comments already stored against this room and this date: inspection grades, guest-facing room-condition taps, or attendant notes. Load the timestamp, the room, and the verbatim rating or comment. Do not convert that record into a public review.

App interactions are in-stay product events that show friction: repeated opens of a room-issue path, abandoned steps after arrival, multiple taps on housekeeping or maintenance without a completed request. Load the event name, timestamp, and stay id. Preference taps that only describe pillows or temperature belong with guest preference-based room setup. They are not complaint evidence unless the guest is also reporting that the room was not set that way.

Service requests are tickets opened during the stay. Load the request type, open time, status, and room. Assignment is a separate job; use the in-room service request router for that. This predictor only needs to know that a request exists, is aging, or was reopened.

Property systems that already hold some of this, PMS, CRM, and guest-messaging suites in the same class as Oracle Hospitality, Mews, Revinate, and TrustYou, are sources, not the model. Map stay id, room, and timestamp. Do not assume a named feature exists in any one of them. If a source cannot return a housekeeping rating, an app event, or a request for this stay, treat that source as silent. Join on stay id and occupancy window. Drop events after checkout and before arrival.

Cite the signal on the flag, or do not raise the flag

A valid flag is a structured record: stay id, room, occupancy dates, at-risk true, and at least one cite. Each cite is a pointer the desk can open: housekeeping rating id plus the rating text or grade; app event id plus event name and time; or service request id plus type and status.

One cite is enough. Do not average them into a score. Do not output a likely star rating. There is no review score in this job's output.

If the model wants to flag and cannot attach a cite, the answer is no flag. That is the first failure mode: a red badge with an empty reason field. Treat cite-less flags as wrong in training and in the daily review.

Thresholds belong to the property. Cite-worthy patterns are local rules: a housekeeping inspection the property itself marked below its own pass line for this room today; an app path that opened a complaint or maintenance flow twice without a closed ticket; a service request still open past the property's own SLA, or reopened after a resolved close. Write those rules in the property's language. Do not import a review-site rubric. When a request is the cite, pass the request id through so guest services sees the same ticket the engineer sees.

Leave the stay empty when those three signals are silent

If housekeeping has not rated this room during this stay, the app has no in-stay events for this guest, and no service request is open or recently closed, the stay stays empty. Empty means at-risk is unset or false, the cite list is empty, and there is no narrative paragraph.

The second failure mode is inventing a review score to fill the blank: no signals, but a guessed rating or a watch-this-profile score. That is a fabricated review, not a quality outcome. Loyalty tier, rate code, and length of stay are not substitutes for the three signals. They can sit on the guest-services screen as context after a real flag. They cannot create the flag.

Silence is not satisfaction proof, and it is not dissatisfaction proof. This job only speaks when one of the three sources speaks. Do not backfill from post-stay surveys that have not been submitted yet, and do not pull OTAs mid-stay to mint a score. If a review appears before checkout, that is the review-alert job.

Guest services contacts the guest; the flag is not a compensation

The workflow after a valid flag is contact, not cash. Guest services, or the duty manager if that role owns in-stay recovery, reaches the guest on the channel the property already uses: in-app message, room phone, SMS if consented, or a knock when that is the house rule.

The agent opens the cite first, confirms the housekeeping note, the app event, or the request is still true, then asks what would make the rest of the stay work. They may offer a room move, a repair ETA, or a late checkout if policy allows. Those offers are human decisions.

The third failure mode is treating the flag as an auto-comp: a rule that posts a folio credit, a voucher, or a points dump whenever at-risk is true. That spends budget on stays that needed a plumber and surprises finance. Keep compensation in the same approval path you use for any other recovery. The flag is an attention ticket.

If the guest already filed a request, do not open a second mystery ticket. Join the conversation to the existing request. After contact, log the outcome on the stay: reached, no answer, or already resolved. That log is operations, not a review score. If the same stay later produces a written complaint, send the text to the complaint root-cause classifier instead of stretching this predictor into a taxonomy engine. A cleared flag does not mean the guest was paid. It means someone spoke to them about the cited signal.

One occupied room, from signal to contact

A guest is two nights into a four-night stay. Morning housekeeping marks the room below the property's own inspection pass for hair in the bath and a wet floor. Yesterday the guest opened a service request for extra towels that still shows open. The app shows one more event: they opened the room-issue flow after the inspection note landed, then backed out without submitting a second ticket.

The model should flag the stay and cite all three: the housekeeping inspection id and the attendant's note, the open towel request id and its age, and the app room-issue event time. It should not emit a star rating. It should not post a credit.

Guest services reads the cites, calls the room, and learns the wet floor is the real problem and the towels were a workaround. They dispatch housekeeping, keep the original request tied to the room, and leave compensation untriggered unless a manager later decides it. If that same stay had had no inspection note, no request, and no app events, the model would have returned empty. If the only input had been a loyalty tier and a long stay, a flag would have been a cite-less failure. If the desk had auto-comped on the flag without reading the wet-floor note, they would have paid for a problem that needed a mop.

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. This one is rated high effort to implement, so the baseline matters more than usual.

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