# Airbnb Reviews Scraper - Guest Reviews, Ratings & Host Replies (`sweet_stickball/airbnb-reviews-scraper`) Actor

Airbnb reviews scraper and API alternative: extract guest reviews of any Airbnb listing with star rating, review text and translation, language, date, reviewer first name and location, host reply and length of stay. Sort by most recent or most relevant, no login.

- **URL**: https://apify.com/sweet_stickball/airbnb-reviews-scraper.md
- **Developed by:** [CrawlKit](https://apify.com/sweet_stickball) (community)
- **Categories:** Travel, Real estate
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 guest reviews

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Airbnb Reviews Scraper - Guest Reviews, Ratings & Host Replies

Extract guest reviews from Airbnb listings: star rating, review text with Airbnb's translation, language, date, reviewer first name and location, host reply and length of stay. Give listing URLs or ids, sort by most recent or most relevant. No login.

### What it does

- Takes one or more Airbnb listing URLs (`https://www.airbnb.com/rooms/<id>`, any Airbnb country domain) or numeric listing ids, and returns one flat JSON item per guest review.
- Each review comes with its rating (1-5), original text, language, ISO date, the reviewer's first name, the reviewer's location (or their tenure on Airbnb, which Airbnb shows instead for some reviewers), the length of stay, and the host's public reply.
- Reviews written in another language than the requested `language` also get Airbnb's own machine translation in `translatedText`.
- Uses the same JSON endpoint as the Airbnb listing page when it shows the reviews, plus the listing page itself for the listing title. No account is used.
- Reviews are deduplicated by `reviewId`. Each listing returns up to `maxItems` reviews.

Typical uses: guest sentiment analysis, monitoring the reviews of your own or competing listings, comparing properties before a purchase or a management contract, training data for review classification.

### Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `listingUrls` | array of strings | Yes | — | Airbnb listing URLs (`https://www.airbnb.com/rooms/36276450`, `https://www.airbnb.fr/rooms/36276450?adults=2`) or listing ids (`36276450`) |
| `sortBy` | string | No | `most_recent` | `most_recent` (newest first) or `most_relevant` (Airbnb's default order) |
| `language` | string | No | `en` | Airbnb locale (`en`, `fr`, `de`, `es`, `pt-BR`...): language of `translatedText`, `stayDetails`, `reviewerTenure` and `hostReplyDate` |
| `maxItems` | integer | No | 50 | Maximum number of reviews per listing (1-5000) |

Example:

```json
{
    "listingUrls": ["https://www.airbnb.com/rooms/36276450", "1423687913527325454"],
    "sortBy": "most_recent",
    "language": "en",
    "maxItems": 100
}
```

### Output

One item per review. Real example:

```json
{
    "reviewId": "1791305971234077119",
    "listingId": "36276450",
    "listingTitle": "A quiet little corner in the heart of Paris",
    "listingUrl": "https://www.airbnb.com/rooms/36276450",
    "rating": 5,
    "text": "The location is fantastic if you wish to visit the cathedral‑Notre‑Dame. It is right next door, so you can hear its bells ring every day, which is a lovely, magical experience. [...]",
    "translatedText": null,
    "language": "en",
    "createdAt": "2026-10-07T12:45:12Z",
    "reviewer": "Blair",
    "reviewerLocation": null,
    "reviewerTenure": "12 years on Airbnb",
    "hostReply": "6 mn de la Station Cité\n7 mn de la station Hôtel de ville\n4 mn du RER B\nL’appartement est au 2e étage et 4 marches.",
    "hostReplyDate": "2 weeks ago",
    "stayDetails": "Stayed a few nights",
    "listingReviewsCount": 682,
    "scrapedAt": "2026-10-28T06:41:10+00:00"
}
```

| Field | Description |
|---|---|
| `reviewId` | Airbnb review id (unique) |
| `listingId`, `listingTitle`, `listingUrl` | The reviewed listing (`listingTitle` is null if the listing page could not be read) |
| `rating` | Overall star rating given by the guest (1-5) |
| `text` | Original review text, line breaks kept |
| `translatedText` | Airbnb's translation into `language` when the review is written in another language, else null |
| `language` | Language of the original text |
| `createdAt` | Review date, ISO 8601 UTC |
| `reviewer` | Reviewer first name as displayed by Airbnb (a last name, if any, is reduced to its initial) |
| `reviewerLocation` | Reviewer's city / country, when Airbnb shows it |
| `reviewerTenure` | "N years on Airbnb", shown by Airbnb instead of the location for some reviewers |
| `hostReply`, `hostReplyDate` | Host's public reply (original text) and its date as worded by Airbnb ("2 weeks ago") |
| `stayDetails` | Length of stay or trip type shown with the review ("Stayed a few nights", "Stayed with kids") |
| `listingReviewsCount` | Total number of reviews of the listing |
| `scrapedAt` | Extraction time |

### Pricing

Pay-per-event, **no start fee**: **$3.50 per 1,000 reviews** on the Apify Free plan, with lower prices on paid plans. Each review pushed to the dataset is one event.

| Event | Free | Starter | Scale | Business | Enterprise |
|-------|------|---------|-------|----------|------------|
| Review (`REVIEW`) | $3.50 | $3.00 | $2.60 | $2.10 | $2.10 |

Prices in USD per 1,000 events.

#### Cost examples (Free plan)

| Scenario | Reviews | Cost |
|----------|---------|------|
| Quick look at one listing | 10 | $0.035 |
| 50 reviews of 10 listings | 500 | $1.75 |
| Full history of a popular listing | 700 | $2.45 |

Set a "Maximum cost per run" in the run options to cap a run: the Actor stops cleanly when it is reached.

### Limitations

- Only the reviews Airbnb publishes on the listing page are available; Airbnb does not show some old or hidden reviews, so a listing can return slightly fewer reviews than `listingReviewsCount`.
- Airbnb shows only the reviewer's first name; no reviewer profile id or photo is returned.
- The host reply date is the relative wording shown by Airbnb ("2 weeks ago", "March 2024"); Airbnb does not expose an exact reply date.
- Category ratings (cleanliness, accuracy, location...) are only published by Airbnb as listing averages, not per review, and are not returned.
- Listing URLs only: search pages, experiences, wishlists and host profiles are not supported.
- The reviews endpoint is the one used by Airbnb's website; when Airbnb changes it, the run fails with an explicit message until the Actor is updated.

# Actor input Schema

## `listingUrls` (type: `array`):

Airbnb listing pages, e.g. https://www.airbnb.com/rooms/36276450 (any Airbnb country domain works, query parameters are ignored), or bare numeric listing ids such as 36276450. Search pages, experiences and host profiles are not supported.

## `sortBy` (type: `string`):

Order in which reviews are collected: 'most_recent' (newest first) or 'most_relevant' (Airbnb's default ordering on the listing page). With a small maxItems this decides which reviews you get.

## `language` (type: `string`):

Airbnb locale code (e.g. 'en', 'fr', 'de', 'es', 'pt-BR'). Reviews written in another language get Airbnb's machine translation into this language in 'translatedText'; 'stayDetails', 'reviewerTenure' and 'hostReplyDate' are also worded in it. The original review text is always returned in 'text'.

## `maxItems` (type: `integer`):

Maximum number of reviews returned for each listing. A listing never returns more reviews than Airbnb shows for it.

## Actor input object example

```json
{
  "listingUrls": [
    "https://www.airbnb.com/rooms/36276450",
    "1423687913527325454"
  ],
  "sortBy": "most_recent",
  "language": "en",
  "maxItems": 10
}
```

# Actor output Schema

## `reviews` (type: `string`):

Guest reviews shown with the 'reviews' view.

# 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 = {
    "listingUrls": [
        "https://www.airbnb.com/rooms/36276450"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("sweet_stickball/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 = {
    "listingUrls": ["https://www.airbnb.com/rooms/36276450"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("sweet_stickball/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 '{
  "listingUrls": [
    "https://www.airbnb.com/rooms/36276450"
  ],
  "maxItems": 10
}' |
apify call sweet_stickball/airbnb-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sweet_stickball/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/jlX9JnVxvxsDfbh06/builds/a8UFk7siUNPW3PW44/openapi.json
