Airbnb Rooms URLs Scraper & Guest Complaint Reviews avatar

Airbnb Rooms URLs Scraper & Guest Complaint Reviews

Pricing

from $2.99 / 1,000 results

Go to Apify Store
Airbnb Rooms URLs Scraper & Guest Complaint Reviews

Airbnb Rooms URLs Scraper & Guest Complaint Reviews

Airbnb Rooms URLs Scraper extracts room listing URLs from Airbnb’s search interface with precision. Ideal for scaling data pipelines, monitoring markets, building datasets, or feeding other Airbnb actors with clean, structured room URLs.

Pricing

from $2.99 / 1,000 results

Rating

0.0

(0)

Developer

SimpleAPI

SimpleAPI

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Airbnb Review Scraper — Listings, Ratings and Complaint Flags

This Airbnb review scraper pulls room listings and the guest reviews underneath them as linked parent and child rows: review text, star rating, reviewer name, localized date, the host's public reply, Airbnb's own topic tags, and a per-review complaint-keyword flag. Star-rating, topic-tag and full-text filters run on Airbnb's own servers before a byte reaches you, so even a capped run still surfaces the worst feedback first. Hospitality operators, revenue managers and market researchers use it to audit guest sentiment at scale — from a single room to a portfolio of listings — without opening a browser.

What is the Airbnb Review Scraper?

The Airbnb Review Scraper takes one or more Airbnb room URLs (or bare room IDs) and returns each listing as a parent row plus every guest review as a child row underneath it, delivered as a structured Apify dataset — JSON by default, with CSV, Excel and XML export built into the Apify platform. It talks directly to Airbnb's public listing page and its internal review endpoint; no Airbnb account, login or API key is required to run it.

Key capabilities:

  • 🏠 Accepts direct room URLs or bare numeric room IDs in startUrls; any entry that isn't a room URL is resolved through Airbnb's own search results instead, returning up to 20 matching listings per keyword
  • 💬 Guest reviews come back as child rows, sorted server-side by Airbnb — default is lowest-rated-first, so a capped run still keeps the worst feedback
  • ⭐ A star-rating ceiling (maxReviewRating), Airbnb's own per-listing review topic tag (reviewTag) and its full-text review search (reviewSearchText) all filter on Airbnb's servers, before the page is even downloaded
  • 🚩 Local, case-insensitive complaint-keyword matching (with short suffix tolerance) flags each review and rolls the hits up into a per-listing frequency table
  • 👤 Optional host-profile enrichment adds a nested profile object to the listing row for one extra request
  • 🛡️ Automatic proxy escalation — none → datacenter → residential — triggers the moment a page comes back without its expected data container

What data can I extract with the Airbnb Review Scraper?

Every run writes two row types into one dataset — listing rows carrying the property, host and rating data, and review rows carrying the guest text — told apart by the type, isChild and parentId columns.

Listing identity, media and policies (parent rows)

FieldExample ValueUse Case
id / listingId"12937"stable key to join parent and child rows
listingTitle / title"Sunny room in the heart of downtown"display name / PDP headline
listingUrlhttps://www.airbnb.com/rooms/12937canonical link, tracking params stripped
urlhttps://www.airbnb.com/rooms/12937?locale=en-US&currency=USDthe full localized URL Airbnb served
requestedUrlhttps://www.airbnb.com/rooms/12937the exact input value that produced the row
thumbnailhttps://a0.muscache.com/...share-card image
androidLink / iosLinkairbnb://...native app deep links
propertyType / roomType"Entire rental unit" / "entire_home"segment by property or space type
homeTier1Airbnb's internal listing tier
personCapacity4party-size fit check
sharingConfigTitle"Charming Loft · Entire home"fallback title, used only if title is empty
description / htmlDescription"Newly renovated loft…"plain-text and raw-HTML listing copy
subDescription{title, items}Airbnb's bullet-point summary block
seoTitle / metaDescriptionAirbnb's own SEO copyon-page metadata
breadcrumbs[{linkRoute, linkText}]Airbnb's own category trail
highlights[{title, subtitle, icon, type}]badges such as "Self check-in"
brandHighlights.hasGoldenLaureltrueGuest Favourite badge flag
images[{caption, imageUrl, orientation}]photo gallery
amenities[{title, values:[...]}]full amenities list, grouped by section
houseRules.general[{title, values:[...]}]house rules, grouped by section
cancellationPolicies[{title, policyName, policyId}]cancellation terms shown on the listing page
location / locationSubtitle"New York, United States" / "Manhattan"display location strings
locationDescriptions[{title, content, mapMarkerRadiusInMeters}]Airbnb's "what's nearby" text blocks
coordinates.latitude / coordinates.longitude40.7128 / -74.006mapping and geofencing
descriptionOriginalLanguage / language"en" / "en-US"source language / run locale
checkIn / checkOut"2026-09-01"dates echoed back from the input
timestampISO 8601 UTCwhen Airbnb generated the listing payload
scrapedAtISO 8601 UTCwhen this Actor wrote the row

