Airbnb Review Scraper With Topic & Keyword Filters avatar

Airbnb Review Scraper With Topic & Keyword Filters

Pricing

from $5.99 / 1,000 results

Go to Apify Store
Airbnb Review Scraper With Topic & Keyword Filters

Airbnb Review Scraper With Topic & Keyword Filters

Airbnb Review Scraper extracts Airbnb reviews with topic and keyword filters, including ratings, review text, dates, reviewer details, property information, and sentiment insights. Ideal for guest feedback analysis, property research, competitor monitoring, and hospitality insights.

Pricing

from $5.99 / 1,000 results

Rating

0.0

(0)

Developer

Scrapier

Scrapier

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

0

Monthly active users

3 days ago

Last modified

Share

Airbnb Review Scraper โ€” Reviews by Topic, Keyword and Topic Breakdown

Collect Airbnb reviews for any listing, narrowed by Airbnb's own review topics (Cleanliness, Location, Check-in and 16 more), by a free-text keyword, or by both โ€” and get every review returned as clean, structured JSON. Every response is ready to pass directly to an LLM, index into a vector store, or feed a monitoring pipeline. Alongside individual reviews, each listing's full topic distribution โ€” every topic Airbnb offers for it, the review count behind each one, and its share of the listing's total โ€” is published as its own row, computed straight from the listing rather than estimated from the reviews collected.

What is Airbnb Review Scraper With Topic & Keyword Filters?

