# Airbnb Reviews Scraper (`codingfrontend/airbnb-reviews-scraper`) Actor

Scrape all reviews from Airbnb listings with full pagination, category ratings, star distribution, and host responses.

- **URL**: https://apify.com/codingfrontend/airbnb-reviews-scraper.md
- **Developed by:** [Coding Frontned](https://apify.com/codingfrontend) (community)
- **Categories:** Travel, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 90.9% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Airbnb Reviews Scraper

Extract public reviews from one or more Airbnb listing URLs. The Actor opens Airbnb's reviews route in a real browser, follows the reviews panel's incremental loading, and falls back to public JSON-LD when browser extraction is unavailable.

### What it returns

Each review record can include:

- Listing context: ID, URL, title, accommodation type, location, capacity, bedrooms, beds, bathrooms, description, cover image, amenity count, overall rating, category ratings, and star distribution.
- Reviewer context: display name, public profile URL and ID, location or Airbnb tenure, and avatar URL.
- Review content: stable review ID when exposed, rating, displayed date, stay type, full text, and one-based result position.
- Host response context: response text, response author/profile, response date, and a `hasHostResponse` flag.
- Provenance: `pageType`, `found`, `extractionMethod`, `fallbackMode`, and `scrapedAt`.

The dataset contains review rows only. A machine-readable `OUTPUT` key reports success, verified empty results, limits, fallback use, and sanitized failures. Unverifiable empty or blocked runs fail explicitly.

### Input options

| Field | Type | Default | Description |
|---|---|---:|---|
| `productUrls` | array of strings | — | Required Airbnb `/rooms/<id>` listing URLs. |
| `maxReviewsPerListing` | integer | `0` | Maximum reviews per listing. `0` means no per-listing cap. |
| `maxTotalReviews` | integer | `0` | Overall review cap across all listing URLs. |
| `includeHostResponses` | boolean | `true` | Include host response fields when available. |
| `includeListingMetadata` | boolean | `true` | Include extended listing and host context. |
| `includeReviewerDetails` | boolean | `true` | Include public reviewer profile, location/tenure, and avatar fields. |
| `reviewSearch` | string | `""` | Optional phrase entered into Airbnb's “Search all reviews” control. |
| `reviewSort` | enum | `BEST_QUALITY` | `BEST_QUALITY`, `MOST_RECENT`, `HIGHEST_RATED`, or `LOWEST_RATED`. |
| `maxConcurrency` | integer | `2` | Browser concurrency from 1 to 5. |
| `maxRequestRetries` | integer | `1` | Crawlee retries for failed listing requests. |
| `requestDelayMs` | integer | `0` | Delay before processing each listing, from 0 to 10,000 ms. |
| `requestTimeoutSecs` | integer | `60` | Listing/reviews navigation timeout, from 15 to 180 seconds. |
| `saveDebugHtml` | boolean | `false` | Opt in to saving `debug-<listing>.html` when the reviews panel cannot be opened. |
| `proxyConfiguration` | object | Residential | Proxy used consistently by the browser and HTTP fallback. |

`maxItems` is also accepted as a backwards-compatible alias for `maxTotalReviews`.

#### Example input

```json
{
  "productUrls": [
    "https://www.airbnb.com/rooms/1234567890123456789"
  ],
  "maxReviewsPerListing": 25,
  "maxTotalReviews": 100,
  "includeHostResponses": true,
  "reviewSort": "MOST_RECENT",
  "reviewSearch": "clean",
  "maxConcurrency": 1,
  "saveDebugHtml": false
}
```

### Example output

```json
{
  "listingId": "1234567890123456789",
  "listingUrl": "https://www.airbnb.com/rooms/1234567890123456789",
  "listingTitle": "Example apartment near the city center",
  "listingType": "Entire apartment",
  "location": "Example City, Example Country",
  "overallRating": 4.87,
  "totalReviewCount": 128,
  "categoryRatings": {
    "cleanliness": 4.9,
    "accuracy": 4.8,
    "checkIn": 4.9,
    "communication": 4.9,
    "location": 4.7,
    "value": 4.6
  },
  "reviewIndex": 1,
  "reviewId": "9876543210987654321",
  "authorName": "Example Reviewer",
  "reviewerLocation": "Example City, Example Country",
  "reviewerUrl": "https://www.airbnb.com/users/profile/123456789",
  "rating": 5,
  "date": "January 2026",
  "stayType": "Stayed a few nights",
  "reviewText": "The apartment was clean, comfortable, and close to public transport.",
  "hasHostResponse": true,
  "hostResponse": "Thank you for your thoughtful feedback. We hope to welcome you again.",
  "source": "Airbnb listing reviews",
  "pageType": "review",
  "found": true,
  "extractionMethod": "playwright_dom",
  "fallbackMode": "browser",
  "scrapedAt": "2026-01-15T12:00:00.000Z"
}
```

### Notes

- Only public Airbnb pages are requested with bounded retries and pacing. The configured proxy is applied consistently; login, CAPTCHA solving, and access-control bypasses are not attempted. CAPTCHA/access-denied/rate-limit responses fail closed and are summarized in `OUTPUT`.
- Airbnb may expose translated or relative date text; `date` preserves the text shown on the page.
- Debug HTML is stored in the default key-value store only when `saveDebugHtml` is enabled and browser extraction fails.
- Every dataset row is a verified `pageType: "review"` record with a reviewer name and review text.

# Actor input Schema

## `productUrls` (type: `array`):

Airbnb listing URLs to scrape reviews from (e.g. https://www.airbnb.com/rooms/12345).

## `maxReviewsPerListing` (type: `integer`):

Maximum number of reviews to scrape per listing. Set 0 for all reviews.

## `maxTotalReviews` (type: `integer`):

Overall cap across all listing URLs. Set 0 for no run-wide cap.

## `includeHostResponses` (type: `boolean`):

If true, include the host's response for each review (if any).

## `includeListingMetadata` (type: `boolean`):

Include listing type, location, capacity, host summary, description, and cover image fields.

## `includeReviewerDetails` (type: `boolean`):

Include reviewer profile, location/tenure, and avatar fields when exposed by Airbnb.

## `reviewSearch` (type: `string`):

Optional phrase to enter into Airbnb's Search all reviews control before extraction.

## `reviewSort` (type: `string`):

Sort order exposed by Airbnb's reviews panel.

## `maxConcurrency` (type: `integer`):

Maximum number of Airbnb listing pages processed at once. Lower values reduce load and proxy pressure.

## `maxRequestRetries` (type: `integer`):

Maximum Crawlee retries for a listing request after a failed browser attempt.

## `requestDelayMs` (type: `integer`):

Optional delay before each listing is processed, useful for pacing requests.

## `requestTimeoutSecs` (type: `integer`):

Navigation timeout used for each listing and its reviews page.

## `saveDebugHtml` (type: `boolean`):

Save a debug-<listing>.html key-value record when the reviews modal cannot be opened.

## `proxyConfiguration` (type: `object`):

Proxy used by both browser and HTTP extraction. Residential proxy is the reliable default for Airbnb.

## Actor input object example

```json
{
  "productUrls": [
    "https://www.airbnb.com/rooms/1104883308160967951"
  ],
  "maxReviewsPerListing": 0,
  "maxTotalReviews": 0,
  "includeHostResponses": false,
  "includeListingMetadata": true,
  "includeReviewerDetails": true,
  "reviewSearch": "",
  "reviewSort": "BEST_QUALITY",
  "maxConcurrency": 2,
  "maxRequestRetries": 1,
  "requestDelayMs": 0,
  "requestTimeoutSecs": 60,
  "saveDebugHtml": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Scraped review records with listing context and extraction metadata.

## `output` (type: `string`):

Counts, completion state, fallback use, and bounded failures.

## `files` (type: `string`):

Key-value store containing debug HTML captured when a reviews panel cannot be opened.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "productUrls": [
        "https://www.airbnb.com/rooms/1104883308160967951"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("codingfrontend/airbnb-reviews-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "productUrls": ["https://www.airbnb.com/rooms/1104883308160967951"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("codingfrontend/airbnb-reviews-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "productUrls": [
    "https://www.airbnb.com/rooms/1104883308160967951"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call codingfrontend/airbnb-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,codingfrontend/airbnb-reviews-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ixbm1cFr8M6vjRAs2/builds/hA7lGdlVOSG5N3yZa/openapi.json