Host and co-host (parent rows)

FieldExample ValueUse Case
host.id / host.contextualUserId"50124"host identifiers used for profile lookup
host.name / host.profileImage"Maria" / image URLdisplay name and avatar
host.isSuperHost / host.isVerifiedtruetrust/status badges
host.highlights / host.about / host.hostDetailsarray / text / arrayhost bio and stated details
host.ratingCount / host.ratingAverage312 / 4.85host-level review stats
host.timeAsHost{years, months}hosting tenure
host.profilenested objectonly present when enrichHostAndCoHostProfiles is on
coHosts[{contextualUserId, name, profilePictureUrl}]co-hosts listed on the property

Review summary and applied filters (parent rows)

FieldExample ValueUse Case
rating.accuracy / .checking / .cleanliness / .communication / .location / .value4.6 eachper-category star breakdown
rating.guestSatisfaction / rating.reviewsCount4.8 / 312overall score and Airbnb's total review count
lowestRatedCategory / lowestRatedCategoryScore"cleanliness" / 4.3the category dragging the listing down
reviewsUrl.../rooms/12937/reviewslink to the reviews page
reviewsCountTotal / reviewsFetched / reviewsFilteredOut312 / 140 / 40Airbnb's total, raw pages read, and rows dropped by filters
reviewPagesRequested / reviewsStatus3 / "ok"pagination cost and outcome per listing
reviewTagsAvailable[{name, localizedName, count}]Airbnb's own topic tags for this listing, with counts
reviewsScraped / lowRatingReviewsCount100 / 76rows kept vs. rows at/below the rating ceiling
reviewRatingBreakdown{"1":10,"2":20,"3":30,"4":25,"5":15}kept-review count per star
averageScrapedReviewRating2.9average of the kept (usually low) reviews only
hostResponseCount / hostResponseRate18 / 0.18how often the host replied among kept reviews
complaintKeywordMatchCount / complaintKeywordFrequency42 / {"dirty":12,"noise":9}keyword hits, rolled up per listing
reviewLanguages["en","es"]languages seen among kept reviews
appliedReviewFilters{maxReviewRating, reviewTag, reviewSearchText, reviewSortBy, onlyComplaintKeywordMatches, complaintKeywords}exact filter values used for this run, echoed for audit
type / isChild / parentId"listing" / false / nullrow-type discriminators

Guest review fields (child rows)

