# Airbnb Listings Scraper (`lergassy/airbnb-listings-scraper`) Actor

\[$1.20/1K listings] Scrape Airbnb listings for any city and dates: stay and nightly price, rating, review count, coordinates, bedrooms, badges, photos; optional description, amenities, host, calendar and reviews. No browser, no login.

- **URL**: https://apify.com/lergassy/airbnb-listings-scraper.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Travel, Real estate, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.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 Listings Scraper** collects Airbnb listings for any city, neighbourhood or region and any dates, and returns them as a clean table: the **total price for the stay and the price per night** in the currency you pick, the struck-through original price and discount, rating and review count, property type and area, coordinates, beds and bedrooms, Guest favorite badge and photos. Switch on one option and every listing also gets its description, full amenities list, host (Superhost, response rate and time), guest capacity, bathrooms, category sub-ratings, cancellation policy and house rules. It reads the data Airbnb puts into its own pages, so there is **no browser, no login and no Airbnb API key**. Export to JSON, CSV or Excel, run it on a schedule, or call it from the API, n8n, Make, Zapier or an AI agent through MCP.

> This is the listings-focused edition of **[Airbnb Scraper](https://apify.com/lergassy/airbnb-scraper)** — same engine and same price, set up so that one city in, one table of listings out.

### What data does Airbnb Listings Scraper return?

| Field | Example from a real run (Lisbon, 6 October 2026) |
|---|---|
| `name`, `propertyType`, `area` | Av Liberdade Historic Center I Balcony I AC I WiFi · Apartment · Santo António |
| `priceTotal`, `pricePerNight`, `currency`, `nights` | 390 · 130 · USD · 3 |
| `priceOriginal`, `discountPercent` | 467 · 16 |
| `rating`, `reviewCount` | 4.9 · 305 |
| `badges`, `isGuestFavorite` | \["Guest favorite"] · true |
| `bedInfo`, `highlights` | \["2 beds"] · \["Free cancellation"] |
| `latitude`, `longitude` | 38.7193 · -9.1428 (approximate, as Airbnb shows before booking) |
| `images` | photo URLs |
| `checkIn`, `checkOut`, `adults` | the stay and party the price was quoted for |
| `url`, `listingId`, `position`, `page`, `query`, `place` | link, id, order, page, your query, how Airbnb understood the place |

With **Open every listing page** (`includeDetails`): `description`, `amenities` and `amenityGroups`, `hostName`, `isSuperhost`, `hostResponseRate`, `hostResponseTime`, `personCapacity`, `bedrooms`, `beds`, `bathrooms`, `roomType`, `categoryRatings` (cleanliness, accuracy, check-in, communication, location, value), `ratingDistribution`, `cancellationPolicy`, `houseRules`, `checkInTime`, `checkOutTime`.

With **Availability calendar** (`includeCalendar`): `minNights`, `maxNights`, `availableOnCheckIn`, day-by-day `calendar` and `availabilityByMonth` with occupancy per month. With **Reviews** (`includeReviews`): the latest guest reviews with the host's replies, on the same row.

### How much does it cost?

Pay per result, **no fee per run**. Error rows and "nothing found" rows are always free.

| Event | Price (Free plan) | Per 1,000 |
|---|---|---|
| Listing (from search or a listing URL) | $0.0012 | **$1.20** |
| Listing detail (add-on: description, amenities, host, rules) | $0.004444 | $4.44 |

Higher Apify plans pay less: a listing goes down to $0.84 per 1,000. The monthly $5 credit of the Apify Free plan covers about 4,000 listings.

### How to scrape Airbnb listings

1. Click **Try for free** (a free Apify account is enough).
2. Type one or more places into **Where**, for example `Lisbon, Portugal` or `Brooklyn, NY`.
3. Set **Check-in** and **Check-out** (without dates the run quotes a 3-night stay starting 30 days from today) and the number of guests.
4. Set **Maximum listings** (50 by default, up to 500; the cap is for the whole run, so with several places the first ones can fill it) and click **Start**.
5. Open the **Output** tab and download the table, or read the dataset through the API.

You can also paste Airbnb search URLs with your own filters, or single listing URLs (`https://www.airbnb.com/rooms/…`), into **Airbnb URLs**.

### ⬇️ Input example

Entire places with at least 2 bedrooms in Austin, $100–250 a night, with the calendar:

```json
{
  "locationQueries": ["Austin, Texas"],
  "checkIn": "2026-11-20",
  "checkOut": "2026-11-23",
  "adults": 4,
  "roomTypes": ["Entire home/apt"],
  "minBedrooms": 2,
  "priceMin": 100,
  "priceMax": 250,
  "maxListings": 30,
  "includeCalendar": true
}
```

An empty input (`{}`) is a demo: 50 Lisbon listings for a 3-night stay a month from today.

### ⬆️ Output example

```json
{
  "type": "listing",
  "listingId": "1075655",
  "url": "https://www.airbnb.com/rooms/1075655",
  "name": "Av Liberdade Historic Center I Balcony I AC I WiFi",
  "propertyType": "Apartment",
  "area": "Santo António",
  "latitude": 38.7193,
  "longitude": -9.1428,
  "priceTotal": 390,
  "priceOriginal": 467,
  "pricePerNight": 130,
  "currency": "USD",
  "nights": 3,
  "rating": 4.9,
  "reviewCount": 305,
  "isGuestFavorite": true,
  "bedInfo": ["2 beds"],
  "place": "Lisbon, Portugal",
  "checkIn": "2026-11-05",
  "checkOut": "2026-11-08",
  "discountPercent": 16
}
```

### Use cases

#### Hosts and property managers

See what comparable listings in your street charge for the same dates, which ones carry the Guest favorite badge, and how their prices move week to week on a schedule.

#### Short-term rental investors and analysts

Pull every listing in a city in price bands, then size the market: nightly rate by area and property type, share of entire homes, occupancy from the calendar.

#### Travel apps and AI agents

One call returns a structured list of stays with numeric prices, ready for ranking, maps or retrieval in an LLM pipeline.

### Limits, honestly

- Airbnb stops paging a search at about 270 results. The Actor then repeats the same search in price bands and de-duplicates by listing, which gets well past that (300 Lisbon listings came back in 86 seconds in our test), but a small town simply has fewer listings.
- Coordinates are approximate until booking — that is Airbnb's own rule.
- A place Airbnb does not recognise is not "searched anyway": you get one free row explaining it, not random listings from other countries.
- Prices are what Airbnb quotes for your dates and party, before any personal coupons.

### ❓ FAQ

#### Is it legal to scrape Airbnb?

The Actor reads only public listing pages that anyone can open without logging in, and collects no guest personal data beyond what Airbnb publishes on the page. Check that your use follows Airbnb's terms and the privacy law of your country.

#### Do I need a proxy?

No. Apify Proxy is on by default, and if Airbnb starts rate-limiting, the run switches itself to residential addresses. That is included in the price.

#### Why is a field empty?

Search cards carry only what Airbnb shows on the card: a listing with no reviews has `rating: null`, a listing without a discount has `priceOriginal: null`. Switch on **Open every listing page** for the full record.

#### Can I get only new listings every day?

Yes — fill **Only new rows — memory name** and schedule the Actor; later runs write and charge only listings you have not received before.

### Your feedback

Something missing or wrong in the table? Open an issue in the **Issues** tab — it is read and answered.

# Actor input Schema

## `locationQueries` (type: `array`):

Cities or areas to collect Airbnb listings from, one per line, typed the way you would type them into Airbnb: <code>Lisbon, Portugal</code>, <code>Brooklyn, NY</code>, <code>Ubud, Bali</code>. Give this or <code>startUrls</code>; with neither, the run lists Lisbon as a demo.

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

First night, YYYY-MM-DD. Airbnb quotes a price only for a date range; leave both dates empty and the Actor searches a stay one month out.

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

Departure day, YYYY-MM-DD.

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

Prices change with occupancy, so set the real party size.

## `maxListings` (type: `integer`):

Cap per run across all places. Airbnb returns 18 listings per page and rarely more than about 270 per search.

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

Currency the prices are quoted in.

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

Adds description, amenities, host, capacity, bedrooms and beds, review tags and exact-location flag. One extra request per listing.

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

For each listing, read the host's calendar: day-by-day availability, the minimum and maximum nights on your check-in date, and occupancy per month. Needs the listing page, so it is billed as a detail row — no extra event.

## `calendarMonths` (type: `integer`):

How many months ahead to read, counting from check-in. 1–12.

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

For each listing, the latest guest reviews with rating, date, text, reviewer and the host's reply. Billed as a detail row — no extra event.

## `maxReviews` (type: `integer`):

Newest first, up to 200.

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

Instead of a place: paste Airbnb search URLs (with your own filters) or listing URLs like <code>https://www.airbnb.com/rooms/1591176990185841592</code>. Listing URLs are always opened in full.

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

Children in the party.

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

Infants in the party.

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

Pets travelling.

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

In the chosen currency.

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

In the chosen currency.

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

Filter applied by Airbnb itself.

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

Filter applied by Airbnb itself.

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

Filter applied by Airbnb itself.

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

Leave empty for all types.

## `maxPages` (type: `integer`):

Each page holds 18 listings. The run stops earlier when a page adds nothing new.

## `onlyNewRowsStore` (type: `string`):

Give this run a name — <code>my-listings-watch</code> — and the Actor remembers every listing row it delivered under that name. Every later run with the same name writes and charges <b>only rows you have not received before</b>. Schedule the Actor daily to get a feed of new listings instead of the whole list each time. Leave empty to get everything found, every time.

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

Apify Proxy is on by default — Airbnb rate-limits repeat callers by IP address. If Airbnb starts refusing pages, the run switches itself to residential addresses; you can also pick residential here up front for large jobs.

## Actor input object example

```json
{
  "locationQueries": [
    "Lisbon, Portugal"
  ],
  "adults": 2,
  "maxListings": 50,
  "currency": "USD",
  "includeDetails": false,
  "includeCalendar": false,
  "calendarMonths": 3,
  "includeReviews": false,
  "maxReviews": 24,
  "children": 0,
  "infants": 0,
  "pets": 0,
  "maxPages": 15,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

One row per listing: name, property type and area, coordinates, total and per-night price for the searched dates, rating and review count, badges such as Guest favorite, bed info, images. With details on: description, amenities by group, host and Superhost flag, capacity, bedrooms, beds, bathrooms, review tags.

## `runSummary` (type: `string`):

JSON counters for the run: rows delivered, filtered out, errors and request statistics.

# 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 = {
    "locationQueries": [
        "Lisbon, Portugal"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/airbnb-listings-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 = { "locationQueries": ["Lisbon, Portugal"] }

# Run the Actor and wait for it to finish
run = client.actor("lergassy/airbnb-listings-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 '{
  "locationQueries": [
    "Lisbon, Portugal"
  ]
}' |
apify call lergassy/airbnb-listings-scraper --silent --output-dataset

```

## MCP server setup

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