# Airbnb Reviews Scraper — Guest Ratings and Host Replies (`s-r/airbnb-reviews`) Actor

Collect public Airbnb guest reviews with ratings, original text, available translations, guest locations, stay highlights and host replies. Supply room URLs or listing IDs and choose review order and a limit per listing.

- **URL**: https://apify.com/s-r/airbnb-reviews.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Travel, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.50 / 1,000 reviews

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

Airbnb Reviews Scraper collects public guest reviews from Airbnb listings. Get ratings,
original review text, available translations, guest display names and locations, stay
highlights, and host replies in a structured dataset. It is useful for hosts, property
managers, reputation analysts, and researchers comparing guest experiences across listings.

### What Airbnb Reviews Scraper delivers

Each dataset row represents one guest review for one listing. The original review text is
preserved alongside an available Airbnb translation, making it possible to compare guest
feedback across languages without losing the source wording. Host responses are separate
fields, so you can examine how hosts respond to praise, complaints, or recurring issues.

Listing IDs and review IDs are returned as strings. Keep them as strings in spreadsheets
and databases: long IDs can lose precision when converted to numbers. Use `place_id` to
join reviews to your listing records and `review_id` to identify individual reviews.
Repeating the same listing within one input does not collect it twice.

### Input

Provide `listings` as a list of Airbnb room URLs or numeric listing IDs written as strings.
Regional Airbnb room URLs work as well. URL query parameters and fragments are ignored,
and room URLs containing `/rooms/plus/` are accepted. Custom vanity links and experience
URLs are unsupported because they do not identify an accommodation listing directly.

This input uses a real public listing from the recorded examples:

```json
{
  "listings": ["https://www.airbnb.com/rooms/1142549760112481397"],
  "max_reviews": 5,
  "sort": "newest",
  "language": "en",
  "translate": true
}
```

The default `max_reviews` is 100 per listing. You can request from 1 to 10,000 reviews per
listing, subject to how many Airbnb makes available. Submit up to 100 listings in one run.
The limit applies separately to each listing, rather than to the combined dataset.

Choose `newest` for recent feedback, `relevant` for Airbnb's relevance order,
`highest_rating` to start with the strongest ratings, or `lowest_rating` to start with
the weakest. Reviews retain this source order within each listing. A review's `position`
shows its one-based position in that order.

The `language` option controls available translations and localized date and location
text. Supported values are `en`, `en-GB`, `nl`, `de`, `pt-BR`, `zh-TW`, and `ja`.
The original text and original language remain available regardless of this option.
Set `translate` to false to return original text with null translation fields.

### Output

Reviews are saved to the default dataset, where you can download them in JSON, CSV, or
other formats supported by Apify. The main fields are:

| Field | Meaning |
|---|---|
| `review_id`, `place_id`, `place_url` | Review ID, listing ID, and canonical room URL |
| `rating` | The guest's rating on Airbnb's 1–5 scale |
| `text`, `language` | Original review text and its language |
| `text_translated`, `translation_language` | Available translated text and requested language |
| `published_at`, `published_text` | Exact review timestamp and localized display date |
| `author_name`, `author_location` | Guest display name and displayed location |
| `author_tenure` | Displayed Airbnb membership duration when location is not shown |
| `length_of_stay`, `trip_type` | Stay duration or trip highlight when available |
| `reply_text`, `reply_text_translated` | Original host reply and available translated reply |
| `reply_date_text` | Host reply date exactly as displayed, without an inferred timestamp |
| `host_name`, `host_id`, `room_type` | Displayed host identity and room type when supplied |
| `photos`, `listing_reviews_count` | Review photo URLs and the listing's reported review total |
| `fetched_at`, `input`, `position` | Retrieval time, original input, and source position |

For example, the recorded review `1791905086662251880` has the original text
`Súper recomendable!! ☺️`, language `es`, rating 5, and the available English translation
`Highly recommended!! ☺️`. Its publication timestamp is `2026-10-08T08:35:32Z`.
Airbnb displays `9 years on Airbnb` in the location area for this guest, so the result
places that text in `author_tenure` and leaves `author_location` null.