FieldExample ValueUse Case
type / isChild / parentId"review" / true / "12937"row-type discriminators, parentId joins to the listing
listingId / listingTitle / listingUrl / requestedUrlcopied from the parentdenormalized for standalone filtering of the review table
reviewId987654321Airbnb's review ID
reviewRating21–5 star rating
reviewText / reviewTextTranslated"The room smelled of mold and the AC was broken."guest's own words / Airbnb's translation, if any
reviewLanguage"en"language of the review
reviewCreatedAt / reviewLocalizedDateISO date / "August 2026"raw timestamp and Airbnb's display date
reviewerName / reviewerId / reviewerContextualUserId"Alex" / "98765"reviewer identity
reviewerProfileUrl / reviewerProfileImageURLreviewer's public profile link and avatar
reviewerLocation"Austin, Texas"reviewer's self-reported location
hostResponse / hostResponseDate / hasHostResponse"We apologize and refunded the cleaning fee."host's public reply, if any
reviewHighlight / reviewHighlightTypeAirbnb-generated snippetAirbnb's own auto-highlighted excerpt
ratingAccessibilityLabel"Rated 2 out of 5 stars"Airbnb's screen-reader label for the rating
complaintKeywordHits / complaintKeywordHitCount / hasComplaintKeywordHit["dirty","broken"] / 2 / truewhich of your complaintKeywords matched
isLowRatingtruewhether this review is at or below maxReviewRating
scrapedAtISO 8601 UTCwhen this Actor wrote the row

Guest reviews and star ratings

Each review row carries reviewRating (1–5), the review text itself (reviewText, plus reviewTextTranslated when Airbnb serves one), the reviewer's display name and profile link, and the host's public hostResponse text where one exists. The parent listing row rolls every kept review into reviewRatingBreakdown — a count per star, 1 through 5 — plus hostResponseRate and complaintKeywordFrequency. A concrete use: filter listings where hostResponseRate is below 0.5, a proxy for hosts who habitually ignore guest complaints, entirely from the parent rows without opening a single review.

Filtering and targeting fields

startUrls accepts a direct room URL or ID for a surgical single-listing pull, or a bare keyword (a city, neighbourhood or property style) resolved through Airbnb's own search for up to 20 matching listings. reviewTag narrows to one of Airbnb's own topic buckets (CLEANLINESS, LOCATION, AMENITIES, and others — the tags a given listing actually has, with counts, come back in reviewTagsAvailable). reviewSearchText runs Airbnb's server-side full-text review search. maxReviewRating sets the star ceiling that decides which reviews count as "complaints" in the first place.

Why not build this yourself?

Airbnb's room and review data isn't exposed through a general-purpose public API, so a DIY pull means reverse-engineering the same internal web endpoints this Actor already handles.

Three things break a first attempt fast:

  • TLS fingerprinting. Airbnb's edge inspects the TLS handshake itself, not just the headers. This Actor impersonates a real Chrome 131 fingerprint (via curl_cffi) on every request; a plain requests/httpx client typically gets an HTTP 200 shell page with no data container instead of the real listing.
  • The reviews endpoint is an undocumented GraphQL persisted query. Its operation hash lives in a versioned JS bundle that Airbnb rotates over time. This Actor extracts the current hash from the room page's own JS chunk at run time, and only falls back to a pinned hash (last verified against the live bundle on 2026-08-02) if that discovery fails — logging a loud warning when it does.
  • Blocked and genuinely unavailable look identical at first glance. A refused exit IP and a de-listed room both answer HTTP 200 — one as an interstitial shell, the other as a well-formed but empty payload. Treating them the same either burns proxy escalation on a room that was never coming back, or silently drops a room that just needed a better IP. This Actor checks for the actual result container to tell the two apart, and only escalates proxies (datacenter, then residential) for the former.

Add non-English locale handling — Airbnb serves a signed POST handoff to a country subdomain instead of the page for most locales — and pagination that has to track review counts across up to 200 pages per listing, and a weekend script turns into an ongoing maintenance job. This Actor exists so you don't re-build and re-tune all of it.

How to use data extracted from Airbnb?

Property managers and hospitality operators

Set maxReviewRating to 3 or 4 and leave complaintKeywords at its default list (dirty, smell, noise, broken, mold, bug, rude, cold, leak, refund, cancel, and more) to get a standing complaint feed for a portfolio of listings. The output's hostResponse and hostResponseRate fields show which properties are being answered and which are being ignored, and lowestRatedCategory on the parent row points straight at the category (cleanliness, communication, location…) dragging a listing's score down — before it shows up as a public 3-star average.

Agencies and consultants auditing client portfolios

