---
title: "Search a hotel's guest reviews"
method: GET
path: "/v1/hotels/{hotelId}/reviews"
tags: ["Hotels"]
---

# Search a hotel's guest reviews

`GET /v1/hotels/{hotelId}/reviews`

Guest reviews for a hotel, newest first: rating, pros, cons and the provider. Filter by topic with ?topics=breakfast,pool and by cohort with ?guest-type=. Quote a review against metadata.totalCandidates, and cite metadata.matchedTerms for the word actually matched.

## Path parameters

- `hotelId` integer, required

## Query parameters

- `page` integer
- `pageSize` integer
- `sort` 'posted_at_desc' | 'rating_desc' | 'rating_asc'
- `locale` string
- `topics` string[]
- `guest-type` 'couple' | 'family_with_children' | 'solo_traveller' | 'extended_group'
- `view` 'default' | 'detail'

## Response `200`

One page of guest reviews.

- object
  - `hotelId` number, required — The hotel these reviews are for.
  - `metadata` object, required — Pagination and the matched-topic accounting for this reviews read.
    - `page` integer, required — 1-based page number of this read.
    - `pageSize` integer, required — Reviews requested per page.
    - `resultCount` integer, required — Reviews on this page.
    - `totalCandidates` integer — Reviews matching this read's filters across ALL pages – the denominator to quote a review against ('15 of 141'). It is the FILTERED total, so an unfiltered read is needed to state the hotel's full review count. EXACT only when hasMore is false: when hasMore is true this can be a LOWER BOUND, because an upstream page that carries no count of its own falls back to the offset plus the rows it sent, so quote it as 'at least N'. ABSENT when this read establishes no total at all – an empty page past the first whose upstream sent no count says nothing about the pages before it. Absent means UNKNOWN, never zero: re-read page 1 before reporting any number.
    - `hasMore` boolean, required — Another page may follow. A full page always sets this, count or no count. While it is true, read totalCandidates as a floor rather than a corpus size.
    - `topics` string[], required — The topic terms this read asked for.
    - `matchedTerms` string[], required — The term variants the upstream actually matched (e.g. breakfast, Breakfast). Empty on an unfiltered read. Cite from here rather than from topics, so a quote states the word that was really found.
  - `results` object[], required — The requested page of guest reviews.
    - `rating` number, required — The provider's own 0–10 rating for this review, passed through.
    - `title` string — Review title, when the guest gave one.
    - `postedAt` string, required — Calendar date (YYYY-MM-DD).
    - `providerCode` string, required — Which provider collected the review (e.g. booking.com).
    - `guestType` 'couple' | 'family_with_children' | 'solo_traveller' | 'extended_group' — The reviewer's cohort, normalized onto the closed set. Omitted when the upstream sent a value outside it.
    - `pros` string[], required — What the guest liked, verbatim.
    - `cons` string[], required — What the guest disliked, verbatim.
    - `notes` string[] — view=detail only – review prose the provider tagged neither positive nor negative.
    - `countryCode` string — view=detail only – the reviewer's country code. The reviewer's name is never returned.

## Other responses

- `400` — Invalid request parameters.
- `401` — Missing or invalid bearer token.
- `404` — Unknown hotel.
- `429` — Rate limit exceeded; retry after the `Retry-After` seconds.
- `502` — The upstream hotels service returned an invalid response.
- `503` — The hotels service is unavailable (`upstream_unavailable`) or rate-limited upstream (`upstream_rate_limited`); retry after the `Retry-After` seconds.

---

[API](https://skmtc.net/wego/apis/wego-api.md) · [All operations](https://skmtc.net/wego/apis/wego-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/wego/wego-api/revisions/e5d7af502419/schema)