It is an Apify Actor that takes one or more Airbnb listing addresses or numeric listing IDs and returns their guest reviews, narrowed however you choose: by Airbnb's own review topics, by a keyword that must actually appear in the review text, or by the overlap of both. No Airbnb account or login is required โ€” the Actor reads the same public listing pages and review feed any visitor's browser reaches. What sets it apart from a plain keyword-search review scraper is the topic side: it can request reviews the way Airbnb itself files them (Cleanliness, Location, Check-in, and 16 other topics), and it always has the option to publish the listing's complete topic table โ€” every topic, its count, and its percentage share โ€” as a separate row, whether or not you filter by topic at all.

  • ๐Ÿก Collects reviews from one or many listings in a single run, given as URLs or bare numeric IDs
  • ๐ŸŽฏ Filters reviews by any combination of 19 official Airbnb review topics
  • ๐Ÿ” Filters reviews by a keyword or phrase that must appear in the review text
  • ๐Ÿงฉ Combines both filters as an intersection, or runs either one alone
  • ๐Ÿ“Š Publishes each listing's full topic distribution (count + share %) as its own row
  • โ†•๏ธ Controls review order (newest first, Airbnb's own ranking, or by rating) and review language

What data can you get with Airbnb Review Scraper?

The Actor returns three row types in one dataset: individual reviews, each listing's topic breakdown, and a status row for any listing that could not be read or any input that was not a listing at all.

Result TypeExtracted FieldsPrimary Use Case
Review (type: "review")id, text, textRaw, localizedText, localizedDate, createdAt, rating, ratingValue, response, reviewHighlight, reviewer object, reviewee (host) object, matchedTopic, matchedTopicLabel, topicMatchTotal, searchTermMatched, matchingReviewTotalReview-level sentiment, topic and keyword analysis for one listing
Topic breakdown (type: "listingTopics")reviewTagBreakdown (per-topic count and share), topicsAvailable, topicsAvailableCount, topicSummary, listingReviewTotalSeeing which topics dominate a listing's reviews without reading a single review
Listing status (type: "listingStatus")listingStatus, input, success, errorDiagnosing which listings or inputs produced no review rows, and why

Topic breakdown

This is the row every other filter option feeds back into: set emitTopicBreakdownRow (on by default) and the Actor adds one row per listing carrying every review topic Airbnb offers for that specific listing โ€” not the whole 19-topic vocabulary, only the subset that listing actually uses โ€” with the real review count behind each topic and its share of the listing's total. The counts come straight from the listing's own metadata, not from tallying the reviews the run happened to collect, so the breakdown is accurate even if maxReviewsPerListing caps the reviews you actually receive.

{
"type": "listingTopics",
"roomId": "12937",
"listingReviewTotal": 214,
"reviewTagBreakdown": [
{ "tag": "CLEANLINESS", "label": "Cleanliness", "count": 61, "sharePct": 28.5 },
{ "tag": "LOCATION", "label": "Location", "count": 88, "sharePct": 41.12 },
{ "tag": "CHECK_IN", "label": "Check-in", "count": 19, "sharePct": 8.88 }
],
"topicsAvailable": ["CLEANLINESS", "LOCATION", "CHECK_IN"],
"topicsAvailableCount": 3,
"topicSummary": "Cleanliness 61 (28.5%) | Location 88 (41.12%) | Check-in 19 (8.88%)"
}

Review match provenance

Every review row carries not just its text but the reason it was returned: matchedTopic and matchedTopicLabel name the Airbnb topic it was fetched under (or null for an unfiltered pass), searchTermMatched is true/false/null depending on whether a keyword filter applied, and topicMatchTotal / matchingReviewTotal carry the listing's own count for that specific filter. This makes it possible to tell, from the row alone, exactly which of your filters a given review satisfied.

Why not build this yourself?

Airbnb does not publish a public API for review data. Airbnb's developer API is restricted to its Preferred Software Partner program and does not expose review content for arbitrary listings (verified against Airbnb API documentation and third-party API guides, 2026-08-15). Reading reviews programmatically means going through the same internal web endpoint the airbnb.com site itself uses โ€” which requires resolving a persisted GraphQL query ID out of a JavaScript bundle that changes with each frontend deploy, carrying a web client key, and handling the block pages Airbnb serves to automated traffic. This Actor does that resolution and retry handling on every run: it discovers the current review-query bundle, extracts the API key, retries transient failures with backoff, and escalates to a more resilient connection route if a listing is slow or refused, all without exposing any of that machinery to you. Building and maintaining this yourself means re-discovering the bundle URL and query ID every time Airbnb ships a frontend change, which is exactly the maintenance burden this Actor absorbs.

How to scrape Airbnb reviews with this Actor

  1. Open Airbnb Review Scraper With Topic & Keyword Filters on the Apify Store and click Try for free (or Run, if you already have it).
  2. Enter one or more listing addresses or numeric IDs in Airbnb Listings (startUrls) โ€” e.g. https://www.airbnb.com/rooms/12937.
  3. Optionally narrow results: pick one or more Review Topics (reviewTopics), enter a Keyword Inside The Reviews (reviewSearchQuery), and choose How To Combine Topic & Keyword (matchMode).
  4. Set Reviews Per Listing (maxReviewsPerListing), Review Order (sortOrder) and Review Language (reviewLanguage) as needed, then start the run.
  5. Download the results from the Dataset tab as JSON, CSV, Excel, or any other export format Apify offers, or pull them programmatically with apify_client.

How to run multiple listings in one job

Add every listing you want as separate entries in Airbnb Listings (startUrls) โ€” or split them between startUrls and the Extra Listings field (listingUrls); the two are merged and de-duplicated by listing ID, so the same listing given twice is only collected once. The Actor works through the merged list one listing at a time, in the order supplied, publishing that listing's rows before moving to the next.

โฌ‡๏ธ Input

The only required field is startUrls. Everything else narrows or adjusts what comes back.

ParameterRequiredTypeConstraintsDescription
startUrlsYesarray of stringsโ€”One or more Airbnb listing addresses (https://www.airbnb.com/rooms/12937) or bare numeric listing IDs (12937). Anything that is not a listing is reported as an unsupported input row instead of being guessed at.
listingUrlsNoarray of stringsโ€”Additional listing addresses or IDs. Merged with startUrls and de-duplicated.
reviewTopicsNoarray of strings (enum)see full list belowKeep only reviews Airbnb itself files under the selected topics. Leave empty for every review. A topic a listing does not use returns an honest zero for that listing, never an error.
reviewSearchQueryNostringโ€”Keep only reviews that mention this word or phrase, e.g. parking, wifi, noise. Every returned review really contains the term.
matchModeNostring (enum)default topicThenTexttopicThenText โ€” topics, then keep only reviews that also contain the keyword (the overlap of both). topicOnly โ€” ignore the keyword. textOnly โ€” ignore the topics.
emitTopicBreakdownRowNobooleanprefill trueAdds one extra row per listing (type: "listingTopics") with every topic Airbnb offers for it, the count behind each, and its share of the listing's total.
maxReviewsPerListingNointegermin 1, max 10000, prefill 25Maximum review rows per listing, counted separately for each selected topic. 25 with Cleanliness and Location selected returns up to 25 cleanliness reviews and up to 25 location reviews.
maxCommentsNointegermin 1, max 10000, default 10Legacy key kept for input built against the original scraper. Used only when maxReviewsPerListing is left empty.
sortOrderNostring (enum)default MOST_RECENTMOST_RECENT (newest first, recommended), BEST_QUALITY (Airbnb's own ranking), RATING_DESC (highest rated first), RATING_ASC (lowest rated first).
reviewLanguageNostring (enum)prefill en-USLanguage for localized review content and dates โ€” see full list below.
localeNostringdefault en-USLegacy key kept for input built against the original scraper. Used only when reviewLanguage is left empty.
proxyConfigurationNoobjecteditor proxyOptional connection settings. The run starts on a direct connection and moves to a more resilient route on its own if a listing is slow to answer.

reviewTopics full enum: ACCESS, BATHROOM, CHECK_IN, CLEANLINESS, COMFORT, DECOR, GETTING_AROUND, GRILL, HOSPITALITY, HOT_TUB, INDOOR_SPACES, LOCATION, NEARBY, PARKING, POOL, SLEEP, VALUE, VIEW, WALKABILITY (Access, Bathroom, Check-in, Cleanliness, Comfort, Decor, Getting around, Grill, Hospitality, Hot tub, Indoor spaces, Location, Nearby, Parking, Pool, Sleep quality, Value, View, Walkability).

reviewLanguage full enum: en-US (English), de-DE (German), es-ES (Spanish), fr-FR (French), it-IT (Italian), pt-PT (Portuguese), nl-NL (Dutch), da-DK (Danish), cs-CZ (Czech), hr-HR (Croatian), id-ID (Indonesian), ca-ES (Catalan), et-EE (Estonian), ga-IE (Irish), az-AZ (Azerbaijani), bs-BA (Bosnian), xh-ZA (Xhosa), zu-ZA (Zulu).

Example input:

{
"startUrls": ["https://www.airbnb.com/rooms/12937"],
"reviewTopics": ["CLEANLINESS", "LOCATION"],
"reviewSearchQuery": "wifi",
"matchMode": "topicThenText",
"emitTopicBreakdownRow": true,
"maxReviewsPerListing": 25,
"sortOrder": "MOST_RECENT",
"reviewLanguage": "en-US",
"proxyConfiguration": { "useApifyProxy": true }
}

โš ๏ธ Common pitfall: maxReviewsPerListing applies per selected topic, not per listing. Selecting four topics with the cap set to 25 can return up to 100 review rows for one listing โ€” one budget of 25 for each topic, not 25 split across all of them.

โฌ†๏ธ Output

Results are pushed to the Actor's dataset as typed, normalized JSON โ€” one row per review, plus one topic-breakdown row and one status row where applicable. Export as JSON, CSV, Excel, XML, RSS or HTML directly from the Dataset tab, or pull rows programmatically with apify_client.

Scraped results

[
{
"type": "review",
"roomId": "12937",
"startUrl": "https://www.airbnb.com/rooms/12937",
"reviewUrl": "https://www.airbnb.com/rooms/12937/reviews",
"listingStatus": "ok",
"locale": "en-US",
"id": "987654321",
"language": "en",
"text": "Spotless apartment, walking distance to everything.\nWould stay again.",
"textRaw": "Spotless apartment, walking distance to everything.<br/>Would stay again.",
"localizedText": "Spotless apartment, walking distance to everything.\nWould stay again.",
"localizedReview": null,
"localizedDate": "March 2026",
"localizedReviewerLocation": "London, United Kingdom",
"createdAt": "2026-03-14T10:02:00Z",
"reviewHighlight": null,
"highlightType": null,
"rating": "5",
"ratingValue": 5,
"response": null,
"ratingAccessibilityLabel": "Rated 5 out of 5 stars",
"matchMode": "topicThenText",
"reviewTopicsRequested": ["CLEANLINESS", "LOCATION"],
"matchedTopic": "CLEANLINESS",
"matchedTopicLabel": "Cleanliness",
"topicMatchTotal": 61,
"reviewSearchQuery": "wifi",
"isSearchResult": false,
"searchTermMatched": false,
"matchingReviewTotal": null,
"listingReviewTotal": 214,
"scrapedAt": "2026-08-15T09:00:00Z",
"reviewer": {
"id": "112233",
"firstName": "Priya",
"hostName": null,
"pictureUrl": "https://a0.muscache.com/im/pictures/user/example.jpg",
"profilePath": "/users/show/112233",
"profilePicture": "https://a0.muscache.com/im/pictures/user/example.jpg"
},
"reviewerId": "112233",
"reviewerName": "Priya",
"reviewerProfileUrl": "https://www.airbnb.com/users/show/112233",
"reviewee": {
"id": "556677",
"firstName": "Marco",
"hostName": "Marco",
"pictureUrl": "https://a0.muscache.com/im/pictures/user/example2.jpg",
"profilePath": "/users/show/556677",
"profilePicture": "https://a0.muscache.com/im/pictures/user/example2.jpg"
},
"hostId": "556677",
"hostName": "Marco",
"hostProfileUrl": "https://www.airbnb.com/users/show/556677"
},
{
"type": "review",
"roomId": "12937",
"startUrl": "https://www.airbnb.com/rooms/12937",
"reviewUrl": "https://www.airbnb.com/rooms/12937/reviews",
"listingStatus": "ok",
"locale": "en-US",
"id": "987654322",
"language": "en",
"text": "Wifi was slow in the evenings but the location made up for it.",
"textRaw": "Wifi was slow in the evenings but the location made up for it.",
"localizedText": "Wifi was slow in the evenings but the location made up for it.",
"localizedReview": null,
"localizedDate": "February 2026",
"localizedReviewerLocation": "Berlin, Germany",
"createdAt": "2026-02-02T18:44:00Z",
"reviewHighlight": null,
"highlightType": null,
"rating": "4",
"ratingValue": 4,
"response": "Thanks for the feedback, we've upgraded the router since.",
"ratingAccessibilityLabel": "Rated 4 out of 5 stars",
"matchMode": "topicThenText",
"reviewTopicsRequested": ["CLEANLINESS", "LOCATION"],
"matchedTopic": "LOCATION",
"matchedTopicLabel": "Location",
"topicMatchTotal": 88,
"reviewSearchQuery": "wifi",
"isSearchResult": false,
"searchTermMatched": true,
"matchingReviewTotal": null,
"listingReviewTotal": 214,
"scrapedAt": "2026-08-15T09:00:00Z",
"reviewer": {
"id": "334455",
"firstName": "Jonas",
"hostName": null,
"pictureUrl": "https://a0.muscache.com/im/pictures/user/example3.jpg",
"profilePath": "/users/show/334455",
"profilePicture": "https://a0.muscache.com/im/pictures/user/example3.jpg"
},
"reviewerId": "334455",
"reviewerName": "Jonas",
"reviewerProfileUrl": "https://www.airbnb.com/users/show/334455",
"reviewee": {
"id": "556677",
"firstName": "Marco",
"hostName": "Marco",
"pictureUrl": "https://a0.muscache.com/im/pictures/user/example2.jpg",
"profilePath": "/users/show/556677",
"profilePicture": "https://a0.muscache.com/im/pictures/user/example2.jpg"
},
"hostId": "556677",
"hostName": "Marco",
"hostProfileUrl": "https://www.airbnb.com/users/show/556677"
},
{
"type": "review",
"roomId": "12937",
"startUrl": "https://www.airbnb.com/rooms/12937",
"reviewUrl": "https://www.airbnb.com/rooms/12937/reviews",
"listingStatus": "ok",
"locale": "en-US",
"id": "987654323",
"language": "en",
"text": "Great location, five minutes from the metro.",
"textRaw": "Great location, five minutes from the metro.",
"localizedText": "Great location, five minutes from the metro.",
"localizedReview": null,
"localizedDate": "January 2026",
"localizedReviewerLocation": "Madrid, Spain",
"createdAt": "2026-01-20T08:15:00Z",
"reviewHighlight": null,
"highlightType": null,
"rating": "5",
"ratingValue": 5,
"response": null,
"ratingAccessibilityLabel": "Rated 5 out of 5 stars",
"matchMode": "topicThenText",
"reviewTopicsRequested": ["CLEANLINESS", "LOCATION"],
"matchedTopic": "LOCATION",
"matchedTopicLabel": "Location",
"topicMatchTotal": 88,
"reviewSearchQuery": "wifi",
"isSearchResult": false,
"searchTermMatched": false,
"matchingReviewTotal": null,
"listingReviewTotal": 214,
"scrapedAt": "2026-08-15T09:00:00Z",
"reviewer": {
"id": "556688",
"firstName": "Elena",
"hostName": null,
"pictureUrl": "https://a0.muscache.com/im/pictures/user/example4.jpg",
"profilePath": "/users/show/556688",
"profilePicture": "https://a0.muscache.com/im/pictures/user/example4.jpg"
},
"reviewerId": "556688",
"reviewerName": "Elena",
"reviewerProfileUrl": "https://www.airbnb.com/users/show/556688",
"reviewee": {
"id": "556677",
"firstName": "Marco",
"hostName": "Marco",
"pictureUrl": "https://a0.muscache.com/im/pictures/user/example2.jpg",
"profilePath": "/users/show/556677",
"profilePicture": "https://a0.muscache.com/im/pictures/user/example2.jpg"
},
"hostId": "556677",
"hostName": "Marco",
"hostProfileUrl": "https://www.airbnb.com/users/show/556677"
},
{
"type": "listingTopics",
"roomId": "12937",
"startUrl": "https://www.airbnb.com/rooms/12937",
"reviewUrl": "https://www.airbnb.com/rooms/12937/reviews",
"listingStatus": "ok",
"locale": "en-US",
"listingReviewTotal": 214,
"reviewTagBreakdown": [
{ "tag": "CLEANLINESS", "label": "Cleanliness", "count": 61, "sharePct": 28.5 },
{ "tag": "LOCATION", "label": "Location", "count": 88, "sharePct": 41.12 }
],
"topicsAvailable": ["CLEANLINESS", "LOCATION"],
"topicsAvailableCount": 2,
"topicSummary": "Cleanliness 61 (28.5%) | Location 88 (41.12%)",
"matchMode": "topicThenText",
"reviewTopicsRequested": ["CLEANLINESS", "LOCATION"],
"reviewSearchQuery": "wifi",
"scrapedAt": "2026-08-15T09:00:00Z"
},
{
"type": "listingStatus",
"roomId": null,
"startUrl": "https://www.airbnb.com/wishlists/some-list",
"reviewUrl": null,
"listingStatus": "unsupportedInput",
"locale": "en-US",
"listingReviewTotal": null,
"matchMode": "topicThenText",
"reviewTopicsRequested": ["CLEANLINESS", "LOCATION"],
"reviewSearchQuery": "wifi",
"input": "https://www.airbnb.com/wishlists/some-list",
"success": false,
"error": "Only Airbnb listing addresses or numeric listing ids are supported.",
"scrapedAt": "2026-08-15T09:00:00Z"
}
]

The Actor also writes a RUN_SUMMARY.json object to its key-value store on every run, separate from the dataset, with listingsRequested, listingsAnswered, listingsUnavailable, unsupportedInputs, reviewRowsPublished, duplicateReviewsSkipped, matchMode, reviewTopicsRequested, reviewSearchQuery, sortOrder, locale and maxReviewsPerListing.

Pay-per-event

This Actor charges on the row_result event, which fires only for review rows (type: "review"). The topic-breakdown row (type: "listingTopics") and the status row for unavailable listings or unsupported input (type: "listingStatus") are pushed to the dataset without a charged event โ€” you get the full topic breakdown and every diagnostic row for free. To see only the charged rows in an export, filter on type == "review".

How can I use the data extracted with Airbnb Review Scraper?

  • ๐Ÿ˜๏ธ Hosts and property managers: filter by CLEANLINESS, CHECK_IN or any recurring complaint topic across your own listings, or a competitor's, to see exactly what guests raise and how often, using matchedTopicLabel and the topic-breakdown row's sharePct.
  • ๐Ÿค– AI engineers and LLM developers: feed the structured review JSON โ€” text, ratingValue, matchedTopicLabel โ€” straight into an LLM as grounding context for a review-summarization or Q&A agent, without any HTML to parse.
  • ๐Ÿ“Š Market researchers: run the same listing set on a schedule and compare reviewTagBreakdown and listingReviewTotal across runs to track how a market segment's guest sentiment shifts.
  • ๐Ÿ› ๏ธ Product teams at travel and rental platforms: mine reviewSearchQuery keyword matches across many listings (e.g. parking, noise, check-in) to spot feature gaps or amenity complaints at scale.

How do you monitor Airbnb review topics over time?

Topic monitoring means re-running the same listing set on a schedule and comparing the listingTopics row between runs rather than re-reading every review. Because the breakdown's counts come from the listing's own metadata, not from the reviews the run collected, the numbers are comparable run over run even if you cap maxReviewsPerListing low to keep runs fast. The fields to diff are reviewTagBreakdown (count and sharePct per topic), listingReviewTotal (has review volume grown?), and topicsAvailable (has Airbnb started surfacing a new topic for this listing?). A typical workflow: schedule a run across a set of listings weekly using an Apify Console schedule, keep the previous run's listingTopics rows, and alert when a topic's sharePct moves past a threshold you define โ€” for example, a jump in the CLEANLINESS share signaling a maintenance issue worth investigating before it shows up in the overall rating.

Integrate Airbnb Review Scraper and automate your workflow

Airbnb Review Scraper With Topic & Keyword Filters works with any language or tool that can send an HTTP request, through Apify's REST API and official client libraries.

REST API with Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run_input = {
"startUrls": ["https://www.airbnb.com/rooms/12937"],
"reviewTopics": ["CLEANLINESS", "LOCATION"],
"reviewSearchQuery": "wifi",
"matchMode": "topicThenText",
"maxReviewsPerListing": 25,
}
run = client.actor("scrapier/airbnb-review-scraper-with-topic-and-keyword-filters").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item.get("type") == "review":
print(item["matchedTopicLabel"], item["ratingValue"], item["text"])

Scheduled monitoring and delivery

Set up an Apify Console Schedule to re-run the same listing set daily or weekly, and read the resulting dataset with apify_client after each run, or configure a webhook on the Actor's run-succeeded event to trigger downstream processing as soon as each run finishes.

Scraping publicly accessible Airbnb review pages is generally lawful โ€” this Actor only returns what any visitor to a listing's review page can already see, and does not access private listings, messaging, or any authenticated area. Because review rows include personal data about identifiable individuals (reviewer first names, host names, profile picture URLs and profile links), collection and storage of that data falls under privacy regimes such as the GDPR (EU/UK) and the CCPA (California) if you retain it, and you are responsible for having a lawful basis, honoring deletion or access requests, and not repurposing it beyond what the data subject would reasonably expect. Scraping for one-off analysis and scraping to build a persistent database of guests or hosts carry different risk profiles โ€” the latter draws more scrutiny under both frameworks. Consult your legal team for commercial use cases involving bulk data storage.

Frequently asked questions

Which languages can Airbnb Review Scraper return reviews in?

reviewLanguage accepts 18 locale codes โ€” English (en-US), German, Spanish, French, Italian, Portuguese, Dutch, Danish, Czech, Croatian, Indonesian, Catalan, Estonian, Irish, Azerbaijani, Bosnian, Xhosa and Zulu (full codes in the Input section above). Only the language part of the code changes what Airbnb returns, and it affects the localized review text and dates shown, not translation of the original review.

Which review order can I choose, and does it matter?

Four options via sortOrder: MOST_RECENT (default, newest first), BEST_QUALITY (Airbnb's own ranking), RATING_DESC and RATING_ASC. โš ๏ธ MOST_RECENT is the default because it walks a listing's reviews without repeating rows across pages. Airbnb's own ranking (BEST_QUALITY) re-serves the same reviews across pages, so a deep pull under it will come back incomplete.

How does Airbnb Review Scraper handle Airbnb's anti-bot measures?

Requests retry up to three times with exponential backoff on transient failures. If a response looks like a block (a 401/403/429 status, or block-page language on a short response body), the Actor automatically escalates to a more resilient connection route before retrying, and it starts every run on a direct connection so the escalation only happens when actually needed.

Does Airbnb Review Scraper extract the topic breakdown for a listing?

Yes โ€” set emitTopicBreakdownRow (on by default) and every listing gets one listingTopics row with reviewTagBreakdown (each topic, its count, and its percentage share), topicsAvailable, and a human-readable topicSummary. This is computed from the listing's own metadata every run, independent of how many individual reviews you asked for.

How many reviews does Airbnb Review Scraper return per listing?

Up to maxReviewsPerListing (1โ€“10000, default 25) โ€” but that cap applies separately to each selected topic, so four topics can return up to four times the cap for one listing. If maxReviewsPerListing is left empty, the legacy maxComments key is used instead (default 10).

Can I filter reviews by both a topic and a keyword at the same time?

Yes, via matchMode: "topicThenText" (the default) โ€” the Actor requests reviews under the selected topic(s) from Airbnb directly, then keeps only the ones whose text actually contains the keyword, giving you the genuine overlap of both filters. topicOnly ignores the keyword; textOnly ignores the topics and searches by keyword alone.

How do I monitor a listing's review topics over time?

Schedule the same listing set to run on a recurring basis using an Apify Console schedule, keep each run's listingTopics row, and compare reviewTagBreakdown and sharePct per topic against the previous run to catch a rising complaint theme before it moves the overall rating.

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

Yes, as an HTTP endpoint โ€” any agent framework that can call the Apify API or apify_client can trigger a run, retrieve the resulting review and topic-breakdown rows, and use them as grounding context before generating an answer.

What happens if I give it a URL that isn't a listing page?

It is reported, not guessed at. Anything that is not https://www.airbnb.com/rooms/<id> or a bare numeric ID is pushed as an uncharged listingStatus row with listingStatus: "unsupportedInput" and the original input preserved in input.

Can I use Airbnb Review Scraper without managing proxies or an Airbnb account?

Yes. No Airbnb account or login is needed โ€” the Actor reads public listing and review pages. proxyConfiguration is optional; the run starts on a direct connection and only switches to a more resilient route on its own if a listing is slow to answer.

๐Ÿ’ฌ Your feedback

Found a bug or a missing Airbnb review field? Open an issue from the Actor's Issues tab on Apify Console โ€” reports of real field or filtering gaps get looked at directly.