Run the same startUrls list on a schedule and diff complaintKeywordFrequency and averageScrapedReviewRating run over run to benchmark a client's properties against each other, or re-run with enrichHostAndCoHostProfiles on to attach superhost status and tenure to a competitive audit deliverable.

Market research and intelligence

Point startUrls at a city or neighbourhood keyword instead of a room URL to pull a market sample through Airbnb's own search (capped at 20 listings per keyword), then aggregate reviewTagsAvailable and rating.* category scores across the sample to map where a submarket's guest complaints cluster — cleanliness in one neighbourhood, noise in another.

AI agents and automated pipelines

complaintKeywordHits and isLowRating are pre-computed per review, so an agent or pipeline can act on them directly — routing a listing into a ticketing system, a Slack alert, or a RAG index of guest sentiment — without re-implementing keyword matching downstream.

🔼 Input sample

Only startUrls is required; every other field has a working default.

ParameterRequiredTypeDescriptionExample Value
startUrlsYesarrayOne or more Airbnb room URLs or bare room IDs. Non-URL entries are resolved via Airbnb search (up to 20 results each). Default: two sample room URLs.["https://www.airbnb.com/rooms/12937"]
maxItemsNointegerCaps parent listing rows only; review rows are capped separately. 0 = every listing supplied. Minimum 0. Default 0.50
scrapeReviewsNobooleanFetches review text and metadata, not just a count. One extra request per 50 reviews. Default true.true
maxReviewRatingNointegerKeeps reviews at or below this star rating. Minimum 1, maximum 5. Applied after Airbnb returns each page. Default 4.3
reviewSortByNostring (enum)Order reviews are requested from Airbnb: lowest-rated, most-recent, most-relevant, highest-rated. Default lowest-rated."lowest-rated"
maxReviewsPerListingNointegerStops after this many kept reviews per listing (counted after rating and keyword filters). Minimum 0, maximum 1000. 0 = every matching review. Default 100.200
reviewTagNostringOnly reviews under this Airbnb topic tag (e.g. CLEANLINESS, LOCATION). An unknown tag returns zero reviews silently. Default "" (no filter)."CLEANLINESS"
reviewSearchTextNostringAirbnb's own server-side full-text review search. Default "" (no filter)."mold"
complaintKeywordsNoarrayWords flagged in review text, case-insensitively, with short suffix tolerance. Clear the list to disable flagging. Default: ["dirty","smell","noise","broken","mold","mould","bug","rude","cold","leak","refund","cancel"].["mold","refund"]
onlyComplaintKeywordMatchesNobooleanDrop kept reviews that hit none of complaintKeywords. Default false.false
enrichHostAndCoHostProfilesNobooleanFetches and attaches the host's public profile (one extra request). Falls back to enrichUserProfiles if unset. Default false.false
enrichUserProfilesNobooleanLegacy alias for enrichHostAndCoHostProfiles, kept for backward compatibility. Only used if the preferred key is unset. Default false.false
checkInNostringCheck-in date, YYYY-MM-DD. Sent to Airbnb as check_in. Invalid formats are ignored (logged), not fatal."2026-09-01"
checkOutNostringCheck-out date, YYYY-MM-DD. Sent to Airbnb as check_out."2026-09-05"
adultsNointegerParty size sent with the listing request. Minimum 1.2
childrenNointegerChildren in the party. Minimum 0.0
infantsNointegerInfants under 2. Minimum 0.0
petsNointegerService animals / pets. Minimum 0.0
localeNostring (enum)Language/region for the listing page and review request; 89 locale options. Default en-US. Examples: en-GB, es-ES, fr-FR, de-DE, ja-JP. Full list in the Actor's input editor."en-US"
currencyNostring (enum)Currency header sent with every request; 47 currency options. Default USD. Examples: EUR, GBP, CAD, AUD. Full list in the Actor's input editor."USD"
proxyConfigurationNoobjectLeave default to auto-escalate none → datacenter → residential on a blocked page. Set a group or your own proxy URLs to use them for every request instead. Default {"useApifyProxy": false}.{"useApifyProxy": true}
{
"startUrls": ["https://www.airbnb.com/rooms/12937", "https://www.airbnb.com/rooms/53997462"],
"maxItems": 0,
"scrapeReviews": true,
"maxReviewRating": 3,
"reviewSortBy": "lowest-rated",
"maxReviewsPerListing": 200,
"reviewTag": "",
"reviewSearchText": "",
"complaintKeywords": ["dirty", "smell", "noise", "broken", "mold", "bug", "refund"],
"onlyComplaintKeywordMatches": false,
"enrichHostAndCoHostProfiles": false,
"locale": "en-US",
"currency": "USD",
"proxyConfiguration": { "useApifyProxy": true }
}

