Airbnb Review Scraper avatar

Airbnb Review Scraper

Pricing

from $2.99 / 1,000 results

Go to Apify Store
Airbnb Review Scraper

Airbnb Review Scraper

Scrape Airbnb reviews from any listing with ease. This actor extracts reviewer names, dates, ratings, comments, and host responses. Ideal for market research, sentiment analysis, pricing strategy, and tracking guest experience trends.

Pricing

from $2.99 / 1,000 results

Rating

0.0

(0)

Developer

Scraper Engine

Scraper Engine

Maintained by Community

Actor stats

0

Bookmarked

27

Total users

0

Monthly active users

a day ago

Last modified

Share

Airbnb Review Scraper — Ratings, Text, Reviewer and Host Reply Data

Airbnb Review Scraper pulls every public guest review from an Airbnb listing into structured JSON — star rating, review date, full review text, the reviewer's name and profile, and the host's reply when one exists. Give it a listing URL or ID, choose how many reviews you want and in which order, and rows land in the dataset the moment they're read, ready to export as JSON, CSV or Excel. Start a run from the Actor page below.


🧭 What is Airbnb Review Scraper?

Airbnb Review Scraper is an Apify Actor that reads the public reviews feed of an Airbnb listing page and returns one structured row per review — no browser, no manual copy-paste, no HTML to parse. It does not require an Airbnb account or login: it authenticates against Airbnb's own public web client, the same one your browser uses to load a listing page, and the input schema has no field for Airbnb credentials. It's built for short-term-rental hosts, property managers, market researchers and data teams who need review data as clean rows rather than a page to read.


🔓 What Airbnb review data is publicly available to scrape?

Everything shown on a listing's public reviews page is accessible without logging in — ratings, review text, dates, host replies, and the reviewer's public name and profile link. Airbnb never publishes reviewer or host contact details on that page, logged in or not.

Data CategoryPublicly AvailableRestricted
Star rating & review text
Review date (raw and localized)
Host reply text✅ when the host has answered
Reviewer display name & profile link
Reviewer profile photo
Review highlight tag (e.g. "Stayed a few nights")✅ on reviews Airbnb tags
Reviewer or host phone number / email❌ never published on the reviews page
Reviewer's exact address❌ only a coarse localized string (city, or membership tenure) is shown

Airbnb Review Scraper only returns publicly visible data — what any visitor sees on the listing's reviews page. Nothing behind a login wall.


📋 What data can I extract with Airbnb Review Scraper?

Every run returns one row per review, plus a labelled status row for any listing that couldn't be read. Below are the fields the row-building code writes to every review row and every status row.

📝 Review content and status

FieldDescription
type"review" for a review row
isChildAlways false on this Actor's rows
idAirbnb's review ID
roomIdAirbnb listing ID
startUrlThe listing input you supplied, resolved to a canonical URL
reviewUrlDeep link to the listing's reviews page
listingStatusAlways "ok" on a review row (see the status row table below for the other values)
statusMessageAlways null on a review row
languageLanguage Airbnb detected for the review text
textReview text with Airbnb's <br/> line-break markup converted to real newlines
textRawReview text exactly as Airbnb returned it, markup included
localizedTextReview text in the language you requested via locale
localizedDateThe date as Airbnb displays it, in your chosen language (e.g. "December 2024")
localizedReviewerLocationWhat Airbnb shows under the reviewer's name — sometimes a place, sometimes a membership tenure like "3 years on Airbnb"
createdAtISO 8601 timestamp of the review
reviewHighlightAirbnb's short highlight tag for this review, when present
highlightTypeThe category of that highlight tag, e.g. "STAY_LENGTH"
responseThe host's reply text, when there is one

🙋 Reviewer, host and rating

FieldDescription
ratingStar rating as a number, or null when Airbnb does not expose one for that review
ratingAccessibilityLabelAirbnb's accessibility text for the rating
reviewerIdThe reviewer's Airbnb user ID
reviewerNameThe reviewer's first name
reviewerProfileUrlLink to the reviewer's public profile
reviewerPictureUrlReviewer's profile picture URL
hostIdThe host's Airbnb user ID
hostNameThe host's name
hostProfileUrlLink to the host's public profile
hostPictureUrlHost's profile picture URL
reviewerThe reviewer as a nested object: id, firstName, hostName, pictureUrl, profilePath, profilePicture
revieweeThe host as a nested object, same shape as reviewer
scrapedAtUTC timestamp when the row was collected

🤖 Add-on: Need additional Airbnb data?

Reviews are only one slice of a listing. If you also need pricing, photos, amenities or availability, pair this Actor with the rest of the Scraper Engine catalog covering other review-driven platforms, or run this Actor alongside a listing-details scraper against the same roomId values to join both datasets.


