# Airbnb Reviews Scraper (Cheap) (`data_api/airbnb-reviews-scraper-cheap`) Actor

Airbnb reviews scraper that pulls every guest review from any listing by URL or room ID, including ratings, comments, reviewer profiles, and host responses, so property managers and data teams can run competitive analysis and sentiment research across one or many properties.

- **URL**: https://apify.com/data\_api/airbnb-reviews-scraper-cheap.md
- **Developed by:** [Data API](https://apify.com/data_api) (community)
- **Categories:** Travel, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 results

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/platform/actors/running/actors-in-store#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

![Airbnb Reviews Scraper](cover.jpg)

Reading through Airbnb reviews by hand is slow, and the page only shows a handful at a time before you have to keep clicking "Show more". This scraper pulls the full review history of any listing for you. Give it a room URL or just the numeric ID and it returns every review as its own row: the star rating, the text (with the English translation when there is one), who wrote it, when, the trip tag, and the host's reply. Pass one listing or a whole batch and the results land in your dataset as the run goes.

### What you get

One row per review, with a steady shape so columns stay predictable in a sheet or database. Missing values come back as `null` rather than disappearing. Each row covers three groups:

- **Review** — `reviewId`, `starRating`, `reviewText`, `originalText`, `languageCode`, `wasTranslated`, `tripTag`
- **Dates** — `submittedAt`, `displayDate`, `collectedAt`
- **People** — `guestName`, `guestId`, `guestContextualId`, `guestPhotoUrl`, `guestProfilePath`, `guestTenure`, `hostName`, `hostId`, `hostReply`, plus the `listingId` the review belongs to

### Quick start

1. Hit **Try for free** and open the input form.
2. Paste an Airbnb listing URL into **Single listing URL or ID**, or drop several into **Multiple listing URLs or IDs** (a bare room ID works too).
3. Set **Reviews per listing** to cap each listing, or leave it at 0 to pull them all. Pick a proxy type if you need one.
4. Press **Start**, then export the results as JSON, CSV, Excel, or XML when the run finishes.

![How it works](how-it-works.jpg)

### Use cases

- **Competitor research** — pull reviews from rival listings and compare what guests say before you adjust pricing or amenities
- **Sentiment analysis** — feed `reviewText` into an NLP pipeline to find what guests praise and what they gripe about
- **Host monitoring** — schedule the actor to catch new reviews on your own listing as they land
- **Travel planning** — read a listing's whole review history before booking instead of trusting the headline score
- **Dataset building** — gather Airbnb reviews in bulk to train or benchmark short-term-rental models

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `listingUrl` | string | One of `listingUrl` or `listingUrls` | A single Airbnb listing URL or numeric room ID. Prefilled with a sample listing. |
| `listingUrls` | array of strings | One of `listingUrl` or `listingUrls` | Several Airbnb URLs or room IDs, one per line. Merged with `listingUrl` when both are given. |
| `reviewsLimit` | integer | No | Reviews to collect per listing. Default `50`; use `0` to pull every review. |
| `contentLocale` | string | No | Language for date labels and translated text, e.g. en, fr, de, zh. Default `en`. |
| `currencyCode` | string | No | Currency sent with the request, e.g. USD, EUR, GBP. Does not change review text. Default `USD`. |
| `requestTimeoutSeconds` | integer | No | Seconds to wait on each HTTP request before giving up. Default `45`. |
| `proxyConfiguration` | object | No | Proxies used for requests. Defaults to Datacenter (Anywhere); switch to Residential if datacenter IPs get blocked. |

#### Example input

```json
{
    "listingUrls": [
        "https://www.airbnb.com/rooms/20669368",
        "https://www.airbnb.com/rooms/14926879",
        "987654321"
    ],
    "reviewsLimit": 0,
    "contentLocale": "en",
    "currencyCode": "USD",
    "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output

Each review on a listing becomes one row in the dataset, and every field is always present — values Airbnb doesn't supply come back as `null` so the dataset stays rectangular.

#### Example output

```json
{
    "reviewId": "1646862738258373172",
    "listingId": "20669368",
    "starRating": 5,
    "reviewText": "The place was fantastic. For the price you get a prime spot close to everything.",
    "originalText": null,
    "languageCode": "en",
    "wasTranslated": false,
    "submittedAt": "2026-03-22T05:42:17Z",
    "displayDate": "6 days ago",
    "tripTag": "WEEKEND TRIP",
    "guestName": "Lester",
    "guestId": "507561268",
    "guestContextualId": "1498306238959795062",
    "guestPhotoUrl": "https://a0.muscache.com/im/pictures/user/example.jpg",
    "guestProfilePath": "/users/profile/1498306238959795062",
    "guestTenure": "3 years on Airbnb",
    "hostName": "Sourov",
    "hostId": "599574226",
    "hostReply": null,
    "collectedAt": "2026-06-29T10:00:00.000000+00:00"
}
```

#### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `reviewId` | string | Unique identifier Airbnb assigns to the review |
| `listingId` | string | Room/listing ID the review was left on |
| `starRating` | integer | Score the guest gave, from 1 to 5 |
| `reviewText` | string | Review content in English, translated when the original was another language |
| `originalText` | string | Untranslated review as the guest wrote it; null when already in English |
| `languageCode` | string | BCP-47 code of the original language, e.g. en, zh-CN, fr |
| `wasTranslated` | boolean | True when Airbnb auto-translated the review |
| `submittedAt` | string | ISO 8601 timestamp of when the guest posted the review |
| `displayDate` | string | Date label as shown on Airbnb, e.g. "February 2026" |
| `tripTag` | string | Trip-type label such as WEEKEND TRIP; null when absent |
| `guestName` | string | First name of the guest who wrote the review |
| `guestId` | string | Airbnb user ID of the reviewer |
| `guestContextualId` | string | Contextual ID used in Airbnb profile URLs |
| `guestPhotoUrl` | string | Link to the reviewer's profile picture |
| `guestProfilePath` | string | Relative path to the reviewer's Airbnb profile |
| `guestTenure` | string | How long the reviewer has been on Airbnb, e.g. "3 years on Airbnb" |
| `hostName` | string | First name of the host the review was written for |
| `hostId` | string | Airbnb user ID of the host |
| `hostReply` | string | Host's response to the review; null when there is none |
| `collectedAt` | string | ISO 8601 timestamp of when the record was captured |

### Tips for best results

- **Pull everything with `reviewsLimit: 0`.** Set it to 0 and the actor pages through the full review history of each listing instead of stopping at the first page.
- **Batch listings in one run.** Put multiple URLs or IDs in `listingUrls`, one per line. Each review carries its `listingId`, so you can tell the listings apart afterward.
- **Any URL format works.** Links with query parameters like `check_in` or `source_impression_id` are fine, and a bare numeric room ID works on its own.
- **Switch to Residential if you get blocked.** Datacenter proxies handle most runs; move to Residential when you hit repeated rate limits on large scrapes.
- **Check the translation fields for non-English reviews.** When Airbnb has an English version, `reviewText` holds it and `originalText` keeps the source; `languageCode` and `wasTranslated` tell you what happened.

### How can I use Airbnb review data?

**How can I use the Airbnb Reviews Scraper to analyze guest sentiment?**
Run it across the listings you care about with `reviewsLimit` set to 0, then push the `reviewText` and `starRating` columns into your sentiment or topic-modeling pipeline. Because every review is a separate row tagged with `languageCode` and `wasTranslated`, you can split English from translated text or weight scores by rating before you summarize what guests actually think.

**How can I scrape all reviews from an Airbnb listing, not just the first page?**
Paste the room URL or ID and set `reviewsLimit` to 0. The scraper calls Airbnb's review endpoint page by page until there's nothing left, so you get the complete history rather than the handful shown on the listing page.

**How can I track new Airbnb reviews for my own listing over time?**
Schedule the actor on your listing URL and compare `submittedAt` between runs to see what's new. Pair it with `guestName`, `tripTag`, and `hostReply` to keep a running log of feedback and spot reviews that still need a response.

**How can I collect Airbnb reviews in bulk for research?**
Drop a list of listing URLs or IDs into `listingUrls` and let it run. Every review lands in one dataset with its `listingId` attached, ready to export as JSON, CSV, or Excel for a market study or a training set.

### Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses or private contact information. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Support

Questions, feature requests, or a field you'd like added? Reach out at <data.apify@proton.me> and we'll get back to you.

# Actor input Schema

## `listingUrl` (type: `string`):

One Airbnb listing URL or its numeric room ID. To pull reviews from several listings at once, use the multi-listing field below instead.

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

Several Airbnb listing URLs or numeric room IDs, one per line, when you want reviews from a batch of listings in a single run. Anything entered in the single-listing field above is added to this list.

## `reviewsLimit` (type: `integer`):

How many reviews to collect from each listing. Leave it at 0 to grab every review the listing has.

## `contentLocale` (type: `string`):

Language used for date labels and translated review text, for example en, fr, de, or zh.

## `currencyCode` (type: `string`):

Currency passed with the request, such as USD, EUR, or GBP. It has no effect on the review content itself.

## `requestTimeoutSeconds` (type: `integer`):

How long to wait on each HTTP request before giving up, in seconds.

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

Pick the proxies used for requests to keep IP blocks and rate limits at bay. Datacenter proxies are quickest; residential ones are tougher to flag.

## Actor input object example

```json
{
  "listingUrl": "https://www.airbnb.com/rooms/20669368",
  "listingUrls": [
    "https://www.airbnb.com/rooms/20669368",
    "https://www.airbnb.com/rooms/14926879"
  ],
  "reviewsLimit": 50,
  "contentLocale": "en",
  "currencyCode": "USD",
  "requestTimeoutSeconds": 45,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "listingUrl": "https://www.airbnb.com/rooms/20669368",
    "listingUrls": [
        "https://www.airbnb.com/rooms/20669368"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("data_api/airbnb-reviews-scraper-cheap").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 = {
    "listingUrl": "https://www.airbnb.com/rooms/20669368",
    "listingUrls": ["https://www.airbnb.com/rooms/20669368"],
    "proxyConfiguration": { "useApifyProxy": True },
}

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

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

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

```

## CLI example

```bash
echo '{
  "listingUrl": "https://www.airbnb.com/rooms/20669368",
  "listingUrls": [
    "https://www.airbnb.com/rooms/20669368"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call data_api/airbnb-reviews-scraper-cheap --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=data_api/airbnb-reviews-scraper-cheap",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

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