Common pitfall: reviewTag only accepts the exact tag string a listing actually carries — an unrecognized or misspelled value (e.g. "clean" instead of "CLEANLINESS") returns zero reviews with no error. Run once with reviewTag empty, read the listing row's reviewTagsAvailable column for that listing's real tags and counts, then re-run with the exact value. Separately, keep locale on an English variant unless you've verified another one works for your target listings — Airbnb serves a domain-switch redirect instead of the listing page for most non-English locales, which produces no row for that URL at all.

🔽 Output sample

Output is a single Apify dataset holding both row types (listing and review), typed and normalized on every run. Export it as JSON, CSV, Excel or XML directly from the Apify Console or API — no extra configuration needed.

Listing row (trimmed — nested arrays shown with one sample element):

{
"id": "12937",
"listingId": "12937",
"type": "listing",
"isChild": false,
"parentId": null,
"listingTitle": "Sunny room in the heart of downtown",
"listingUrl": "https://www.airbnb.com/rooms/12937",
"url": "https://www.airbnb.com/rooms/12937?locale=en-US&currency=USD",
"propertyType": "Entire rental unit",
"roomType": "entire_home",
"personCapacity": 4,
"location": "New York, United States",
"coordinates": { "latitude": 40.7128, "longitude": -74.006 },
"rating": {
"accuracy": 4.6,
"checking": 4.7,
"cleanliness": 4.3,
"communication": 4.8,
"location": 4.9,
"value": 4.5,
"guestSatisfaction": 4.7,
"reviewsCount": 312
},
"lowestRatedCategory": "cleanliness",
"lowestRatedCategoryScore": 4.3,
"host": {
"id": "50124",
"name": "Maria",
"isSuperHost": true,
"ratingCount": 312,
"ratingAverage": 4.85
},
"images": [{ "caption": "Living room", "imageUrl": "https://a0.muscache.com/...", "orientation": "LANDSCAPE" }],
"amenities": [{ "title": "Bathroom", "values": [{ "title": "Hair dryer", "icon": "ICON", "available": true }] }],
"reviewsCountTotal": 312,
"reviewsFetched": 140,
"reviewsFilteredOut": 40,
"reviewsStatus": "ok",
"reviewTagsAvailable": [{ "name": "CLEANLINESS", "localizedName": "Cleanliness", "count": 28 }],
"reviewsScraped": 100,
"lowRatingReviewsCount": 76,
"reviewRatingBreakdown": { "1": 10, "2": 20, "3": 30, "4": 25, "5": 15 },
"averageScrapedReviewRating": 2.9,
"hostResponseCount": 18,
"hostResponseRate": 0.18,
"complaintKeywordMatchCount": 42,
"complaintKeywordFrequency": { "dirty": 12, "noise": 9, "broken": 7 },
"appliedReviewFilters": {
"maxReviewRating": 3,
"reviewTag": null,
"reviewSearchText": null,
"reviewSortBy": "RATING_ASC",
"onlyComplaintKeywordMatches": false,
"complaintKeywords": ["dirty", "smell", "noise", "broken", "mold", "bug", "refund"]
},
"scrapedAt": "2026-08-04T12:00:03Z"
}

Review row (trimmed):