🛠️ Why not build this yourself?

Airbnb has no public, self-service API. Its developer/partner API is granted only to approved companies through a closed application process, and as of August 2026 that partner API does not include review data at all — there is no public review endpoint on Airbnb's roadmap (StayAPI, "Airbnb Reviews API: How to Access Airbnb Review Data (2026)"; Elfsight, "How to get and use Airbnb API: partnership and integration [2026]", checked 2026-08-15).

Building this yourself means reverse-engineering Airbnb's internal GraphQL endpoint: extracting a rotating operation ID and API key out of a versioned JavaScript bundle referenced from the listing page, telling a genuinely empty listing apart from a refused request (Airbnb answers both with an HTTP 200), handling pagination and duplicate reviews across four sort orders, and detecting soft-block interstitials before they corrupt a run. Airbnb Review Scraper already does all of this, including a pinned fallback bundle hash for when the page no longer references the JS file directly, and a proxy-rotation ladder that only escalates when a block is actually detected.


⚡ How to use Airbnb Review Scraper

  1. Open Airbnb Review Scraper on the Apify Console (or call it via apify_client / the Apify API).
  2. Provide the required input, startUrls — one or more Airbnb listing URLs or bare listing IDs.
  3. Optionally set maxComments (reviews per listing), sortOrder, locale, and proxyConfiguration.
  4. Start the run.
  5. Download the dataset as JSON, CSV or Excel, or stream it via the Apify API as rows are pushed.

🔁 How to scale to bulk review extraction

startUrls is an array, so a single run can hold as many listing URLs or IDs as you need — the schema places no cap on how many. maxComments applies per listing, so 10 listings with maxComments: 50 collects up to 500 review rows in one run. There's no need to loop separate runs per listing unless you want independent proxy or locale settings per batch.


💡 What can you do with Airbnb review data?

  • 🏠 Hosts and property managers track guest sentiment using rating and text across their own portfolio, spotting a recurring complaint before it drags the listing average down.
  • 📊 Revenue managers line up rating against createdAt to see whether a rating dip follows a price or amenity change.
  • 🏘️ Investors and market researchers judge a property's demand using rating, reviewHighlight and review volume across a set of roomId values before buying or listing a competing unit.
  • 🧑‍💼 Brand and reputation teams pull response alongside text to audit which hosts reply to guests and how.
  • 🤖 AI engineers feed text, localizedText and response into a sentiment-analysis or RAG pipeline, using reviewerName, rating and createdAt as structured metadata for citations and filtering.

🚦 How does Airbnb Review Scraper handle rate limits and blocking?

The Actor manages its own connection: by default it talks to Airbnb directly and only escalates to Apify Proxy's residential group after it detects a block (an HTTP 401/403/429, or a short response body containing an interstitial phrase like "verify you are a human"). Once triggered, that escalation stays in effect for the rest of the run. Every request gets up to 3 attempts with exponential backoff between tries, and the route rotates on each retry.

⚠️ This Actor does not solve CAPTCHAs — it detects the block signal and reroutes; a persistent block still ends the request as a failure after retries are exhausted.

If a listing fails before any review is collected, it's reported as a not_found status row. If it fails partway through, the reviews already collected stay in the dataset and the listing is marked incomplete rather than silently truncated. If the once-per-run session bootstrap itself fails, the run stops and reports setup_failed rather than continuing on a broken connection.


⬇️ Input

