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

Scrape Airbnb search results: prices, discounts, ratings, coordinates and photos. No login or API key needed.

- **URL**: https://apify.com/steadyfeeds/airbnb-listings-scraper.md
- **Developed by:** [christopher tan](https://apify.com/steadyfeeds) (community)
- **Categories:** Travel, Real estate, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

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 Listings Scraper

Export Airbnb search results into a spreadsheet, JSON, or your own app. Prices, discounts, ratings, coordinates and photos, with no login or API key.

Press **Start** to see it work. The default input searches Lisbon.

Need the full detail for listings you find? Feed the results into the [Airbnb Listing Details Scraper](https://apify.com/steadyfeeds/airbnb-listing-details) for every amenity, the house rules, per-category ratings and room-by-room photos.

### What you get

One row per listing:

| Field | Example |
|---|---|
| `name` | `Lisbon Downtown Baixa, ideal for short stay` |
| `roomTypeTitle` | `Apartment in Santa Maria Maior` |
| `price` / `pricePerNight` | `1025` / `250` |
| `priceOriginal` + `isDiscounted` | `1253`, `true` — spot listings currently discounted |
| `priceBreakdown` | Line items: nights x rate, discounts, cleaning |
| `rating` / `reviewsCount` | `4.91` / `226` |
| `isGuestFavorite` / `badges` | `true` / `["GUEST_FAVORITE"]` |
| `latitude` / `longitude` | `38.7111` / `-9.1357` — ready to map |
| `details` | `["1 bedroom", "1 king bed", "1 bathroom"]` |
| `photoUrls` | Up to 29 full-size image URLs |
| `url` | `https://www.airbnb.com/rooms/670694153658292838` |

### What people use it for

- **Short-let market research.** Compare nightly rates by area and property size before buying or listing.
- **Revenue management.** Watch what comparable listings charge for your dates and spot who is discounting.
- **Competitive analysis for hosts.** See which nearby listings hold Guest Favourite status and how their pricing moves.
- **Travel and relocation tools.** Feed live inventory with coordinates straight into a map or an AI agent.
- **Academic and policy research.** Build a dated, geocoded snapshot of short-term rental supply in a city.

### Input

Give it a location, or paste an Airbnb search URL to reuse filters you already set in the browser. Both work, and you can mix them.

| Setting | What it does |
|---|---|
| **Locations** | `Lisbon, Portugal`, `Austin, Texas`, and so on. Each is searched separately. |
| **Airbnb search URLs** | Any Airbnb `/s/.../homes` URL. Filters in the URL are respected. |
| **Check-in / Check-out** | Optional. Adding dates makes prices real quotes rather than estimates. |
| **Guests** | Adults, children, infants, pets. Changes both results and price. |
| **Price range** | Nightly minimum and maximum. |
| **Currency** | Three-letter code such as `USD`. |
| **Max listings per search** | Default 100. |
| **Proxy** | Off by default. Turn on if Airbnb starts showing bot checks. |

### Sample output

```json
{
  "search": "Lisbon, Portugal",
  "listingId": "670694153658292838",
  "url": "https://www.airbnb.com/rooms/670694153658292838",
  "name": "Lisbon Downtown Baixa, ideal for short stay",
  "roomTypeTitle": "Apartment in Santa Maria Maior",
  "rating": 4.91,
  "reviewsCount": 226,
  "isGuestFavorite": true,
  "latitude": 38.7111,
  "longitude": -9.1357,
  "details": ["1 bedroom", "1 king bed", "1 bathroom"],
  "price": 1025.0,
  "priceDisplayed": "$1,025 SGD",
  "priceOriginal": 1253.0,
  "isDiscounted": true,
  "pricePerNight": 250.0,
  "priceQualifier": "for 5 nights",
  "photoCount": 29
}
```

### An unrecognised location is reported, not guessed

Airbnb answers a search it cannot resolve with HTTP 200 and a scatter of unrelated listings from all over. Rather than hand those to you as if they matched, this Actor detects it and tells you the location was not recognised. Misspellings that Airbnb can still resolve, like `Lisbonnn`, work normally.

### What it cannot do, and why

Worth reading before you plan a large job:

- **Airbnb caps any single search at about 270 results** (15 pages of 18). This is Airbnb's own limit, not a limit of this Actor, and no scraper can page past it. To cover a whole city, split the job: run several price bands, or several neighbourhoods, and combine the output. Setting a higher limit will simply return 270.
- **Airbnb serves different results per country.** Requests are redirected to a local Airbnb domain, and prices come back in that region's currency. The Actor detects and follows this automatically, and reports which domain it used. Set `currency`, or use a proxy in the country you care about, if you need specific pricing.
- **Duplicates across pages are removed.** Airbnb repeats some listings between pages; every row you get is a distinct listing.
- **Prices are Airbnb's displayed totals**, matching what a guest sees for those dates and guest count. Without dates, they are Airbnb's estimates.
- **No host or guest personal data, and no reviews text.** This collects listing information only.

### More tools from steadyfeeds

- [Telegram Channel Scraper](https://apify.com/steadyfeeds/telegram-channel-scraper) — Export posts from public Telegram channels.
- [Airbnb Listing Details Scraper](https://apify.com/steadyfeeds/airbnb-listing-details) — Full detail for a listing: amenities, rules, host and photos.
- [Job Board Scraper](https://apify.com/steadyfeeds/job-board-scraper) — Every open role from company career pages across eight systems.
- [Events Scraper](https://apify.com/steadyfeeds/events-scraper) — public events from Eventbrite, Meetup and Luma in one run.

### Notes

Reads the same public search pages you can open in a browser. No headless browser is used, which is why runs are fast and cheap.

Something broken or a field you need? Open an issue on this Actor and I will take a look.

# Actor input Schema

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

Places to search, for example "Lisbon, Portugal" or "Austin, Texas". Each one is searched separately.

## `searchUrls` (type: `array`):

Paste Airbnb search URLs to reuse filters you set in the browser. Any filter Airbnb puts in the URL is kept. Use this instead of, or alongside, the locations above.

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

Date as YYYY-MM-DD. Leave both dates empty to search without dates.

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

Date as YYYY-MM-DD.

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

Number of adults. Affects which listings Airbnb returns and the quoted price.

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

Number of children aged 2 to 12.

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

Number of infants under 2.

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

Number of pets. Filters to listings that allow them.

## `minPrice` (type: `integer`):

Lowest nightly price to include, in the selected currency.

## `maxPrice` (type: `integer`):

Highest nightly price to include. Splitting one search into several price bands is the way to get past Airbnb's 270-result cap.

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

Three-letter code such as USD, EUR or GBP. Defaults to whatever Airbnb serves for the run's location.

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

Airbnb caps any single search at about 270 results, so values above that return 270. Narrow the search to go deeper.

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

Off by default. Turn a proxy on if Airbnb starts returning bot checks, or to search as if from another country.

## Actor input object example

```json
{
  "locations": [
    "Lisbon, Portugal"
  ],
  "maxListings": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All scraped listings as JSON.

## `spreadsheet` (type: `string`):

The same results as an .xlsx spreadsheet.

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

The same results as a CSV file.

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

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

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

```

## MCP server setup

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