Reviews

Every Airbnb and Booking.com review in one API: read, reply, and review a guest. Guide: /docs/reviews.

List reviews

GET/v1/reviews

Request

curl https://api.repull.dev/v1/reviews?limit=20 \
  -H "Authorization: Bearer $REPULL_API_KEY"

Response

{
  "data": [
    {
      "id": "123",
      "externalId": "123",
      "platform": "booking",
      "listingId": "123",
      "reservationId": "123",
      "reservationConfirmationCode": "Example text",
      "guestId": "123",
      "guestName": "Example",
      "guestAvatar": null,
      "reviewerRole": "Example text",
      "rating": 0,
      "categories": [
        {
          "category": "facilities",
          "rating": 0,
          "comment": null
        }
      ],
      "publicReview": "Example text",
      "privateFeedback": null,
      "isRevieweeRecommended": null,
      "response": null,
      "submittedAt": "Example text",
      "updatedAt": "Example text",
      "expiresAt": null,
      "hidden": false,
      "language": null,
      "providerPropertyId": "123"
    }
  ],
  "pagination": {
    "nextCursor": "eyJpZCI6MTIzfQ==",
    "hasMore": true,
    "total": 0
  }
}

Captured from a real response. Regenerated on every release, and CI fails if this shape stops matching the API.

Query Parameters

accountstring

Only one connected account's records, as `provider:externalAccountId` (e.g. `airbnb:79730216`, `booking:10167991`, `vrbo:36`, `hostaway:…`) — the pair on every webhook `account` block, on `connect.session.completed`, and on each record's `account`. See /for-platforms.

cursorstring

Opaque cursor returned in the previous response's `pagination.nextCursor`.

offsetinteger

First-class alias for cursor-based pagination. Mutually exclusive with `cursor` — passing both returns 422. Accepts integers in `[0, 10000]`; deeper walks must use `cursor` (constant per-page cost). The response always includes `pagination.nextCursor` so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying.

limitinteger

platformstring

listingIdinteger

Restrict to one internal Repull listing.

rating_minnumber

rating_maxnumber

statusstring

`responded` — host has replied. `unanswered` — host has not replied. `all` — no filter.

reviewerRolestring

`guest` (default) — reviews written by guests about the host/property. `host` — reviews written by the host about guests. `all` — both.

Get a review

GET/v1/reviews/:id

Request

curl https://api.repull.dev/v1/reviews/321 \
  -H "Authorization: Bearer $REPULL_API_KEY"

Response

{
  "id": "123",
  "externalId": "123",
  "platform": "booking",
  "listingId": "123",
  "reservationId": "123",
  "reservationConfirmationCode": "Example text",
  "guestId": "123",
  "guestName": "Example",
  "guestAvatar": null,
  "reviewerRole": "Example text",
  "rating": 0,
  "categories": [
    {
      "category": "facilities",
      "rating": 0,
      "comment": null
    }
  ],
  "publicReview": "Example text",
  "privateFeedback": null,
  "isRevieweeRecommended": null,
  "response": null,
  "submittedAt": "Example text",
  "updatedAt": "Example text",
  "expiresAt": null,
  "hidden": false,
  "language": null,
  "providerPropertyId": "123"
}

Captured from a real response. Regenerated on every release, and CI fails if this shape stops matching the API.

Reply to a review (Airbnb, Booking.com, VRBO, or through a PMS)

POST/v1/reviews/:id/reply

Note

Posts your public reply under a guest's review on whichever channel it came from. Each channel accepts one reply per review. A channel without a reply API is 422 unsupported_channel. A review read from a connected PMS (`pms` set on the review — Guesty, Hostaway) is answered through that PMS, and the response names it in `pms`; a PMS with no reply API (Hostaway) is 422 pms_write_unsupported. GET /v1/connect/{provider} → capabilities.pms.reviews.reply says so beforehand. Guide: /docs/pms-writes#reviews

Request

curl -X POST https://api.repull.dev/v1/reviews/321/reply \
  -H "Authorization: Bearer $REPULL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "message": "Thank you for staying with us!"
}'

Response

{ "id": "200", "platform": "booking", "pms": null, "response": "Thank you for your kind words!" }

Body Parameters

messagestringRequired

Reply text. `response` is accepted as an alias.

Review a guest (Airbnb; publishes, final)

POST/v1/reviews/:id/guest-review

Note

Your review of a guest — a review with reviewerRole "host". Submitting publishes it and is final: Airbnb has no draft and no edit (409 review_already_submitted). A review from another channel is 422 unsupported_channel. Anything missing is 422 invalid_params naming the field, before anything is sent. Guide: /docs/reviews#review-a-guest.

Request

curl -X POST https://api.repull.dev/v1/reviews/321/guest-review \
  -H "Authorization: Bearer $REPULL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "publicReview": "Joanne was a great guest.",
  "rating": 5,
  "isRevieweeRecommended": true
}'

Response

{ "id": "181567", "externalReviewId": "1776076418138684216", "submitted": true }

Body Parameters

publicReviewstringRequired

Your review of the guest, shown on their Airbnb profile. Up to 1000 characters. `comment` is accepted as an alias.

isRevieweeRecommendedbooleanRequired

Whether you would host this guest again. Required by Airbnb; never assumed.

ratinginteger

1–5, used for every category you do not rate in `categoryRatings`.

categoryRatingsarray

`[{ category, rating, comment? }]` for `cleanliness`, `communication`, `respect_house_rules`. All three must end up rated.

privateFeedbackstring

A note to the guest that is not published.

AI