# Airbnb Scraper — Listings, Prices, Ratings & Hosts (`bovi/airbnb-scraper`) Actor

Scrape public Airbnb stays from Airbnb. Get listing, price, rating, host, location, amenity, and image data. Run with a location; no buyer API key, cookies, or Airbnb login. Pricing: $0.0019 per listing-item event on Free; Actor Start is $0.00005.

- **URL**: https://apify.com/bovi/airbnb-scraper.md
- **Developed by:** [Vitalii Bondarev](https://apify.com/bovi) (community)
- **Categories:** Travel, Real estate
- **Features:** Limited permissions
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.84 / 1,000 listings

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 Scraper for Listings and Prices

Scrape public Airbnb stays by city, region, or address through Airbnb’s internal GraphQL API, with optional dates, adult counts, and nightly price filters. Run it from your Apify account with no API key, cookies, or Airbnb login; records include listing, price, rating, host, location, amenity, and image data.

- Collect structured listing data for travel planning and market research.
- Compare nightly and total stay prices, ratings, reviews, and amenities for rental analysis.
- Find Superhost and Guest Favorite listings for partnership or lead-generation research.
- Use GPS coordinates and image URLs in property and travel applications.

### What you get

The Actor returns 26 structured fields for each listing. A field is `null` when Airbnb does not provide the value; `amenities` and `images` are empty arrays when no values are available.

| Field family | Fields | Type | What it contains |
|---|---|---|---|
| Identity | `listing_id`, `url` | string | Listing identifier and URL; `null` if unavailable |
| Listing description | `title`, `name` | string | Listing context and name; `null` when unavailable |
| Listing description | `room_type` | string | Room type; comes only from detail-page enrichment, otherwise `null` |
| Prices and stay | `price_per_night`, `price_total`, `price_original` | number | Nightly, total, and original prices; `null` when unavailable |
| Prices and stay | `stay_nights`, `currency` | integer; string | Stay length can be `null`; currency is `USD` |
| Ratings and badges | `rating`, `review_count`, `is_superhost`, `is_guest_favorite` | number; integer; boolean | Rating and review count can be `null`; badge fields are boolean |
| Host | `host_name`, `host_id` | string | Host name and identifier; come only from detail-page enrichment, otherwise `null` |
| Space | `person_capacity` | number | Guest capacity; comes only from detail-page enrichment, otherwise `null` |
| Space | `bedrooms`, `beds`, `bathrooms` | string | Text from the search card, for example "1 bedroom"; can be `null` |
| Location | `latitude`, `longitude` | number | Listing GPS coordinates; values can be `null` |
| Amenities and media | `amenities`, `images` | array of strings | Amenity names (detail-page enrichment only) and image URLs; empty when no values are available |
| Run context | `search_location`, `scraped_at` | string; ISO 8601 string | Searched location and record timestamp; populated for successful records |

With `enrichDetails`, the Actor also fetches listing detail pages for host, room type, capacity, and amenity information.

### Sample output

The sample is shortened to two image URLs.

```json
{
  "listing_id": "1265043383778376281",
  "url": "https://www.airbnb.com/rooms/1265043383778376281",
  "title": "Hotel Augustin - Astotel",
  "name": "Hotel Augustin - Astotel, Twin room",
  "room_type": "Private room",
  "price_per_night": 118.66, "price_total": null, "price_original": null, "stay_nights": 2, "currency": "USD",
  "rating": 4.89, "review_count": 622, "is_superhost": false, "is_guest_favorite": false,
  "host_name": null, "host_id": null, "bedrooms": null, "beds": null, "bathrooms": null, "person_capacity": 2,
  "latitude": 48.8754, "longitude": 2.3183,
  "amenities": ["Breakfast for purchase", "Air conditioning", "Wifi", "Elevator", "Dedicated workspace", "TV", "Hair dryer", "Luggage dropoff allowed", "Toiletries"],
  "images": ["https://a0.muscache.com/im/pictures/BnbProperty/BnbProperty-1690121189016553584/original/dde5590c-3344-47ee-a880-bbe64dbdb86d.jpeg", "https://a0.muscache.com/im/pictures/BnbProperty/BnbProperty-1690121189016553584/original/04c9815d-231a-497a-a125-319ba01d667c.jpeg"],
  "search_location": "Paris, France", "scraped_at": "2026-10-29T04:44:48.888758+00:00"
}
```

### Pricing

The Actor uses pay-per-event billing. `listing-item` represents one returned listing with price, rating, host, beds, amenities, coordinates, and images. `apify-actor-start` is charged once per GB of run memory, with a minimum of one event.

You pay only for the events listed below. This Actor does not use the Pay per event + usage option, so the platform usage of your runs (compute, proxy traffic and storage) is not billed to you separately.

| Event | Billing unit | Free plan |
|---|---|---:|
| `listing-item` | One returned Airbnb listing | $0.0019 per event on Free |
| `apify-actor-start` | One event per GB of run memory, minimum one event | $0.00005 per event on Free |

`listing-item` is charged after the corresponding records are successfully pushed. `apify-actor-start` is charged when the Actor starts running.

At Free-plan rates, 1,000 x $0.0019 = $1.90 and 10,000 x $0.0019 = $19.00 for `listing-item` events.

On the Free plan, the $5 monthly platform usage credit covers 2,631 `listing-item` results plus one minimum `apify-actor-start` event, totaling $4.99895 on Free.

### How to use

1. Open the Actor in your Apify account.
2. Enter the required `location`, such as `Paris, France`, a city, region, or address.
3. Add optional `checkIn` and `checkOut` dates in `YYYY-MM-DD` format for stay prices.
4. Set `adults`, `priceMin`, `priceMax`, and a positive `maxItems` value to narrow the search.
5. Enable `enrichDetails` for host names, room type, capacity, and amenities; use a residential proxy for detail enrichment at scale.
6. Run the Actor and inspect the dataset. Repeat through Apify Schedules, starting with a daily schedule for listing or price monitoring.

Example input:

```json
{
  "location": "Paris, France",
  "adults": 2,
  "priceMin": 80,
  "priceMax": 250,
  "maxItems": 20,
  "enrichDetails": true,
  "proxyConfiguration": {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}
}
```

Export the dataset as JSON or CSV, or read it through the Apify dataset API.

### Input parameters

| Parameter | What it does | Default |
|---|---|---|
| `location` | Required city, region, or address passed to Airbnb search | Required |
| `checkIn` | Optional check-in date in `YYYY-MM-DD`; used with `checkOut` for stay pricing | Not set |
| `checkOut` | Optional check-out date in `YYYY-MM-DD` | Not set |
| `adults` | Adult guests passed to search; constrained to 1–16 | `1` |
| `priceMin` | Minimum nightly price in USD | Not set |
| `priceMax` | Maximum nightly price in USD | Not set |
| `maxItems` | Maximum listings to push; default is 100 | `100` |
| `enrichDetails` | Fetches detail pages for host, room type, capacity, and amenities | `true` |
| `proxyConfiguration` | Configures proxy use for search and detail requests | `useApifyProxy: true`, group `RESIDENTIAL` |
| `disableUsageStats` | Set to `true` to turn off the run summary described in Usage statistics. | `false` |

### Limits and edge cases

| Condition | What you see | What to do |
|---|---|---|
| Airbnb limits results for a location search | Approximately 270–300 available listings per search | Search by neighborhood or vary the date range |
| `maxItems` is omitted | The default maximum of 100 listings is used | Set a positive `maxItems` value |
| A search page has no results | Pagination stops; an empty first page produces no records | Check the location and reduce restrictive filters |
| `enrichDetails` is `false` | Detail fetching is skipped; `host_name`, `host_id`, `room_type`, `person_capacity`, and `amenities` stay null or empty | Enable `enrichDetails` when needed |
| A detail page cannot be fetched | The search-level record is still pushed; detail fields can be unavailable | Use residential proxy configuration for enrichment at scale |
| A search page is blocked | The Actor retries with a new session and proxy URL; the run stops after 3 attempts, and a blocked first page produces no records | Configure a residential proxy and review logs |
| A later page has a search or transport error | Records from completed earlier pages have already been pushed to the dataset; the later page is incomplete | Review logs and retry with the same or adjusted input |
| Airbnb does not provide a value | Fields such as `price_total`, host, or space fields can be `null` | Use available fields or try suitable dates and filters |

### FAQ

#### How much does it cost to scrape Airbnb stays?

On the Free plan, each `listing-item` event costs $0.0019 and each `apify-actor-start` event costs $0.00005. 1,000 `listing-item` events cost $1.90 on Free.

#### Why did the Actor return an empty dataset?

The search may have no results for the location, dates, guest count, or price range. Broaden the location, remove restrictive filters, or run without dates.

#### What should I do if the Actor is not working?

Check the run logs for a blocked search page, Airbnb fetch error, or transport error. Configure a residential proxy for detail enrichment at scale and rerun if needed.

#### Why are `host_name` or `amenities` missing?

They come only from detail-page enrichment and can be unavailable when `enrichDetails` is disabled or a detail page cannot be fetched.

#### Is it legal or allowed to scrape Airbnb public data?

The Actor extracts data exposed through Airbnb’s public search and listing experience through that same API. Whether a particular use is legal or allowed depends on your use case, applicable law, and the source’s terms; review those requirements before using the data.

### Related actors

- [Multi-Platform STR Monitor — Airbnb + Booking](https://apify.com/bovi/multi-stl-rental-monitor) — monitoring short-term rental listings across Airbnb and Booking.
- [Gathern Rental Listings Scraper](https://apify.com/bovi/gathern-scraper) — rental listings scraper.
- [Sutochno.ru Accommodation Listings](https://apify.com/bovi/sutochno-ru-scraper) — accommodation-listing extraction for Sutochno.ru.

### Rate this Actor

If Airbnb Scraper saved you time, please rate it on the Apify Store. A rating takes a few seconds and helps other people find a working scraper.

### Usage statistics

This Actor creates a small, content-free summary at the end of each run, used only to monitor reliability and improve this Actor. No input values, credentials or scraped data are sent.

A copy of the exact record for your run is saved as `USAGE_STATS` in your own Apify key-value store.

To opt out, set `disableUsageStats` to `true` in the input. Nothing is sent then.

[Full list of collected fields](https://api.apify.com/v2/key-value-stores/v9rgHjMKLDGtHf8tD/records/index.html)

# Actor input Schema

## `location` (type: `string`):

City, region, or address to search on Airbnb (e.g. 'Paris, France', 'New York, NY', 'Tokyo, Japan'). Required.

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

Optional check-in date in ISO format (e.g. '2026-07-10'). When set, prices will reflect the actual stay cost. Leave blank for general listing prices.

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

Optional check-out date in ISO format (e.g. '2026-07-15'). Must be after checkIn.

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

Number of adult guests (default 1). Affects which listings are shown.

## `priceMin` (type: `integer`):

Only return listings priced at or above this amount per night. Leave blank for no minimum.

## `priceMax` (type: `integer`):

Only return listings priced at or below this amount per night. Leave blank for no maximum.

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

Maximum number of listings to return. Default 100. Set to 0 for all available (up to Airbnb's ~300 result cap). You are charged per listing returned.

## `enrichDetails` (type: `boolean`):

When enabled, fetches each listing's detail page to add host name and full amenities list. Costs one extra request per listing but gives richer data. Default: true.

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

Proxy settings for scraping. Airbnb's search API typically works without a proxy, but RESIDENTIAL is recommended for detail-page enrichment at scale.

## `disableUsageStats` (type: `boolean`):

See the README Usage statistics section for details.

## Actor input object example

```json
{
  "location": "Paris, France",
  "adults": 1,
  "maxItems": 20,
  "enrichDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "disableUsageStats": false
}
```

# Actor output Schema

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

Dataset containing Airbnb Scraper records (listing_id, title, name, room_type, price_per_night, price_total, rating, review_count, is_superhost, host_name, beds, bedrooms, latitude, longitude, url).

# 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 = {
    "location": "Paris, France",
    "adults": 1,
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("bovi/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 = {
    "location": "Paris, France",
    "adults": 1,
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("bovi/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 '{
  "location": "Paris, France",
  "adults": 1,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call bovi/airbnb-scraper --silent --output-dataset

```

## MCP server setup

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