# Airbnb Scraper: Listings, Prices, Occupancy & Revenue (`ayrtondavoli97/airbnb-scraper`) Actor

Every Airbnb listing in a city with prices, ratings, host & amenities, plus 12-month availability, estimated occupancy and annual revenue per listing. Market summary per area and competitor tracking. Gets past the ~300-result limit. CSV, Excel, JSON, API.

- **URL**: https://apify.com/ayrtondavoli97/airbnb-scraper.md
- **Developed by:** [Francesco Ayrton Davoli](https://apify.com/ayrtondavoli97) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 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.

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, Occupancy & Revenue

Extract **every Airbnb listing in a city or area** with prices, ratings, photos and, uniquely, **12-month availability, estimated occupancy and estimated annual revenue** for each listing. Built for short-term-rental investors, hosts, property managers and analysts who need an affordable alternative to AirDNA-style market data.

- 🗺️ **Whole-city coverage**: Airbnb shows at most ~300 results per map view. This Actor detects truncated areas and **splits them automatically**, so you get all listings, not just the first pages.
- 💶 **Prices**: price per night, stay total, cleaning fee, service fee, discounts (exact for your dates when check-in/out are set).
- 📅 **Availability & occupancy**: free nights in the next 30/90/365 days, estimated occupancy, next available date, typical minimum stay.
- 📈 **Estimated annual revenue** per listing (price per night × estimated occupied nights).
- 📊 **Market summary per location**: median price per night and quartiles, median price by number of bedrooms, average occupancy, median and top-quartile annual revenue, share of Superhosts and Guest Favourites.
- 🔁 **Competitor tracking**: schedule it on the same area and get price change (€ and %), availability change and new listings since the previous run.
- 🏠 **Listing details** (from each listing page): property type ("Entire villa in Monopoli"), guests, bedrooms, beds, baths, review count, the **6 rating categories** (cleanliness, accuracy, check-in, communication, location, value), host name, years hosting, response rate, verified/Superhost, host-level rating and reviews, full amenities list (50+ items) with quick flags (pool, A/C, sea view, hot tub, free parking, wifi, kitchen, washer, pets allowed), full description.
- ⭐ Rating, reviews, Guest Favourite and Superhost flags, coordinates, up to 10 photos.
- 🔎 Search by **location name** ("Bari, Italy", "Trastevere, Rome") or paste **Airbnb search URLs** with your filters.
- ⚡ Fast and cheap: direct calls to Airbnb's web API, no browser.

### Use cases

| Who | What for |
|---|---|
| STR investors | Compare occupancy and revenue across neighbourhoods before buying |
| Hosts & property managers | Track competitor prices and availability, set your rates |
| Real estate agents | Show buyers the rental potential of an area |
| Analysts, journalists, city councils | Measure short-term-rental supply and pressure on housing |

### Input

| Field | Description |
|---|---|
| `locations` | List of places, e.g. `["Monopoli, Italy", "Polignano a Mare"]` |
| `startUrls` | Airbnb search URLs (filters and map area are kept) |
| `checkIn`, `checkOut` | Optional dates for exact prices |
| `adults`, `roomType`, `minBedrooms`, `priceMin`, `priceMax` | Optional filters |
| `currency` | EUR, USD, GBP, CHF |
| `includeDetails` | Listing page details: type, rooms, review count, rating categories, host, amenities (default on) |
| `includeCalendar` | Availability & occupancy metrics (default on) |
| `maxItems` | 0 = all listings in the area |
| `trackChanges`, `trackingId` | Compare with the previous run of the same tracked search |

### Output example

```json
{
  "id": "53817392",
  "url": "https://www.airbnb.com/rooms/53817392",
  "name": "Trullo with pool near Monopoli",
  "title": "Home in Monopoli",
  "rating": 4.92,
  "reviewsCount": 137,
  "isGuestFavorite": true,
  "isSuperhost": false,
  "currency": "EUR",
  "pricePerNight": 120,
  "priceTotal": 600,
  "nights": 5,
  "cleaningFee": 50,
  "availableNights30": 6,
  "availableNights90": 31,
  "estimatedOccupancy90": 0.656,
  "estimatedOccupancy365": 0.48,
  "estimatedAnnualRevenue": 21024,
  "nextAvailableDate": "2026-10-19",
  "minNightsTypical": 2,
  "propertyType": "Entire home in Monopoli, Italy",
  "guests": 4,
  "bedrooms": 2,
  "beds": 3,
  "bathrooms": 1,
  "ratingCleanliness": 4.95,
  "ratingLocation": 4.81,
  "hostName": "Paolo",
  "hostYearsHosting": 4.2,
  "hostResponseRate": 90,
  "amenitiesCount": 57,
  "hasPool": false,
  "hasAirConditioning": true,
  "petsAllowed": true,
  "lat": 40.95,
  "lng": 17.30,
  "thumbnail": "https://a0.muscache.com/im/pictures/...",
  "searchLocation": "Monopoli, Italy"
}
```

### Market summary

Saved in the run's key-value store as `MARKET_SUMMARY` (link in the Output tab), one object per location:

```json
{
  "location": "Monopoli, Italy",
  "listings": 812,
  "currency": "EUR",
  "pricePerNightMedian": 107.5,
  "pricePerNightP25": 82,
  "pricePerNightP75": 150,
  "medianPricePerNightByBedrooms": {"0": 70, "1": 88, "2": 120, "3": 185, "4+": 290},
  "avgEstimatedOccupancy90": 0.58,
  "estimatedAnnualRevenueMedian": 18400,
  "estimatedAnnualRevenueP75": 27100,
  "avgRating": 4.84,
  "shareGuestFavorite": 0.41,
  "shareSuperhost": 0.33
}
```

### How occupancy is estimated

Airbnb's calendar marks each future night as available or not. Unavailable nights are either **booked or blocked by the host**, and Airbnb doesn't distinguish them, so `estimatedOccupancy*` is an **upper-bound estimate**. It's most reliable for active listings (recent reviews, Guest Favourite). `estimatedAnnualRevenue` uses the current price per night; prices vary by season, so treat it as an indication, and set check-in/out dates for exact prices.

### Tips

- Results are saved progressively: if a run hits its timeout, everything found so far is already in the dataset.
- A whole city with details and calendars can take 10–30 minutes: set the run timeout to 1 hour (default).
- Start with `maxItems: 20` to preview, then set 0 for the whole area.
- Turn off `includeDetails` and `includeCalendar` if you only need prices and ratings: runs are several times faster and cheaper.
- Track competitors: enable `trackChanges`, set a `trackingId` (e.g. `monopoli-sea-view`) and schedule the run daily or weekly.

### Responsible use

The Actor collects publicly visible listing data only (no guest data, no host contact details). You are responsible for complying with applicable laws (including GDPR) and Airbnb's terms in how you use the data.

# Actor input Schema

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

Cities, neighbourhoods or regions, e.g. 'Bari, Italy', 'Trastevere, Rome', 'Lisbon'. Big areas are split automatically to get past Airbnb's ~300-result limit.

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

Optional: paste Airbnb search URLs (with your filters and map area) instead of, or in addition to, locations.

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

Optional. With dates you get exact prices and totals for that stay; without dates Airbnb shows indicative prices.

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

Optional, required if check-in is set.

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

Optional number of guests.

## `roomType` (type: `string`):

Filter by type of place.

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

Optional.

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

Optional, in the selected currency.

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

Optional, in the selected currency.

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

Currency for all prices.

## `includeCalendar` (type: `boolean`):

Fetch the 12-month calendar of each listing: available nights, estimated occupancy (30/90/365 days), next free date, estimated annual revenue. Adds one request per listing.

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

Open each listing page for property type, guests, bedrooms, beds, baths, review count, the 6 rating categories (cleanliness, location…), host name and experience, amenities (pool, A/C, parking…) and description. Adds one request per listing.

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

0 = all listings in the area. Prefilled with 20 for a quick first try.

## `trackChanges` (type: `boolean`):

For scheduled runs on the same area: adds priceChange, priceChangePct, availableNights90Change and isNewListing compared with the previous tracked run.

## `trackingId` (type: `string`):

Name of the tracked search (e.g. 'monopoli-competitors'). Use different IDs for different areas.

## `keepArrays` (type: `boolean`):

Off: lists (images, badges) are joined with '; ' for clean CSV/Excel. On: native JSON arrays.

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

Residential proxy recommended.

## Actor input object example

```json
{
  "locations": [
    "Monopoli, Italy"
  ],
  "roomType": "any",
  "currency": "EUR",
  "includeCalendar": true,
  "includeDetails": true,
  "maxItems": 20,
  "trackChanges": false,
  "keepArrays": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Listings with prices, rating and occupancy.

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

Every field of every listing.

## `csv` (type: `string`):

Full dataset as CSV.

## `marketSummary` (type: `string`):

Median price per night, quartiles, occupancy, revenue, Superhost/Guest Favourite share, price by bedrooms.

# 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": [
        "Monopoli, Italy"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

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

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

```

## MCP server setup

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