# Airbnb Scraper - Listings, Prices, Ratings & Coords (`alex_expert/airbnb-search-scraper`) Actor

Scrape Airbnb search results without login: prices in any currency, ratings and review counts, bedrooms and beds, GPS coordinates, photos and badges. Paste a search URL or type a location. Date, guest and price filters, pagination and a hard max-items cap.

- **URL**: https://apify.com/alex\_expert/airbnb-search-scraper.md
- **Developed by:** [Alexander Shulga](https://apify.com/alex_expert) (community)
- **Categories:** Travel, Real estate, E-commerce
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Airbnb Scraper — Listings, Prices, Ratings & Coordinates

Scrape Airbnb search results anywhere in the world, without a login or an API key.
Prices in the currency you ask for, results in the language you ask for, and a hard
cap so a run can never cost more than you expect.

### What you get per listing

| | |
|---|---|
| **Identity** | listing id, direct URL, name, property type |
| **Price** | displayed price, **price per night**, number of nights, discount, total |
| **Quality** | rating, review count, "new listing" flag, badges such as Guest favourite |
| **Space** | bedrooms, beds, bathrooms |
| **Place** | latitude and longitude |
| **Media** | main photo URL |
| **Host & quality** | superhost flag, per-category ratings: cleanliness, location, value, check-in, accuracy, communication |
| **Detail** | room type, guest capacity, full amenity list |

The **per-night price and the discount** are the fields most scrapers miss. Airbnb leaves
its `secondaryLine` empty and hides the real breakdown in an explanation block —
"5 nights x $170.96", "Early booking discount −$189.61". This Actor parses that block, so
you get comparable nightly rates instead of a lump sum that depends on trip length.

Turning **Fetch full listing details** off makes runs about twice as fast and skips the
host, amenity and per-category rating fields. It is on by default because most people
want the full picture.

### Quick start

1. Type a **Location** the way you would on Airbnb: `Lisbon, Portugal`, `Tokyo, Japan`,
   `Warsaw, Poland`, `Bali, Indonesia`, `New York, NY`.
2. Optionally set dates, guests, a price range and a currency.
3. Press **Start**.

Defaults work with no configuration. You can also paste search URLs straight from your
browser — every filter you set on the Airbnb site is preserved.

### Worldwide by design

- **Any location** Airbnb knows, on any continent.
- **Any currency**: USD, EUR, GBP, PLN, JPY, BRL, INR, AUD, TRY, MXN and the rest.
  Without this you silently get whatever currency the server's location implies.
- **26 languages** for property types and titles: English, Deutsch, Français, Español,
  Italiano, Português, Nederlands, Polski, Русский, Українська, Türkçe, 日本語, 한국어,
  中文, العربية and more.

### Who uses this

- **Short-term rental investors** sizing a market before buying.
- **Hosts** checking what comparable places nearby actually charge.
- **Property managers** repricing against live competition.
- **Researchers and journalists** measuring supply, price levels and concentration.
- **PropTech and AI builders** feeding live rental data into models and dashboards.

### Output example

```
{
  "id": "1373174229965723254",
  "url": "https://www.airbnb.com/rooms/1373174229965723254",
  "name": "Historical Center - Tagus View",
  "propertyType": "Apartment in Lisbon",
  "bedrooms": 3, "beds": 4, "bathrooms": 2,
  "price": 827, "pricePerNight": 203.33, "nights": 5,
  "discount": 189.61, "totalPrice": 827.03,
  "priceCurrency": "EUR", "priceSymbol": "€",
  "rating": 4.89, "reviewsCount": 98,
  "badges": ["Guest favorite"],
  "latitude": 38.7102, "longitude": -9.1312
}
```

### Control what you pay for

You are charged per listing, so the cost is always predictable.

| Run | Listings | Cost on the Free tier |
|---|---|---|
| One page | ~18 | ~$0.07 |
| Three pages (default) | ~54 | ~$0.22 |
| All 15 pages | ~270 | ~$1.08 |
| Anything with `maxItems: 50` | 50 | ~$0.20 |

Higher Apify plans get automatic volume discounts. The Actor also honours the maximum
charge you set on a run and stops cleanly instead of burning compute you are not paying for.
Duplicate listings across pages are skipped and never billed twice.

### Input reference

| Field | Description | Default |
|---|---|---|
| `location` | Any place on Airbnb | `Lisbon, Portugal` |
| `startUrls` | Airbnb search URLs pasted from the browser | empty |
| `checkIn` / `checkOut` | `YYYY-MM-DD`. Set both, or neither | empty |
| `adults` / `children` / `infants` / `pets` | Guest mix | 2 / 0 / 0 / 0 |
| `priceMin` / `priceMax` | Nightly price bounds in your currency | 0 / 0 |
| `minBedrooms` | Minimum bedrooms | 0 |
| `currency` | Three-letter code | `USD` |
| `language` | Two-letter code, 26 supported | `en` |
| `maxPages` | Pages per search, up to 15 (~18 listings each) | 3 |
| `maxItems` | Hard cap on listings. 0 = no limit | 0 |
| `enrichListings` | Open each listing page for host, amenities and per-category ratings | `true` |
| `proxyConfiguration` | Residential recommended for larger runs | Apify RESIDENTIAL |

### Troubleshooting

- **No listings at all?** Check the spelling of the location, or relax the filters.
  A location Airbnb does not recognise fails immediately with a clear message rather
  than running for minutes and returning nothing.
- **Bedrooms and beds are empty for some rows?** Search cards omit room counts for hotels
  and serviced apartments. Leave **Fetch full listing details** on and they are read from
  the listing page instead, which fills them for every row.
- **Prices look odd?** Set `currency` explicitly. Without it Airbnb picks a currency from
  the server location, which for a cloud run is rarely the one you want.
- **Larger runs slowing down or failing?** Enable Apify Proxy with the `RESIDENTIAL` group.

### Measured against the most-used alternative

Same query, same day, 20 listings in Lisbon:

| | This Actor | Most-used alternative |
|---|---|---|
| Fields per listing | **40** | 37 |
| Room counts filled | **20/20** | partial |
| Per-night price and discount | **yes** | in a nested blob |
| Unknown location | **refuses, charges nothing** | returned 10 listings spread over 12,031 km and billed them |

That last row is the one that matters. Airbnb answers an unrecognised place with random
listings from all over the world rather than an error. This Actor measures how far apart
the results are and stops before writing a single row, so a typo costs you nothing.

### What this Actor does not do

- **Booking.com and other sites.** Booking answers automated requests with a challenge
  page (HTTP 202, no data), so supporting it honestly would need a full browser and
  constant maintenance. Promising it here would mean charging you for a feature that
  breaks weekly.
- **Occupancy history.** Airbnb's calendar endpoint sits behind a rotating signed query
  hash. Anything advertising stable historical occupancy from search pages is guessing.

### Integrations

Results can be pushed to Google Sheets, Slack, Zapier and Make, or pulled via the Apify API and MCP.

# Actor input Schema

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

Any place on Airbnb, anywhere in the world. Type it the way you would in the Airbnb search box: "Lisbon, Portugal", "Tokyo, Japan", "Warsaw, Poland", "Bali, Indonesia", "New York, NY".

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

Paste search addresses copied straight from your browser. All filters you set on the Airbnb site are kept. Works alongside the Location field.

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

YYYY-MM-DD. Leave both dates empty to get generic nightly prices instead of a real quote.

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

YYYY-MM-DD. Must be later than check-in.

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

Number of adult guests.

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

Guests aged 2-12.

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

Guests under 2.

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

Number of pets. Filters out listings that do not allow them.

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

In the currency you select below. 0 means no lower bound.

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

In the currency you select below. 0 means no upper bound.

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

0 means any.

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

Three-letter code for the prices you get back: USD, EUR, GBP, PLN, JPY, BRL, INR, AUD, CAD, CHF, SEK, TRY, MXN, ZAR and so on. Without this you get whatever currency Airbnb guesses from the server location.

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

Two-letter code. Property types and titles come back in this language: en, de, fr, es, it, pt, nl, pl, ru, uk, tr, ja, ko, zh, ar, sv, da, no, fi, cs, el, he, hu, id, th, vi.

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

Airbnb returns about 18 listings per page and offers up to 15 pages. 3 pages is roughly 54 listings.

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

Hard cap on listings, so you always know the maximum a run can cost. 0 means no limit.

## `enrichListings` (type: `boolean`):

Open each listing page to add the host status, per-category ratings (cleanliness, location, value, check-in, accuracy, communication), amenities, room type and guest capacity. Adds one request per listing. Turn off for a faster, lighter run.

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

Residential proxies are recommended. Airbnb throttles datacenter IPs once a run grows past a few pages.

## Actor input object example

```json
{
  "location": "Lisbon, Portugal",
  "startUrls": [],
  "checkIn": "",
  "checkOut": "",
  "adults": 2,
  "children": 0,
  "infants": 0,
  "pets": 0,
  "priceMin": 0,
  "priceMax": 0,
  "minBedrooms": 0,
  "currency": "USD",
  "language": "en",
  "maxPages": 3,
  "maxItems": 0,
  "enrichListings": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

All collected Airbnb listings with prices, ratings and coordinates.

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

Same data as a spreadsheet-ready CSV file.

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

Which searches succeeded, which failed, and why.

# 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": "Lisbon, Portugal",
    "currency": "USD"
};

// Run the Actor and wait for it to finish
const run = await client.actor("alex_expert/airbnb-search-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": "Lisbon, Portugal",
    "currency": "USD",
}

# Run the Actor and wait for it to finish
run = client.actor("alex_expert/airbnb-search-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": "Lisbon, Portugal",
  "currency": "USD"
}' |
apify call alex_expert/airbnb-search-scraper --silent --output-dataset

```

## MCP server setup

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