ParameterRequiredTypeDescriptionExample Value
startUrlsYesarray of stringsOne or more Airbnb listing URLs (https://www.airbnb.com/rooms/12937) or bare listing IDs (12937). Anything that isn't an Airbnb listing is reported back as a clearly labelled row instead of being guessed at.["https://www.airbnb.com/rooms/12937", "20669368"]
maxCommentsNointeger (min 1, max 10000, default 10)How many reviews to collect from each listing. The only ceiling is the listing's own review count.50
sortOrderNostring, enum, default "MOST_RECENT"Which reviews come first: MOST_RECENT (newest first — recommended, complete coverage), RATING_DESC (highest rated first), RATING_ASC (lowest rated first), BEST_QUALITY (Airbnb's own relevance order — may repeat reviews)"MOST_RECENT"
localeNostring, enum, default "en"The language Airbnb should localise review text and dates into. Options: en, az, bs, ca, cs, da, de, es, et, fr, ga, hr, id, sr, xh, zu"en"
proxyConfigurationNoobjectOptional. The run manages its own connection by default and adapts if Airbnb slows it down.{"useApifyProxy": false}

Example input

{
"startUrls": [
"https://www.airbnb.com/rooms/12937",
"20669368"
],
"maxComments": 50,
"sortOrder": "MOST_RECENT",
"locale": "en",
"proxyConfiguration": {
"useApifyProxy": false
}
}

⬆️ Output

Rows are typed, normalized JSON pushed to the dataset as each review is read, and can be exported as JSON, CSV, Excel, or pulled directly through the Apify API. Every run pushes two kinds of row: review rows and listing status rows.

Only review rows are billed. Each review is pushed with charged_event_name="row_result"; listing status rows — the accounting/error rows described below — are pushed with no charged event attached, so they cost nothing. Filter on type === "review" (or exclude type === "listingStatus") to isolate billed rows.

Example output

Review row:

{
"type": "review",
"isChild": false,
"id": "1734926331335308010",
"roomId": "12937",
"startUrl": "https://www.airbnb.com/rooms/12937",
"reviewUrl": "https://www.airbnb.com/rooms/12937/reviews",
"listingStatus": "ok",
"statusMessage": null,
"language": "en",
"text": "Great host! The room was clean and well kept.\nOur flight got delayed and the host was flexible with check-in.",
"textRaw": "Great host! The room was clean and well kept.<br/>Our flight got delayed and the host was flexible with check-in.",
"localizedText": "Great host! The room was clean and well kept.\nOur flight got delayed and the host was flexible with check-in.",
"localizedDate": "December 2024",
"localizedReviewerLocation": "Santiago, Chile",
"createdAt": "2024-12-23T15:18:51Z",
"rating": 5,
"ratingAccessibilityLabel": "Rating, 5 stars",
"reviewHighlight": "Stayed a few nights",
"highlightType": "STAY_LENGTH",
"response": "Thank you so much for staying with us!",
"reviewerId": "1608886371300404735",
"reviewerName": "Emily",
"reviewerProfileUrl": "https://www.airbnb.com/users/profile/1608886371300404735",
"reviewerPictureUrl": "https://a0.muscache.com/im/pictures/user/example.jpg",
"hostId": "15483",
"hostName": "Orestes",
"hostProfileUrl": "https://www.airbnb.com/users/profile/15483",
"hostPictureUrl": "https://a0.muscache.com/im/users/15483/example.jpg",
"reviewer": {
"id": "1608886371300404735",
"firstName": "Emily",
"hostName": null,
"pictureUrl": "https://a0.muscache.com/im/pictures/user/example.jpg",
"profilePath": "/users/profile/1608886371300404735",
"profilePicture": "https://a0.muscache.com/im/pictures/user/example.jpg"
},
"reviewee": {
"id": "15483",
"firstName": "Orestes",
"hostName": "Orestes",
"pictureUrl": "https://a0.muscache.com/im/users/15483/example.jpg",
"profilePath": "/users/profile/15483",
"profilePicture": "https://a0.muscache.com/im/users/15483/example.jpg"
},
"scrapedAt": "2026-08-15T09:14:02Z"
}

Listing status row (pushed instead of, or in addition to, review rows — see the table below for every listingStatus value):

{
"type": "listingStatus",
"isChild": false,
"id": null,
"roomId": "99999999999",
"startUrl": "https://www.airbnb.com/rooms/99999999999",
"reviewUrl": "https://www.airbnb.com/rooms/99999999999/reviews",
"listingStatus": "not_found",
"statusMessage": "Airbnb did not return this listing. It may not exist, or it is no longer publicly available.",
"listingReviewTotal": null,
"reviewsCollected": 0,
"scrapedAt": "2026-08-15T09:14:02Z"
}

listingStatus values on a status row: ok (a real listing with zero reviews so far), not_found (Airbnb refused or the listing doesn't exist), incomplete (the walk started but Airbnb stopped answering partway through — reviews already collected stay in the dataset), invalid_input (the value in startUrls isn't an Airbnb listing URL or ID), setup_failed (the session Airbnb requires couldn't be established, ending the run).

A run in which nothing resolved to an available listing finishes as failed, not as a green run with zero rows. Rows already pushed before that point remain in the dataset regardless.

The Actor also writes RUN_SUMMARY.json to the run's key-value store, with listingsRequested, listingsWithReviews, listingsUnavailable, listingsIncomplete, inputsNotAListing, reviewsCollected, sortOrder, language and maxReviewsPerListing.


⚙️ How does it work?

Airbnb Review Scraper opens the listing page once per run to pick up the public API key and the GraphQL operation ID Airbnb's own web app uses for reviews, then queries that same endpoint directly — the requests look like a normal page load, not a browser session. A refused or non-existent listing is told apart from a genuinely empty one by checking that the reviews container is positively present in the response, since Airbnb answers both cases with an ordinary HTTP 200. Requests rotate through a proxy-rotation ladder that only escalates to a residential route once a block is actually detected, with bounded retries on transient failures. Only what's rendered on the listing's public reviews page is returned — the output schema stays the same regardless of how Airbnb's front end changes.


🔌 Integrations

Airbnb Review Scraper runs on Apify, so it works with anything that can call the Apify API or the apify-client SDK.

Calling Airbnb Review Scraper programmatically

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_API_TOKEN>")
run = client.actor("airbnb-review-scraper").call(run_input={
"startUrls": ["https://www.airbnb.com/rooms/12937"],
"maxComments": 50,
"sortOrder": "MOST_RECENT",
"locale": "en",
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request to the Apify API.

No-code tools (n8n, Make, LangChain)

In n8n, use the HTTP Request node pointed at the Actor's run-sync-get-dataset-items endpoint with your API token, or the dedicated Apify node if you have it installed. In Make, the Apify app's "Run an Actor and get dataset" module takes the same input JSON shown above. In LangChain or a custom agent framework, call the Apify API endpoint directly as a tool and pass the returned JSON straight into your chain — no parsing step needed.


Scraping publicly available data — content anyone can view without logging in — is generally lawful. Airbnb Review Scraper returns only what's shown on a listing's public reviews page: review text, ratings, dates, and the reviewer's public name and profile link. Reviewer and host names and profile links are personal data, so if you plan to store or process this data at scale, you're responsible for a lawful basis under GDPR (if you or your data subjects are in the EU/EEA) or CCPA (California residents), and for complying with Airbnb's Terms of Service for your specific use. Consult legal counsel if your use case involves bulk storage of personal data.


❓ Frequently asked questions

What Airbnb review fields does Airbnb Review Scraper return?

The top fields are rating, text, createdAt, reviewerName and response (the host's reply). See What data can I extract above for the full field list.

Does Airbnb Review Scraper require an Airbnb account or login?

No. It authenticates using a public web client key extracted from the listing page itself — the same one any visitor's browser uses — and the input schema has no field for Airbnb credentials.

How many reviews can I extract in one run?

maxComments caps reviews per listing between 1 and 10,000, and startUrls places no limit on how many listings you can queue in one run. Ten listings at maxComments: 50 collects up to 500 rows.

What happens if a listing is removed, private, or doesn't exist?

You get a listingStatus: "not_found" row with a plain-English statusMessage, not a silently empty dataset. If the listing genuinely has zero reviews (as opposed to being refused), the row instead reports listingStatus: "ok" with reviewsCollected: 0 — the two cases are never conflated.

Can I scrape reviews from multiple Airbnb listings at once?

Yes. Put as many listing URLs or IDs into startUrls as you need; maxComments, sortOrder and locale apply to every listing in the run.

Does Airbnb Review Scraper work with Claude, ChatGPT and other AI agent tools?

It's callable as an HTTP endpoint through the Apify API from any agent framework that can make a tool call — LangChain, a custom Claude or GPT tool, or any orchestration layer that can issue an HTTP request.

How does Airbnb Review Scraper compare to other Airbnb review scrapers?

It tells a refused or non-existent listing apart from a listing that genuinely has zero reviews, rather than reporting both as an empty dataset, and it flags which sort orders are stable versus which one (BEST_QUALITY) can repeat reviews on long listings — both documented directly from this Actor's own source, since Airbnb itself doesn't publish that distinction.

Does Airbnb Review Scraper return data in a format LLMs can use directly?

Yes. Typed, normalized JSON with consistent field names across runs — no HTML parsing, no selectors. Pass it straight to an LLM, index it into a vector store, or feed it to an agent tool.

What happens when Airbnb changes its layout or anti-bot system?

The Actor discovers the current review-endpoint bundle from the listing page's own HTML rather than hardcoding one, with a pinned bundle hash as a documented last-resort fallback. The output schema stays stable regardless of front-end changes. No specific update turnaround is promised.

Can I use Airbnb Review Scraper without managing proxies or browser infrastructure?

Yes. The Actor manages its own connection and only escalates to Apify Proxy's residential group when it detects a block. Setting proxyConfiguration is optional, for when you need a specific country or connection type.

Which fields work best for AI training data and RAG indexing?

For RAG, index text (or localizedText) and response — the high-information narrative fields. For structured training data or filtering, rating, createdAt, reviewerName and highlightType return as consistent typed primitives across every row.


ScraperWhat it extracts
Facebook Reviews ScraperPublic review and recommendation posts from Facebook pages
Walmart Reviews ScraperProduct reviews from Walmart product listings
Udemy Course Reviews ScraperWritten student reviews from Udemy courses
Goodreads Book ScraperBook search results — title, author, rating, ratings count, publication year
Amazon Price TrackerAmazon prices, ratings, reviews, sellers and stock

💬 Your feedback

Found a bug or missing a field? Let us know through the Actor's Issues tab on Apify Console, or leave a message on the Actor's Store page — reports like this are how the field list and error handling stay accurate.