Airbnb Reviews API — Guest Reviews as JSON
Documentation menu
FetchLayer FetchLayer API

Read a listing’s guest reviews

Guest reviews for one listing, by id or URL. Each review carries its rating, its text **in the language it was written in**, that language code, the source's own translation where one is published, the date, the guest's public first name, photo and home town, and the host's reply when there is one. **A reviews response tells you how complete it is, without a second call.** `totalReviewCount` is the listing's full review count as the source reports it, `reviewCount` is how many came back in this response, `hasMore` is the boolean, and `notes[]` states it in plain words. A real response measured on 17 September 2026: `notes: ["These are 10 of the 52 reviews the source reports for this listing.", "More reviews are available. Continue with nextCursor."]`. Pull the whole set and the same field says so instead — `notes: ["These are 52 of the 52 reviews the source reports for this listing."]`, with `hasMore: false` and `nextCursor: null` and no second note. That difference is the point: ten reviews and *the first ten of fifty-two* are different answers, and you can tell which one you are holding from the response in your hand. The response also carries `topics` — the source's own tally of what reviewers talked about, as `[{topic, count}]` — which gives you the shape of 465 reviews from a page of ten. Billing: 1 credit per page fetched, reported as `pagesFetched`. A page is 50 reviews by default; a walk stops early when `limit` is reached and `pagesFetched` reports what was actually read, so asking for `pages: -1` with a small `limit` does not bill for pages nobody fetched. Measured on 17 September 2026: `{"listing":"33579922","limit":10}` returned 200 in 0.53-0.58s across three runs with 10 reviews and `pagesFetched: 1`.

POST /listing-reviews Reviews
https://api.fetchlayer.dev/airbnb/listing-reviews
OpenAPI JSON

Headers

Authorization string required

Bearer token — your FetchLayer API key.

Parameters

listing string required

A listing: its `airbnb.com/rooms/…` URL, or its numeric id. The only required field.

limit integer optional

Maximum reviews returned in total, up to 1000. Pass -1 for the maximum. (default: 50)

pages integer optional

How many pages of reviews to walk in one request, up to 20. Each page fetched is 1 credit. Pass -1 for the maximum — combined with `limit: -1` that is how you pull every review a listing has. (default: 1)

cursor string optional

Continue from a previous response's `nextCursor`.

format string optional

Envelope format: json or markdown. (default: json)

Response Fields

listing-reviews

Read a listing’s guest reviews

transport string

The source. "airbnb".

notes string[]

Caveats and completeness statements you can act on, in plain words. On /listing-reviews this is where the "10 of the 52" line lives; on the priced routes it is where the stay window used for pricing is stated; on /listing-availability it is where the booking-window warning lives — read it before reading a run of closed nights as a closure.

pagesFetched number

Pages read, and what the request is billed at: 1 credit per page. A page costs the same whether it comes back full or half empty. /resolve-url reports 0 and is free.

listingId string

The listing the reviews belong to, echoed back — useful when you passed a URL.

totalReviewCount number

**The listing's full review count as the source reports it.** Compare it to `reviewCount` and you know whether you are holding all of them, with no second call. This is the field that makes a partial answer honest.

reviewCount number

How many reviews came back in this response.

hasMore boolean

Whether there are further reviews past this page. False, with `nextCursor: null` and a single "N of N" note, is what a complete pull looks like.

nextCursor string

Pass back as `cursor` to continue. Null when there is nothing more.

topics object[]

`[{topic, count}]` — the source's own tally of what reviewers wrote about, e.g. `{topic: "Cleanliness", count: 14}`. Ten topics on the listings measured.

reviews[].id string

The review's id.

reviews[].rating number

The guest's overall score for the stay. A single number — the per-category breakdown is published for the listing as a whole on /listing-detail (`listing.rating.categories`), not per review.

reviews[].text string

**The review as the guest wrote it**, in their own language. Never replaced by a machine translation.

reviews[].language string

The language `text` is written in, as a code. Measured across 100 reviews on one listing: 86 en, plus de, pt, ko, fr, ja, is, nl, no and es — so a listing's reviews are not one language, and this is the field to branch on.

reviews[].translatedText string

The source's own published translation, where there is one — 14 of those 100 reviews carried it. Null otherwise. The original in `text` is always there either way.

reviews[].createdAt string

An ISO timestamp, e.g. "2026-09-03T08:21:19Z".

reviews[].reviewer object

`{id, firstName, profilePictureUrl, location}` — the guest's public profile only. `location` is their stated home town where they published one ("Boston, Massachusetts", "Tokyo, Japan"), null where they did not.

reviews[].hostResponse object

`{text, createdAt}` when the host replied, null otherwise — 2 of 100 on the listing measured. `createdAt` here is the month the source prints, e.g. "October 2025", not an ISO timestamp.

Request

curl -X POST "https://api.fetchlayer.dev/airbnb/listing-reviews" \
  -H "Authorization: Bearer ss-your-key" \
  -H "Content-Type: application/json" \
  -d '{"listing":"1695539435866678513","limit":10}'

Response

{
  "transport": "airbnb",
  "notes": [
    "These are 10 of the 52 reviews the source reports for this listing.",
    "More reviews are available. Continue with nextCursor."
  ],
  "pagesFetched": 1,
  "listingId": "1695539435866678513",
  "totalReviewCount": 52,
  "reviewCount": 10,
  "hasMore": true,
  "nextCursor": "10",
  "topics": [
    {
      "topic": "Cleanliness",
      "count": 14
    },
    {
      "topic": "Hospitality",
      "count": 14
    },
    {
      "topic": "Pool",
      "count": 13
    },
    {
      "topic": "Location",
      "count": 12
    }
  ],
  "reviews": [
    {
      "id": "1766530781113184592",
      "rating": 4,
      "text": "The hotel room was lovely and spotless and had a coffee machine and sink in the room which was great. The staff were really friendly and helpful. The only down side was the swimming pool was tiny, not as it looked in the photo. …",
      "language": "en",
      "translatedText": null,
      "createdAt": "2026-09-03T08:21:19Z",
      "reviewer": {
        "id": "584964753",
        "firstName": "Estelle",
        "profilePictureUrl": "https://a0.muscache.com/im/pictures/user/User/original/0db2697f-2644-41b4-aa04-ac2edce9d6ae.jpeg",
        "location": null
      },
      "hostResponse": null
    }
  ]
}