# Airbnb Scraper: Listings, Prices, Availability & Reviews (`zaiq/airbnb-scraper`) Actor

Search public stays by location, dates, guests and filters. Get listing details, dated prices, amenities, host information, reviews and availability calendars. No login. Failed requests are free.

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

## Pricing

from $2.40 / 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: Listings, Prices, Availability & Reviews

![Airbnb Scraper: Listings, Prices, Availability & Reviews](https://api.apify.com/v2/key-value-stores/4VJNANhwKgqPpXtAi/records/hero-airbnb-scraper.jpg)

Collect public rental listings by city, region or listing link. Search with dates, guest counts, price limits, room type and minimum bedrooms, beds or bathrooms. Keep listing details on for descriptions, amenities, host information, photos, policies and a quote for your dates.

Add public reviews or an availability calendar when you need them. Listings, reviews and calendars have separate row types and share the listing ID. No account or login is required. Failed requests are recorded as free notes, and each delivered result is charged once under its event.

Location checks compare your requested city or region and country with the site’s resolved location. An ambiguous name such as a region without its country is rejected with an explanation. A result from a different location is not sold as the place you requested.

### What you get

| Field | What it holds |
|---|---|
| Listing identity | `kind: listing`, `id`, `url`, `title`, `type`, `roomType`, `location`, `coordinates`, `latitude`, `longitude` |
| Dated prices | `checkin`, `checkout`, `currency`, `pricePerNight`, `priceTotal`, `priceDetails`, `priceNote`; with a successful detailed quote, `stay` and `availableForDates` |
| Search provenance | `search`, `resolvedLocation`, `resolvedCountry`, `resolvedCity`, `resolvedState`, `searchTitle`, `searchTotal`, `filtersApplied` |
| Property and reputation | `guests`, `bedrooms`, `beds`, `baths`, `rating`, `reviewsCount`, `superhost`, `badges`, `guestFavorite`; fields absent from the public response remain null |
| Full details | `description`, `amenities`, `notIncluded`, `sleeping`, `houseRules`, `safety`, `host`, `photos`, `ratings`, `ratingShares`, `reviewTopics`, cancellation terms when returned |
| Review rows | `kind: review`, `listingId`, `id`, `rating`, `text`, `language`, `translation`, `date`, `createdAt`, public author fields, `stay`, `reply`, `replyDate`, review photos |
| Calendar rows | `kind: calendar`, `listingId`, `from`, `to`, `openDays`, `closedDays`, monthly counts, closed-date ranges and `days` with availability, minimum and maximum nights, check-in and check-out restrictions |
| Run evidence | `scrapedAt` on data rows. `SUMMARY` contains delivered counts, charges, request count, timing, traffic, spending-limit status and notes. |

### What people use it for

- **Compare rental supply:** Collect the same fields for properties in selected cities or neighbourhoods and compare accommodation types, capacity and amenities.
- **Monitor displayed prices:** Repeat a search for the same dates, guests and currency. Keep each run’s timestamp and quoted dates so price comparisons describe the same stay.
- **Read public guest feedback:** Export review text, stars, dates and host replies. Sort by newest, relevance, highest or lowest rating before collecting.
- **Track calendar changes:** Compare public availability snapshots over time. Closed dates alone cannot tell you whether a property is booked or blocked by its host.
- **Maintain a property dataset:** Use listing IDs to join listing, review and calendar rows in a database or spreadsheet.

### How to use it

1. Enter one city or region followed by its country per entry in Locations, or add public listing links or IDs. Use the full English country name; common codes such as US, ZA and GB are also accepted.
2. Choose dates, currency and guest counts. Dates apply to every location and listing link in the run. Without dates, search rows use the site’s own suggested dates; direct links have no dated quote.
3. Choose the listings per location. The default is three with details on. Set reviews per listing above zero or enable the calendar if needed.
4. Set Maximum cost per run and start. Open the dataset and use `kind` to select listing, review, calendar or free note rows. Read SUMMARY for partial results and limits.

### Input

| Field | Example | Notes |
|---|---|---|
| Locations | `["Cape Town, South Africa"]` | Up to 20 locations. Country is required to avoid resolving a name in the visitor’s country. |
| Listing links or IDs | Your public listing links or numeric IDs | Up to 50; duplicates for the same dates are skipped. |
| Check in / Check out | `2026-11-16` / `2026-11-19` | YYYY-MM-DD. Check out must follow check in. Update dates when reusing an example. |
| Nights | `3` | Used only when check in is supplied without check out. |
| Adults / Children / Infants / Pets | `2` / `0` / `0` / `0` | Included in search and dated quote requests. |
| Listings per location | `3` | 1–270; search results may overlap across nearby areas. |
| Listing details | on | One detailed-listing event replaces the basic-listing event. |
| Reviews per listing | `0` | 0–2,000; the public number available may be smaller. |
| Availability calendar | off | Current calendar month and following eleven months; past days are omitted. |
| Currency | `USD` | Request a three-letter currency such as USD, ZAR, EUR or GBP. |
| Details and reviews language | `en` | en, de, es, fr, it, pt or nl. Original review text is kept; translation is supplied only when the site returns it. |
| Room type | `entire` | Any, entire home, private room, shared room or hotel room. |
| Minimum bedrooms / beds / bathrooms | `2` / `2` / `1.5` | Search filters. Known returned numeric values are checked again before a row is delivered. |
| Minimum / maximum nightly price | `0` / `0` | Zero disables that bound. The returned average nightly price is checked against enabled bounds. |
| Review order | `newest` | Newest, relevant, highest or lowest. |

### Output

Each result is one row in the run's dataset (download it as JSON, CSV, Excel, XML or HTML, or read it through the API). An example row (values shortened):

```json
{
  "kind": "listing",
  "checkin": "2026-11-16",
  "checkout": "2026-11-19",
  "currency": "USD",
  "pricePerNight": 102.33,
  "priceTotal": 307.0,
  "rating": 4.71,
  "reviewsCount": 66,
  "guests": 6,
  "bedrooms": 2,
  "beds": 2,
  "baths": 2.0,
  "superhost": false,
  "id": "123456789",
  "url": "https://example.com/rooms/123456789",
  "title": "Example two-bedroom apartment",
  "type": "Entire rental unit",
  "location": "Example City, Example Country",
  "host": {
    "name": "Example Host",
    "superhost": false
  },
  "photos": [
    {
      "room": "Example room",
      "url": "https://example.com/photos/1.jpg"
    }
  ]
}
```

Example drawn from the direct test on 17 October 2026: three listings returned details, dated prices, 150 reviews and three calendars. The example’s identifying names, listing ID, place names and site addresses have been replaced; the measured numerical fields are retained. SUMMARY in the run’s key-value store records the results and charges. This local test does not establish cloud success rates.

### Pricing

- **$0.003 per basic listing** when full details are off, or when a search row is delivered after its details request failed.
- **$0.005 per detailed listing**, including its search discovery when applicable, public details, policies when available and a dated quote when requested and returned. This replaces the basic listing price; the two listing events are not added together.
- **$0.0005 per review**: $0.50 per 1,000 delivered public reviews.
- **$0.002 per calendar**, including all returned daily entries, rather than a charge for every day.
- Failures, invalid input, mismatched locations and empty results are free. A useful detailed listing is still charged if an optional quote or policy is unavailable; its row explains what is missing.
- There is no AI step or separate model bill. The selected event prices cover the Actor’s work.
- Measured on Apify on 17 October 2026: 6 listings from two cities in 5 seconds; 3 detailed listings with 150 reviews and 3 calendars in 26 seconds, read directly (no proxy needed).

What typical jobs cost at the list price:

| Job | Cost |
|---|---|
| 100 basic listings | $0.30 |
| 100 detailed listings | $0.50 |
| One detailed listing, 50 reviews and its calendar | $0.032 |
| Three detailed listings, 50 reviews each and three calendars | $0.096 |
| 1,000 reviews, plus one detailed listing | $0.505 |

On Apify's Scale and Business plans the per-event prices are lower (Store discounts). Set **Maximum cost per run** and the Actor stops cleanly when it is reached: you never pay more than that.

### Tips

- Keep dates, guests and currency constant when comparing prices. The nightly value is the displayed total divided by nights, not necessarily the host’s base rate.
- For a shared place name, include the country and use the site’s local spelling. Strict validation can reject abbreviations or an unrecognized location; use a listing link when you already know the property.
- For a large area, search smaller neighbourhoods. The site exposes at most 270 results for one search and may repeat listings between pages.
- Start with a few listings and add reviews or calendars only when needed. Processing order is listing, calendar, then reviews for that listing.
- Use SUMMARY to distinguish a budget stop, a changed public response, a refused request and a search that returned no matching properties.

### Use it through the API

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("zaiq/airbnb-scraper").call(run_input={"locations": ["Cape Town, South Africa"], "maxListingsPerLocation": 3, "currency": "USD", "reviewsPerListing": 50})
for row in client.dataset(run.default_dataset_id).iterate_items():
    print(row)
```

**JavaScript**

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('zaiq/airbnb-scraper').call({"locations": ["Cape Town, South Africa"], "maxListingsPerLocation": 3, "currency": "USD", "reviewsPerListing": 50});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**HTTP (one call, results back)**

```bash
curl -X POST 'https://api.apify.com/v2/acts/zaiq~airbnb-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"locations": ["Cape Town, South Africa"], "maxListingsPerLocation": 3, "currency": "USD", "reviewsPerListing": 50}'
```

### Integrations and schedules

- **Schedules:** run it every hour, day or week from the Apify Console (Schedules) and keep a history of results.
- **Make, Zapier, n8n, Google Sheets, Slack, Airtable:** connect it through Apify's integrations, or send each finished run to a **webhook**.
- **Datasets:** results stay in the run's dataset; export them or read them by API whenever you need them.

### Use it with AI agents (MCP)

Add Apify's MCP server (`https://mcp.apify.com`) to Claude, ChatGPT, Cursor, VS Code or any MCP client. The agent can find this Actor and run it for you: ask it for "collect public rental listings for this city and date range, including prices and 50 reviews per listing". AI agents can also pay for runs directly through Apify's agentic payments.

### Limits

- Only signed-out public data is collected. Login walls and bot checks are reported; the Actor does not sign in, solve challenges or create anti-bot tokens.
- Cloud requests try the direct connection, a datacenter route, and up to two fresh residential sessions on refusal. These cloud routes require the platform’s proxy configuration and still need cloud validation. HTTP 429 causes backoff and stops further site requests in that run.
- Each run makes at most 150 site requests, including retries and domain redirects, with a short pause between requests. Large combinations of details, reviews and locations can hit this ceiling before every requested item is returned.
- Availability covers the remainder of the current month plus the following eleven months, often fewer than 365 days. A closed day can be booked, host-blocked or restricted. It is not a measured occupancy rate. Daily prices are not supplied by the calendar endpoint.
- Prices are the site’s displayed quotes, including the tax and fee treatment it supplies for that request. Displayed totals can be rounded. They are not a final checkout guarantee, and availability can change before booking.
- Searches without dates may have different suggested dates for different properties. A direct listing link without dates does not return a dated price.
- The site may relax filters or omit fields. Known bedroom, bed, bath and nightly-price values are checked again; a missing field cannot be independently verified. Room-type filtering follows the site’s search response.
- Details and review translations follow the selected language when available. Search headings and numeric booking quotes are read in English for consistent location and price parsing. No AI translation is performed.
- Public query formats can change. If a response no longer matches a parser, the Actor keeps successful earlier rows and reports the missing part instead of inventing values.
- Duplicate listing IDs for the same dates are delivered once per run. Different runs are separate snapshots and are billed independently.

### FAQ

**Is there an account or login requirement?**

No. The Actor reads public pages and their public data responses.

**Do details add another charge on top of a listing?**

No. A delivered property is charged as either a basic listing or a detailed listing. Reviews and calendars are separate optional events.

**What happens if the listing loads but its quote fails?**

The details row is delivered with a note. If it came from a search, the search price can remain as a clearly identified fallback. A direct link may have no price. The useful detailed listing is charged; the missing quote has no separate event.

**Can I get only reviews or a calendar from a link?**

The Actor first reads and delivers the listing to establish that it exists. Set details off to use the basic listing event, then request reviews or a calendar.

**Are blocked dates bookings?**

No. The public calendar does not distinguish a booking from a host block or a stay restriction.

**How is the spending limit enforced?**

Before requesting chargeable data, the Actor checks the remaining budget. Review batch size is reduced to the number that fits, and delivered rows are charged through the platform’s row-and-event operation.

**Can I use different dates for each location?**

One run uses one date range. Use separate runs for different stays.

**What does a missing value mean?**

The public response did not contain a usable value. Null does not mean zero, unavailable or false.

**How many reviews are returned?**

Up to the requested limit, in pages of at most 50. Deleted, unavailable or restricted reviews may not be accessible. Repeated review IDs are omitted.

**How do I report a broken input?**

Open an issue with the run ID, the input that failed and the relevant free note from SUMMARY.

### Related Actors from Zaiq

- [google-hotels-scraper](https://apify.com/zaiq/google-hotels-scraper): hotel listings and dated booking-site prices

### Support

Questions, a site that changed, or a field you need? Open an issue on this Actor's **Issues** tab: we answer there, usually within a day.

***

Also found as: airbnb scraper, rental listing scraper, airbnb reviews, rental availability calendar, short-term rental prices.

# Actor input Schema

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

City or region followed by its country. One location per entry. Mismatched places are rejected; use local spellings or a smaller area if needed.

## `listingUrls` (type: `array`):

Public listing links or numeric listing IDs. Up to 50. Links are normalized to the public listing page.

## `checkin` (type: `string`):

Arrival YYYY-MM-DD. Leave both dates blank for the site’s suggested dates on search rows; direct links then have no dated quote.

## `checkout` (type: `string`):

Departure YYYY-MM-DD, after check in. Omit for check in plus nights.

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

Length of stay when check out is omitted.

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

Adults included in the search and price request.

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

Children included in the search and price request.

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

Infants included in the search and price request.

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

Pets included in the search and price request.

## `maxListingsPerLocation` (type: `integer`):

Maximum per location; the site exposes at most 270. Results may overlap across searches.

## `reviewsPerListing` (type: `integer`):

Maximum public reviews per listing. Zero skips reviews. Fewer may exist or be accessible.

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

Zero means no minimum.

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

Zero means no minimum.

## `minBathrooms` (type: `number`):

Minimum bathrooms, including half bathrooms. Zero means no minimum.

## `priceMin` (type: `number`):

Lower nightly search filter in the selected currency. Zero means no minimum.

## `priceMax` (type: `number`):

Upper nightly search filter in the selected currency. Zero means no maximum.

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

Type of accommodation to search for.

## `details` (type: `boolean`):

Get full listing information and a price request for supplied dates. Charged once as a detailed listing instead of a basic listing.

## `availabilityCalendar` (type: `boolean`):

Get the current month and next eleven months, with daily availability and stay restrictions. Unavailable dates are not proof of bookings.

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

Three-letter currency requested from the site, such as USD, ZAR, EUR or GBP. Prices are displayed quotes, not guaranteed checkout totals.

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

Language requested for listing descriptions, policies and review translations. Search titles stay English so location validation and numeric search fields remain consistent. Original review text is kept.

## `reviewSort` (type: `string`):

Site-provided review order.

## Actor input object example

```json
{
  "locations": [
    "Cape Town, South Africa"
  ],
  "listingUrls": [],
  "nights": 3,
  "adults": 2,
  "children": 0,
  "infants": 0,
  "pets": 0,
  "maxListingsPerLocation": 3,
  "reviewsPerListing": 0,
  "minBedrooms": 0,
  "minBeds": 0,
  "minBathrooms": 0,
  "priceMin": 0,
  "priceMax": 0,
  "roomType": "any",
  "details": true,
  "availabilityCalendar": false,
  "currency": "USD",
  "language": "en",
  "reviewSort": "newest"
}
```

# Actor output Schema

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

Dataset: the results.

## `summary` (type: `string`):

What each input returned, and notes.

# 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": [
        "Cape Town, South Africa"
    ],
    "listingUrls": [],
    "details": true,
    "currency": "USD"
};

// Run the Actor and wait for it to finish
const run = await client.actor("zaiq/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": ["Cape Town, South Africa"],
    "listingUrls": [],
    "details": True,
    "currency": "USD",
}

# Run the Actor and wait for it to finish
run = client.actor("zaiq/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": [
    "Cape Town, South Africa"
  ],
  "listingUrls": [],
  "details": true,
  "currency": "USD"
}' |
apify call zaiq/airbnb-scraper --silent --output-dataset

```

## MCP server setup

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