{
"type": "review",
"isChild": true,
"parentId": "12937",
"listingId": "12937",
"listingTitle": "Sunny room in the heart of downtown",
"listingUrl": "https://www.airbnb.com/rooms/12937",
"reviewId": 987654321,
"reviewRating": 2,
"reviewText": "The room smelled of mold and the AC was broken the entire stay.",
"reviewLanguage": "en",
"reviewLocalizedDate": "August 2026",
"reviewerName": "Alex",
"reviewerProfileUrl": "https://www.airbnb.com/users/show/98765",
"reviewerLocation": "Austin, Texas",
"hostResponse": "We apologize and refunded the cleaning fee.",
"hasHostResponse": true,
"complaintKeywordHits": ["mold", "broken"],
"complaintKeywordHitCount": 2,
"hasComplaintKeywordHit": true,
"isLowRating": true,
"scrapedAt": "2026-08-04T12:00:03Z"
}

⚠️ Billing note: every pushed row — both listing rows and review rows — is charged under the single row_result pay-per-event. Listings that come back blocked or de-listed push no row at all (they're skipped, not charged), so a failed URL is invisible in the dataset rather than appearing as an error row; check the run log for FAILED / UNAVAILABLE entries if you need to know which inputs didn't produce data.

How do you filter and target specific listings?

Four real controls decide what ends up in the dataset. Scope: startUrls takes either a precise room URL/ID for a single audited listing, or a bare keyword resolved through Airbnb's own search for a broader sample (capped at 20 results per keyword — there is no way to raise this from the input). Topic precision: reviewTag and reviewSearchText are both sent to Airbnb's servers, so they narrow the result set (and therefore the run's cost and time) before a single review is downloaded — an unrecognized tag simply returns nothing. Quality threshold: maxReviewRating is the ceiling that defines a "complaint" for this run — set it to 3 for hard negatives only, leave it at the default 4 to catch everything below Airbnb's typical ~4.8★ average, or raise it to 5 to keep every review. Volume: maxItems caps listings, maxReviewsPerListing caps kept reviews per listing (up to the hard ceiling of 1000), and reviews are paginated 50 at a time up to 200 pages — with reviewSortBy left on lowest-rated, the run stops early the moment a full page comes back entirely above your rating ceiling, so a capped budget is spent on the worst reviews first.

Three real targeting examples:

{ "startUrls": ["https://www.airbnb.com/rooms/12937"], "maxReviewRating": 3, "maxReviewsPerListing": 500 }

A single-listing deep audit: only hard negatives (3★ and below), up to 500 of them.

{ "startUrls": ["downtown Austin"], "reviewTag": "CLEANLINESS", "maxReviewRating": 4 }

A neighbourhood-level sample (resolved via Airbnb search, up to 20 listings), narrowed to cleanliness-tagged complaints across all of them.

{ "startUrls": ["https://www.airbnb.com/rooms/53997462"], "complaintKeywords": ["mold", "bug", "refund"], "onlyComplaintKeywordMatches": true }

A pure keyword report: only reviews that actually mention mold, bugs, or a refund — everything else dropped, regardless of star rating.

▶️ Want to try other travel and review scrapers?

ScraperWhat it extracts
TripAdvisor Review Scraper — Photo & Visual Content FiltersHotel reviews with ratings, reviewer profiles, owner responses, and photo-content filters
Google Maps Extractor with Reservation & Order Online LinksGoogle Maps places plus the online-booking platform and deep link behind each one

How to extract Airbnb data programmatically

This Actor runs as a standard Apify Actor: one API call starts it, one API call reads the finished dataset back as JSON.

Python example

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("<store-username>/airbnb-rooms-urls-scraper-and-guest-complaint-reviews").call(
run_input={
"startUrls": ["https://www.airbnb.com/rooms/12937"],
"maxReviewRating": 3,
"complaintKeywords": ["mold", "noise", "refund"],
}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item.get("type") == "review":
print(item["reviewRating"], item["reviewText"], item.get("hostResponse"))

Export to spreadsheets or CRM

Download the dataset directly as CSV or Excel from the Apify Console (or via the API's items?format=csv endpoint) and map columns straight in: listingTitle and listingUrl identify the property, reviewRating and reviewText are the review body, hostResponse is the reply, and complaintKeywordHits lists which flagged words matched — ready to import into a spreadsheet or a CRM's custom-fields import.

Yes — scraping publicly accessible Airbnb listing and review pages is generally legal; this Actor only reads pages Airbnb serves to any visitor, the same content anyone can see in a browser without logging in. Guest reviews, however, contain personal data — reviewer names, host names, host replies and reviewer-supplied locations — so GDPR (if you or your data subjects are in the EU/UK) and CCPA (California) obligations attach to how you store, use and retain that data, not to the act of reading a public page. Keep collection proportionate to your purpose and be ready to honor deletion or access requests for any personal data you retain. Consult legal counsel for commercial applications involving bulk storage of personal data.

❓ FAQ

What happens if a listing is de-listed or no longer bookable?

The Actor pushes no row at all for that URL. A de-listed, private or removed room returns a well-formed but empty Airbnb payload; the Actor detects this and logs an UNAVAILABLE line rather than writing a blank or broken row, so the dataset never carries a placeholder for a dead listing.

Can I get guest reviews along with the listing data?

Yes, by default (scrapeReviews: true). Reviews come back as child rows with reviewText, reviewRating, reviewerName, reviewLocalizedDate, and hostResponse. The one caveat: maxReviewsPerListing (default 100, hard maximum 1000) caps how many kept reviews come back per listing, counted after your rating and keyword filters are applied.

How accurate is the review and rating data?

The Actor returns review text, star ratings and host replies exactly as Airbnb's server answers at request time — it doesn't re-score or interpret anything. Accuracy of the underlying content depends on Airbnb and the reviewer/host keeping it current; treat scrapedAt as the freshness timestamp for any downstream reporting.

How many listings and reviews can I get per run?

Listings: maxItems defaults to 0 (every URL you supply, no cap); there is no other listing ceiling for direct room URLs. If you supply a keyword instead of a URL, Airbnb's search resolution is capped at 20 listings per keyword — a hard-coded limit, not adjustable from the input. Reviews: maxReviewsPerListing defaults to 100 kept reviews per listing and cannot be raised past 1000; set it to 0 to keep every review that passes your other filters instead.

How do I filter reviews down to just the complaints?

Combine maxReviewRating (the star ceiling — try 3 for hard negatives) with complaintKeywords and set onlyComplaintKeywordMatches: true to drop anything that doesn't mention one of your words. reviewTag and reviewSearchText narrow further on Airbnb's own server before any of that local filtering runs.

Does the Airbnb Review Scraper work with Claude, ChatGPT and AI agent frameworks?

It has no dedicated MCP server integration documented at this time. Any agent framework that can call an HTTP endpoint — via the Apify API or the apify_client SDK — can start a run and read the resulting dataset back as JSON, the same way the Python example above does.

How does this compare to other Airbnb review scrapers?

Compare any Airbnb scraper on three concrete axes: does it return the review text itself or only a count; does it filter by star rating, topic tag and full text on Airbnb's own server (cutting cost and time) rather than downloading everything and filtering locally; and does it expose Airbnb's own per-listing review topic tags (reviewTagsAvailable) so you know what filters are even available before you run one. This Actor does all three, sourced directly from the listing's own review payload.

Can I use this without an Airbnb account or API key?

Yes. The Actor reads Airbnb's public listing and review pages directly; no Airbnb login, account or API key is needed. You only need an Apify account to run the Actor itself.

Conclusion

The Airbnb Review Scraper turns a list of room URLs into structured listing and review data — worst reviews first, complaint keywords flagged, host replies included — without you touching Airbnb's anti-bot layer, its undocumented review API, or its locale handling. It's built for anyone who needs guest sentiment at scale: property managers, agencies auditing portfolios, and researchers mapping complaint patterns across a market. Paste in a room URL or a neighbourhood keyword and start a run on the Apify platform to see the first rows land in your dataset.