Skip to content
Dashboard

Reviews

A review is a guest’s rating of a stay: one you collected through a guest-portal survey, or one SuiteOp synced from a channel through your PMS. The API has one review operation, getReview. It is designed to be used with the review.submitted webhook: the delivery tells you a review arrived and carries its id, and getReview re-reads it whenever you need it again. There is no operation to list, create, edit or reply to reviews.

OperationRequestPermission
getReviewGET /reviews/{id}view_reservations

Paths are relative to your region’s base URL, for example https://api-us.suiteop.com/api/v1. See Authentication for permissions.

Terminal window
curl "https://api-us.suiteop.com/api/v1/reviews/7c1d9e2a-5b4f-4a8e-9d3c-2f6b1a0e8c47" \
-H "Authorization: Bearer sk_live_your_key_here"
{
"data": {
"id": "7c1d9e2a-5b4f-4a8e-9d3c-2f6b1a0e8c47",
"reservationId": "3f8b2c6d-1e4a-4b7c-8d9e-0a1b2c3d4e5f",
"propertyId": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
"source": "airbnb",
"reviewedAt": "2026-09-28T10:14:00.000Z",
"rating": 4,
"cleanlinessRating": 5,
"checkinRating": 4,
"communicationRating": 5,
"valueRating": 4,
"locationRating": null,
"accuracyRating": null,
"publicReview": "Lovely flat, easy check-in.",
"privateReview": "The shower drain was slow.",
"isComplete": true,
"photoUrls": [],
"createdAt": "2026-09-28T10:14:03.000Z"
},
"meta": { "requestId": "…" }
}
type Review = {
id: string
reservationId: string | null
propertyId: string | null
source: string | null
reviewedAt: string | null
rating: number | null
cleanlinessRating: number | null
checkinRating: number | null
communicationRating: number | null
valueRating: number | null
locationRating: number | null
accuracyRating: number | null
publicReview: string | null
privateReview?: string | null
isComplete: boolean
photoUrls: string[]
createdAt: string
}
const reviewId = '7c1d9e2a-5b4f-4a8e-9d3c-2f6b1a0e8c47' // from a review.submitted delivery
const res = await fetch(`https://api-us.suiteop.com/api/v1/reviews/${reviewId}`, {
headers: { Authorization: `Bearer ${process.env.SUITEOP_API_KEY}` },
})
if (!res.ok) throw new Error(`getReview failed: ${res.status}`)
const { data: review } = (await res.json()) as { data: Review }
  • Ratings — rating is the overall score and the six category ratings (cleanliness, checkin, communication, value, location, accuracy) break it down. Every rating is a number from 1 to 5 on every channel (it can be fractional, such as 4.5), and null when the guest gave no opinion on it. Treat null as “not rated”, never as zero, or your averages will drop.
  • source — where the review came from: airbnb, booking_com, vrbo, check_in_survey, check_out_survey, suiteop, direct or google. Accept unknown strings too: new sources can be added.
  • reservationId and propertyId — the stay and property the review belongs to. Either can be null.
  • publicReview and privateReview — the text the guest published, and the private feedback meant only for you. privateReview is present only when your credential also holds view_analytics. Without it the key is absent from the object, not null, so check for the key rather than its value.
  • photoUrls — signed download links to photos the guest attached to a check-in survey; reviews from any other source have an empty array. They are short-lived: download the files when you receive them, and call getReview again for fresh links rather than storing the URLs. A photo that cannot be signed is left out of the array rather than failing the request.

getReview answers 400 (validation_error) when the id is not a UUID, and 404 (not_found_error) when the review belongs to another organization or, for an OAuth credential limited to some properties, to a property outside that scope. The two 404 cases are deliberately indistinguishable. An API key (sk_) reaches every property in its organization.

  • Webhooks — the review.submitted event and when it does and doesn’t fire
  • Reservations — the stay a review’s reservationId points to
  • Errors — the error envelope