# Airbnb Scraper - Listings, Prices, Details & Reviews (`randy-tools/airbnb-scraper`) Actor

Scrape Airbnb stays without a browser: search any place or paste a search URL, filter by dates, guests, price, room type, bedrooms and amenities, go beyond the 270-result cap with map tiling. Optional full details (host, rating breakdown, rules, cancellation, photos) and reviews. Pay per result.

- **URL**: https://apify.com/randy-tools/airbnb-scraper.md
- **Developed by:** [AICORP Tools](https://apify.com/randy-tools) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 Scraper — Listings, Prices, Details & Reviews

Extract **Airbnb stays** for any destination: search by place name or paste an Airbnb search URL, set dates and guests, and get every stay with its price, rating, host badges, bedrooms and coordinates. Turn on **listing details** for the full description, amenities, house rules, rating breakdown, host, all photos and the cancellation policy, or add **public guest reviews**. Airbnb only shows 270 stays per search; **deep search** splits the map into tiles to reach every stay in a busy city.

Built for **speed and low cost**: it calls the same JSON endpoints the Airbnb website uses, over plain HTTP (no browser). Requests are paced, retried and moved to a fresh IP when blocked, so scheduled runs keep succeeding.

### What you can do with it

- **Revenue and pricing research:** nightly and total prices for the same dates across a whole city or neighbourhood
- **Competitor and market analysis:** count listings by room type, bedrooms, Superhost status and rating in any market
- **Investment screening:** find high-rated stays, review counts and amenities before buying or managing a property
- **Guest sentiment:** collect public review text and ratings to see what guests praise or complain about
- **Travel apps and comparison sites:** availability and total price for chosen dates in any currency and language

### Features

- 🔎 **Search by place or URL:** type "Lisbon, Portugal" or paste any airbnb.com search URL; its dates, guests and filters are kept
- 📅 **Dates and guests:** check-in and check-out (or nights), adults, children, infants, pets. With dates you get the **total price for the stay** and only available stays
- 💶 **33 currencies and 15 languages** for prices, titles and descriptions
- 🧹 **Filters:** min and max nightly price, room type (entire home, private room, hotel room, shared room), min bedrooms, beds and bathrooms, 24 amenities (Wifi, Kitchen, Pool, Washer, Air conditioning...), Superhost, Guest favorite, Instant Book, free cancellation
- 🗺️ **Deep search beyond 270 results:** when a search fills all 15 pages, its map area is split into four tiles, recursively, until each tile is read completely
- 🧾 **Listing details (optional):** full description, amenities by group, house rules with check-in and check-out times, safety notes, sleeping arrangements, rating breakdown (cleanliness, accuracy, check-in, communication, location, value) and star distribution, host name, Superhost, host rating, years hosting and response rate, coordinates, all photos, cancellation policy timeline
- ⭐ **Reviews (optional):** reviewer first name, rating, date, text, translation when the review is not in your language and the host's reply, newest first
- 📌 **Single listings** by URL or ID
- 🔒 **No personal data:** only what Airbnb shows publicly. No logins, no contact details, no reviewer profiles or photos.

### Input example

```json
{
  "locations": ["Lisbon, Portugal", "Porto, Portugal"],
  "checkIn": "2026-12-04",
  "nights": 3,
  "adults": 2,
  "currency": "EUR",
  "minPrice": 50,
  "maxPrice": 200,
  "roomTypes": ["entire_home"],
  "amenities": ["wifi", "kitchen"],
  "maxItemsPerSearch": 300,
  "includeDetails": true,
  "includeReviews": true,
  "maxReviewsPerListing": 50,
  "startUrls": ["https://www.airbnb.com/rooms/51797569"]
}
```

### Output

Every record has a `recordType`: `listing` or `review`. A search result looks like this:

```json
{
  "recordType": "listing",
  "id": "33460323",
  "url": "https://www.airbnb.com/rooms/33460323",
  "name": "2 Be Part 2 - Bairro Alto",
  "propertyLabel": "Apartment in Bairro Alto",
  "latitude": 38.71266,
  "longitude": -9.14494,
  "rating": 4.88,
  "reviewCount": 212,
  "isSuperhost": true,
  "isGuestFavorite": false,
  "bedrooms": 2,
  "beds": 3,
  "bathrooms": 1.0,
  "currency": "EUR",
  "totalPrice": 359.0,
  "originalTotalPrice": null,
  "pricePerNight": 119.67,
  "nights": 3,
  "freeCancellation": true,
  "thumbnail": "https://a0.muscache.com/im/pictures/...",
  "images": ["..."],
  "checkIn": "2026-12-04",
  "checkOut": "2026-12-07",
  "adults": 2,
  "searchQuery": "Lisbon, Portugal",
  "page": 1,
  "scrapedAt": "2026-09-28T19:19:42+00:00"
}
```

With `includeDetails` (and always for listing URLs and IDs) the record also has:

```json
{
  "detailsScraped": true,
  "propertyType": "Entire condo in Paris, France",
  "description": "Ideally located in the heart of Paris ...",
  "maxGuests": 3,
  "locationText": "Paris, Île-de-France, France",
  "isExactLocation": true,
  "ratingBreakdown": {"accuracy": 4.91, "cleanliness": 4.92, "checkIn": 4.91, "location": 4.95, "communication": 4.92, "value": 4.82},
  "ratingDistributionPercent": {"5": 94.2, "4": 4.7, "3": 0.8, "2": 0.0, "1": 0.4},
  "hostName": "Pascale",
  "isSuperhost": true,
  "hostRating": 4.92,
  "hostYears": 5,
  "hostResponseTime": "Responds within an hour",
  "amenities": ["Kitchen", "Wifi", "Hair dryer"],
  "amenityGroups": {"Bathroom": ["Bathtub", "Hair dryer"]},
  "unavailableAmenities": ["Air conditioning"],
  "houseRules": {"checkIn": "Check-in after 4:00 PM", "checkOut": "Checkout before 10:00 AM", "items": ["No pets", "No parties or events"]},
  "sleepingArrangements": [{"room": "Bedroom", "beds": "2 single beds"}],
  "photos": [{"url": "https://a0.muscache.com/im/pictures/...", "caption": null}],
  "cancellationPolicy": "Free cancellation for 24 hours. After that, the reservation is non-refundable.",
  "cancellationTimeline": [{"when": "Within 24 hours after booking", "refund": "Full refund", "terms": "Get back 100% of what you paid."}],
  "totalPrice": 168.0,
  "priceBreakdown": [{"label": "2 nights x €84.00", "amount": 168.0, "amountText": "€168.00"}],
  "available": true
}
```

A review record:

```json
{
  "recordType": "review",
  "reviewId": "1668043507155412133",
  "listingId": "51797569",
  "listingUrl": "https://www.airbnb.com/rooms/51797569",
  "reviewerName": "Angela",
  "rating": 5,
  "text": "It was a nice stay",
  "language": "en",
  "translatedText": null,
  "createdAt": "2026-04-20T11:04:41Z",
  "dateText": "April 2026",
  "hostResponse": "Dear Angela, ...",
  "scrapedAt": "2026-09-28T19:19:42+00:00"
}
```

Export results as JSON, CSV, Excel or HTML, or pull them via the Apify API, webhooks, Make, Zapier, n8n or MCP.

### Pricing

Pay only for what you get: a small fee per run start, a fee **per listing**, a higher fee per listing **with details** (each needs its own page requests) and a fee **per review**. Proxy costs are included.

### FAQ

**How many stays can I get per search?** Airbnb shows at most 270 stays (15 pages of 18) for any search. Turn on **deep search** to split the map into tiles and read them one by one, or split the search yourself by price range, room type or neighbourhood.

**Are prices per night or for the whole stay?** With a check-in date, `totalPrice` is the total Airbnb shows for those dates and `pricePerNight` is that total divided by the nights. Without dates Airbnb shows a nightly price and only `pricePerNight` is filled. Prices are before taxes when Airbnb shows them that way.

**Why is the location of a listing approximate?** Airbnb blurs the pin of many listings until you book. `isExactLocation` tells you which ones are exact.

**Do I get host contact details or guest profiles?** No. The Actor returns only the public listing, the host's first name as shown on the listing, and reviewers' first names with their public review text.

**Does it need a proxy?** The default Apify datacenter proxy works for normal runs. Choose a residential proxy for very large deep searches.

**Is this legal?** The Actor collects only publicly visible data, without logins. You are responsible for handling the data in line with applicable laws (such as GDPR) and Airbnb's terms.

**Something broke?** Open an issue on the Issues tab. We monitor the Actor daily and usually respond within 24 hours.

# Actor input Schema

## `locations` (type: `array`):

Places to search, written the way you would type them on airbnb.com, e.g. "Paris, France", "Lisbon, Portugal", "Brooklyn, NY". Each location is a separate search that uses the filters below.

## `startUrls` (type: `array`):

Search result URLs copied from airbnb.com (their dates, guests and filters are kept) and/or single listing URLs (/rooms/...). Filters below are added to search URLs. Listing URLs always return full details.

## `listingIds` (type: `array`):

Airbnb listing IDs, e.g. 51797569 (the number after /rooms/ in a listing URL). Each one returns full details.

## `maxItemsPerSearch` (type: `integer`):

Stop each search after this many listings. Airbnb shows at most 270 stays (15 pages) per search; turn on deep search to go beyond that.

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

Stop the whole run after this many listings across all searches and listing URLs. 0 means no limit.

## `checkIn` (type: `string`):

YYYY-MM-DD. With dates, prices are the total for the stay and only available stays are returned. Without dates Airbnb shows the nightly price for a typical stay.

## `checkOut` (type: `string`):

YYYY-MM-DD, after the check-in date. If empty, the stay lasts the number of nights below.

## `nights` (type: `integer`):

Length of stay when only a check-in date is given.

## `adults` (type: `integer`):

Number of adults. Airbnb hides stays that cannot host this many guests.

## `children` (type: `integer`):

Children aged 2 to 12.

## `infants` (type: `integer`):

Infants under 2.

## `pets` (type: `integer`):

Number of pets. Only stays that allow pets are returned when this is above 0.

## `currency` (type: `string`):

Currency of all prices.

## `locale` (type: `string`):

Language of titles, descriptions, amenities and reviews as Airbnb translates them.

## `minPrice` (type: `integer`):

Lowest nightly price in the selected currency. 0 means no minimum.

## `maxPrice` (type: `integer`):

Highest nightly price in the selected currency. 0 means no maximum.

## `roomTypes` (type: `array`):

Only these kinds of stay. Leave empty for all.

## `minBedrooms` (type: `integer`):

At least this many bedrooms.

## `minBeds` (type: `integer`):

At least this many beds.

## `minBathrooms` (type: `integer`):

At least this many bathrooms.

## `amenities` (type: `array`):

Stays must have every selected amenity.

## `superhostOnly` (type: `boolean`):

Only stays hosted by a Superhost.

## `guestFavoriteOnly` (type: `boolean`):

Only stays with the Guest favorite badge.

## `instantBookOnly` (type: `boolean`):

Only stays you can book without waiting for host approval.

## `freeCancellationOnly` (type: `boolean`):

Only stays with a flexible cancellation policy.

## `deepSearch` (type: `boolean`):

Airbnb stops at 270 stays per search. When a search fills all 15 pages, split its map area into four tiles and search each one, recursively, to reach every stay. Uses more requests; combine it with a large 'Max listings per search'.

## `maxSplitDepth` (type: `integer`):

How many times a crowded map area may be split into quarters. 4 gives up to 256 tiles per search.

## `includeDetails` (type: `boolean`):

Open every listing for the full description, amenities, house rules, rating breakdown, host, coordinates, all photos and cancellation policy; with dates also the total price per cancellation option. Two to three extra requests per listing.

## `includeReviews` (type: `boolean`):

Add public guest reviews (first name, rating, date, text, host reply) as separate records after each listing.

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

Reviews are fetched 24 at a time.

## `reviewsSort` (type: `string`):

Newest first, or the order Airbnb shows by default (best quality first).

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

Listing pages fetched in parallel when details are on.

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

Apify Proxy rotates the exit IP. The default datacenter proxy is included in the price; choose residential if Airbnb blocks a run.

## Actor input object example

```json
{
  "locations": [
    "Lisbon, Portugal"
  ],
  "maxItemsPerSearch": 20,
  "maxItems": 0,
  "nights": 3,
  "adults": 1,
  "children": 0,
  "infants": 0,
  "pets": 0,
  "currency": "USD",
  "locale": "en",
  "superhostOnly": false,
  "guestFavoriteOnly": false,
  "instantBookOnly": false,
  "freeCancellationOnly": false,
  "deepSearch": false,
  "maxSplitDepth": 4,
  "includeDetails": false,
  "includeReviews": false,
  "maxReviewsPerListing": 50,
  "reviewsSort": "most_recent",
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "locations": [
        "Lisbon, Portugal"
    ],
    "maxItemsPerSearch": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("randy-tools/airbnb-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 = {
    "locations": ["Lisbon, Portugal"],
    "maxItemsPerSearch": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("randy-tools/airbnb-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 '{
  "locations": [
    "Lisbon, Portugal"
  ],
  "maxItemsPerSearch": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call randy-tools/airbnb-scraper --silent --output-dataset

```

## MCP server setup

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