Missing information remains null or an empty list. This source does not provide a listing
name, an individual review permalink, guest country codes, rating sub-scores, or an exact
host reply timestamp. The host's display name is not presented as the listing name.
Review photos are often an empty list. Stay duration is only supplied when Airbnb displays
a stay-duration highlight; a family-trip highlight is recorded separately as `trip_type`.

### Pricing

Billing is per delivered review. A listing with no returned reviews contributes no review
charges. Review rows are delivered before they are counted for billing; listing metadata
and error messages are not review rows. Consult the actor's Apify pricing panel for the
current price per review before starting a run.

Users without a paid Apify plan receive at most ten review rows per run in total, even
when several listings are submitted. The cap applies to delivery and billing together.
Users with a paid plan can request the stated per-listing maximum.

### Large collections and unavailable listings

Apify follows continuation pages automatically during a run. Larger collections may take
longer because each listing has its own review pages. The `OUTPUT` record contains counts
and completion information. Check `partial`, warnings, and errors before assuming that
every requested review was collected. A remaining continuation means the collection has
not finished; retry the unfinished work with the same options when using the API.

A missing listing does not prevent valid listings in the same request from producing
reviews. If every listing has no available reviews, the run returns no review rows. Source
availability and review totals can change between collection times. For repeated analysis,
retain review IDs and retrieval timestamps so you can identify changes between exports.

### FAQ

#### Can I collect reviews for several properties?

Yes. Put their room URLs or string listing IDs in `listings`. The maximum review count
applies to each property independently, while the free-plan limit applies to the whole run.

#### Does selecting a translation language replace the original review?

No. Original text remains in `text`. Available translated text is stored separately.
A missing or empty translation stays null, and a host reply can have a translation even
when the guest review does not. Airbnb supplies the translations.

#### Why is a guest location missing?

Airbnb may show membership duration instead of a location. That display text is stored
as `author_tenure`. When neither is displayed, both fields remain null. Location text is
kept as Airbnb displays it and is not converted into a country code.

#### Can I get an exact date for a host response?

This review source provides the host reply's display date rather than an exact timestamp.
Use `reply_date_text` as display information and avoid treating it as an exact date.

#### What should I check when a collection is incomplete?

Inspect the run's `OUTPUT`, warnings, and errors. Already delivered review rows remain
available. A temporary source error may leave a continuation for unfinished reviews;
keep the original listing and sorting options when continuing the collection.

# Actor input Schema

## `listings` (type: `array`):

One to 100 public Airbnb room URLs or numeric string listing IDs. Duplicate listings are collected once.

## `sort` (type: `string`):

Newest first, Airbnb relevance, highest rating first or lowest rating first.

## `max_reviews` (type: `integer`):

Collect up to this many reviews per listing, following cursor pages automatically on Apify.

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

Language of available Airbnb translations and displayed dates and locations. Original review text is always preserved.

## `translate` (type: `boolean`):

Include Airbnb translations of reviews and host replies when available. False makes translated fields null.

## `proxy_country` (type: `string`):

Two-letter request country. Defaults to US. GB is unsupported; this setting does not change translation language.

## `cursor` (type: `string`):

Opaque continuation from next_cursor. Repeat the original inputs. Apify follows cursors automatically.

## Actor input object example

```json
{
  "listings": [
    "1142549760112481397"
  ],
  "sort": "newest",
  "max_reviews": 100,
  "language": "en",
  "translate": true,
  "proxy_country": "US"
}
```

# Actor output Schema

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

Delivered guest reviews.

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

Counts, continuation and errors.

# 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 = {
    "listings": [
        "1142549760112481397"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/airbnb-reviews").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 = { "listings": ["1142549760112481397"] }

# Run the Actor and wait for it to finish
run = client.actor("s-r/airbnb-reviews").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 '{
  "listings": [
    "1142549760112481397"
  ]
}' |
apify call s-r/airbnb-reviews --silent --output-dataset

```

## MCP server setup

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

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/tKIetR5afgiOLxdwt/builds/ag7MPXIJoPGUp9ett/openapi.json
