# Airbnb Scraper + STR Market KPIs (ADR · Occupancy · RevPAR) (`sian.agency/airbnb-property-scraper`) Actor

🏠 Airbnb scraper for STR investors — listings + ADR + occupancy + RevPAR + estimated annual revenue. Market KPIs, HTML report, calendar enrichment. Search by destination, coordinates, place ID, category, or URL. Independent tool — not affiliated with Airbnb, Inc.

- **URL**: https://apify.com/sian.agency/airbnb-property-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Automation, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Property Scraper - STR KPIs, Occupancy & RevPAR 🚀

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian)
[![Airbnb Property Scraper](https://img.shields.io/badge/Store-Airbnb%20Property%20Scraper-FF5A5F)](https://apify.com/sian.agency/airbnb-property-scraper?fpr=sian)

#### 🎉 The Airbnb analyzer built for investors — forward-looking calendar enrichment computes ADR, occupancy, RevPAR & annual revenue per listing
##### Built-in Airbnb profit calculator and income estimator for short-term rental investors, vacation-rental analysts, and Airbnb arbitrage operators

---

### 📋 Overview

**Stop guessing what an Airbnb market is worth.** This Airbnb scraper pulls clean listing data plus the short-term rental KPIs investors actually need — average daily rate (ADR), occupancy, RevPAR, and estimated annual revenue — across any city, map area, or category on Airbnb.

**Why thousands of STR investors and analysts choose us:**
- ✅ **5 search modes**: destination text, map-bounds coordinates, place ID, Airbnb category tag, or paste-a-URL — cover every research workflow
- ⚡ **40 listings per page, auto-paginated**: cursor-based pagination drains entire markets without manual clicking
- 🎯 **Real STR KPIs**: ADR, occupancy rate, RevPAR, estimated annual revenue, days-until-next-available — computed per listing from forward-looking calendar data
- 💰 **Best price on Apify**: pay-per-result, no monthly fee, FREE tier with 25 listings to test
- 💎 **Beautiful HTML market report**: shareable summary with KPI distributions, top performers, and stale-listing flags
- ✨ **35+ data fields per listing** (40+ with `computeOccupancy` enrichment): photos, bedrooms, baths, ratings, reviews, badges, lat/lng, price qualifiers, and more

---

### ✨ Features

- 🧭 **Destination Search**: free-text city or neighborhood ("Lisbon, Portugal", "Brooklyn, NY")
- 🗺 **Map-Bounds Coordinates**: NE + SW lat/lng box for precise geographic scans
- 🆔 **Place ID Search**: pinpoint a market by Google/Airbnb internal place ID
- 🎯 **Category Browsing (PAID)**: scrape entire Airbnb categories like Beach, Cabin, Tiny Home
- 🔗 **URL Mode**: paste any Airbnb search URL directly from your browser
- 📅 **Calendar Enrichment**: per-listing forward availability → real occupancy & RevPAR
- 💹 **STR KPI Engine**: ADR, occupancy, RevPAR, estimated annual revenue, stale-listing detector
- 📊 **HTML Market Report**: visual summary with charts saved to key-value store
- 🌍 **Multi-currency**: 3-letter ISO currency support (USD, EUR, GBP, AUD, etc.)
- 🏘 **Smart Filters**: price range, bedrooms, beds, baths, Superhost, Guest Favorite, Luxe

---

### 🎬 Quick Start

Pick a search mode, drop in a destination (or coordinates, place ID, category, or URL), and run. Results land in your Apify dataset within minutes — listings plus computed STR KPIs and a shareable HTML report.

```bash
curl -X POST "https://api.apify.com/v2/acts/sian.agency~airbnb-property-scraper/runs?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchMode":"destination","destination":"Lisbon, Portugal","computeOccupancy":true}'
````

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Choose Your Search Mode

Pick `destination`, `coordinates`, `placeId`, `category`, or `url`. Each mode reads its own dedicated input fields.

#### Step 2: Configure Stay Context (Optional)

Add `checkIn`/`checkOut` for accurate per-night pricing, set guests/currency, apply filters (price range, bedrooms, Superhost, Guest Favorite, Luxe).

#### Step 3: Enable Occupancy KPIs (PAID, Recommended)

Turn on `computeOccupancy` to fetch each listing's calendar and compute ADR, occupancy, RevPAR, and estimated annual revenue. Perfect for underwriting.

**That's it! In a few minutes, you'll have:**

- Clean Airbnb listings with 35+ fields (40+ with calendar enrichment)
- Computed STR KPIs (ADR, occupancy, RevPAR, annual revenue)
- A beautiful HTML market report ready to share with stakeholders

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| searchMode | string | Yes | `destination`, `coordinates`, `placeId`, `category`, or `url` |
| destination | string | Mode-specific | Free-text city (destination mode) |
| destinations | array | Optional (PAID) | Bulk destinations array |
| ne\_lat / ne\_lng / sw\_lat / sw\_lng | string | Mode-specific | Map-bounds box (coordinates mode) |
| placeId | string | Mode-specific | Google/Airbnb place ID |
| category\_tag | string | Mode-specific (PAID) | Airbnb category tag (e.g. `Tag:4104`) |
| airbnbUrl | string | Mode-specific | Airbnb search URL |
| airbnbUrls | array | Optional (PAID) | Bulk URLs |
| checkIn / checkOut | string | Optional | ISO dates for date-filtered search & per-night pricing |
| adults / children / infants / pets | integer | Optional | Guest counts |
| currency | string | Optional | 3-letter ISO code (default `USD`) |
| typeOfPlace | string | Optional | `Any_type`, `Room`, or `Entire_home` |
| priceRangeMin / priceRangeMax | integer | Optional | Nightly price filter |
| bedrooms / beds / bathrooms | integer | Optional | Minimum room counts |
| superhost / guestFavorite / luxuryHomes | boolean | Optional | Quality filters |
| computeOccupancy | boolean | Optional (PAID) | Enable calendar enrichment & full STR KPIs |
| availabilityWindowDays | integer | Optional | 30 / 90 (default) / 180 / 365 |
| maxResultsPerQuery | integer | Optional | Cap per query (default 40, FREE capped at 25) |

**Example — Destination with full KPIs:**

```json
{
  "searchMode": "destination",
  "destination": "Lisbon, Portugal",
  "checkIn": "2026-07-15",
  "checkOut": "2026-07-22",
  "currency": "EUR",
  "computeOccupancy": true,
  "availabilityWindowDays": 90,
  "maxResultsPerQuery": 100
}
```

**Example — Map-bounds coordinates:**

```json
{
  "searchMode": "coordinates",
  "ne_lat": "44.029",
  "ne_lng": "-79.317",
  "sw_lat": "43.824",
  "sw_lng": "-79.498",
  "typeOfPlace": "Entire_home"
}
```

**Example — URL mode (bulk, PAID):**

```json
{
  "searchMode": "url",
  "airbnbUrls": [
    "https://www.airbnb.com/s/Lisbon--Portugal/homes",
    "https://www.airbnb.com/s/Porto--Portugal/homes"
  ]
}
```

***

### 📤 Output

Results are saved to the Apify dataset. Every listing returns **35+ base fields**; turning on `computeOccupancy` adds the calendar-enrichment fields (marked below).

| Field | Type | Description |
|-------|------|-------------|
| listingId | string | Numeric Airbnb listing ID |
| detailUrl | string | Direct URL to the listing page |
| listingTitle | string | Listing title |
| subtitle | string | Property name / headline |
| city | string | Localized city |
| latitude / longitude | number | Coordinates |
| totalPrice | number | Sample stay total |
| nightlyRateFromTotal | number | Nightly rate from sample |
| adr | number | Average daily rate (computed) |
| occupancyRate *(enrichment)* | number | Occupancy rate decimal (0.65 = 65%) |
| unavailableRate *(enrichment)* | number | Raw share of unavailable nights |
| revpar *(enrichment)* | number | Revenue per available night (ADR × occupancy) |
| estimatedAnnualRevenue *(enrichment)* | number | RevPAR × 365 |
| daysUntilNextAvailable *(enrichment)* | number | Forward-looking earliest open night |
| isStale *(enrichment)* | boolean | True if calendar fully open AND reviews < 3 |
| bedrooms / beds / baths | number | Property dimensions |
| rating / reviewCount | number | Social proof signals |
| badges | array | Superhost, Guest Favorite, Luxe |
| photos | array | All photo URLs |
| availability *(enrichment)* | object | Full per-day calendar |
| kpiAssumptions *(enrichment)* | object | Documented heuristic baselines |

> **Fields marked *(enrichment)*** are only populated when `computeOccupancy: true` is set on the input. Without enrichment they're omitted from the record (saving you per-row cost when you don't need them).

A **shareable HTML market report** is saved to the run's key-value store with KPI distributions, top performers, and assumption disclosures.

**Example listing record (with `computeOccupancy: true` — occupancy/revpar fields shown):**

```json
{
  "listingId": "12345678",
  "detailUrl": "https://www.airbnb.com/rooms/12345678",
  "listingTitle": "Apartment in Lisbon",
  "city": "Lisbon",
  "latitude": 38.7223,
  "longitude": -9.1393,
  "adr": 142.5,
  "occupancyRate": 0.74,
  "revpar": 105.45,
  "estimatedAnnualRevenue": 38489.25,
  "daysUntilNextAvailable": 3,
  "rating": 4.92,
  "reviewCount": 187,
  "bedrooms": 2,
  "beds": 3,
  "baths": 1,
  "isStale": false
}
```

***

### 💼 Use Cases & Examples

#### 1. STR Investment Underwriting

**Real estate investors evaluating short-term rental purchases**

**Input:** Destination + price range + bedroom filter + `computeOccupancy: true`
**Output:** ADR, occupancy, RevPAR, and projected annual revenue for every comparable listing
**Use:** Pro-forma underwriting, rent-vs-buy analysis, market comp pulls for lender packages

#### 2. Rental Market Analysis by Metro or Map Area

**Hospitality consultants and PE analysts mapping new markets**

**Input:** Map-bounds coordinates covering a metro or resort area
**Output:** Total active listings, ADR distribution, RevPAR by submarket
**Use:** Market entry decisions, expansion strategy decks, demand forecasting

#### 3. Competitor RevPAR Benchmarking

**Existing Airbnb hosts and property managers tracking the competition**

**Input:** URL mode with the host's local search URL + `computeOccupancy: true`
**Output:** Side-by-side ADR and occupancy for every neighbor
**Use:** Pricing strategy, dynamic-rate calibration, identifying underpriced or stale comps

#### 4. Vacation Rental Investment & Arbitrage Sourcing

**Rental arbitrage operators scouting cities for new units**

**Input:** Destination + Entire-home filter + price range
**Output:** Top-performing listings with revenue benchmarks and review velocity
**Use:** Lease-up decisions, neighborhood ranking, ROI projections for landlords

#### 5. Destination Revenue Forecasting

**Tourism boards, DMOs, and academic researchers tracking STR supply**

**Input:** Destination or place ID + 365-day availability window
**Output:** Full-year occupancy curves, seasonality patterns, supply density
**Use:** Policy briefs, tax-revenue projections, supply-vs-demand reports

#### 6. Category-Level Trend Research (PAID)

**Travel media, OTA strategists, and content brands**

**Input:** Category mode with tags like `Tag:4104` (Beach) or `Tag:8186` (Cabin)
**Output:** Category-wide pricing and occupancy benchmarks
**Use:** Editorial features, trend reports, category-specific marketing

#### 7. Stale-Listing & Inventory Quality Audits

**Airbnb co-hosts and property management agencies**

**Input:** Destination + `computeOccupancy: true`
**Output:** `isStale` flag plus full forward calendar per listing
**Use:** Identify abandoned listings, recovery outreach, inventory cleanup

***

### 🔗 Integration Examples

A clean real estate data API for your stack — call the actor from anywhere via the Apify REST API or one of the official client libraries.

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/airbnb-property-scraper').call({
  searchMode: 'destination',
  destination: 'Lisbon, Portugal',
  computeOccupancy: true,
  availabilityWindowDays: 90,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/airbnb-property-scraper').call(
    run_input={
        'searchMode': 'coordinates',
        'ne_lat': '44.029',
        'ne_lng': '-79.317',
        'sw_lat': '43.824',
        'sw_lng': '-79.498',
        'computeOccupancy': True,
    }
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~airbnb-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"searchMode":"url","airbnbUrl":"https://www.airbnb.com/s/Lisbon--Portugal/homes"}'
```

#### Automation Workflows (n8n / Zapier / Make)

1. **Trigger**: Schedule a weekly market scan
2. **HTTP Request**: Call the actor with your destination
3. **Process**: Filter listings by ADR or occupancy thresholds
4. **Action**: Push winners to Notion, Sheets, or Slack

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **25 listings per query** — full data fields, same quality
- All 5 search modes available (except Category & bulk arrays)
- No credit card required
- Perfect for evaluating a market before investing

#### PAID Tier (Production Ready)

- **Unlimited listings** per query, up to 500 per run
- Bulk arrays for destinations and URLs
- **Calendar enrichment unlocked** — full ADR, occupancy, RevPAR, estimated annual revenue
- Category-mode browsing
- Pay-per-result: only charged for listings actually returned

**Pricing events:**

- `apify-actor-start` — $0.005 per run
- `ListingExtracted` — $0.005 per listing
- `OccupancyEnriched` — $0.003 per listing (only when calendar enrichment succeeds)

💰 **Best price on the market** — full STR underwriting data for under a cent per listing.

🔗 [View current pricing](https://apify.com/sian.agency/airbnb-property-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: Is there a free Airbnb profit calculator?**
A: Yes — the FREE tier doubles as a free Airbnb profit calculator: run any market, get ADR, occupancy, RevPAR, and estimated annual revenue per listing on the first 25 results. Upgrade to PAID for unlimited listings and full forward-looking calendar enrichment.

**Q: How do I calculate Airbnb investment returns?**
A: Enable `computeOccupancy: true` (PAID) and the actor returns ADR, occupancy rate, RevPAR, and estimated annual revenue per listing — the same inputs every Airbnb investment calculator uses, but populated from real forward-looking calendar data instead of city-level averages. Pull comps for any address radius or category and underwrite directly from the dataset.

**Q: How many listings can I scrape?**
A: FREE tier: 25 per query. PAID tier: up to 500 per query, unlimited queries via bulk arrays.

**Q: How accurate are the occupancy and RevPAR numbers?**
A: Occupancy is a forward-looking heuristic derived from each listing's public calendar minus a 10% host-block baseline. It's a strong directional signal — full assumptions are documented in the `kpiAssumptions` field and HTML report.

**Q: Do I need to provide check-in / check-out dates?**
A: Optional but recommended. Without dates, the search returns results without date filtering and per-night prices are unavailable. With dates, you get filtered results and accurate nightly pricing.

**Q: What's the difference between ADR and `nightlyRateFromTotal`?**
A: `nightlyRateFromTotal` comes from the search sample stay; `adr` is computed across the full availability window when calendar enrichment is enabled. ADR is more accurate for revenue projections.

**Q: Can I filter by Superhost or Guest Favorite?**
A: Yes — toggle `superhost`, `guestFavorite`, or `luxuryHomes` to restrict results.

**Q: What output formats are available?**
A: JSON, CSV, Excel, HTML, RSS — export directly from the Apify dataset. A pre-built HTML market report is also saved to the key-value store.

**Q: How long does processing take?**
A: ~1 second per listing without enrichment, ~2 seconds with calendar enrichment. A 100-listing market scan with full KPIs takes about 3 minutes.

**Q: Is this legal?**
A: Yes — only publicly available Airbnb listing data is extracted. See the legal section below.

***

### 🐛 Troubleshooting

**No results returned for a destination**

- Verify the destination string matches Airbnb's autocomplete (e.g. "Lisbon, Portugal" not "lisbon portugal")
- Try URL mode instead with the exact search URL from airbnb.com

**Coordinates mode returns empty**

- Confirm `sw_lat < ne_lat` and `sw_lng < ne_lng` (southwest corner is the smaller box corner)
- Lat must be -90..90, lng must be -180..180

**Occupancy rate seems low**

- The 10% host-block baseline is documented in `kpiAssumptions`. For raw availability, use `unavailableRate`
- A wider `availabilityWindowDays` (180 or 365) smooths short-term anomalies

**Per-night prices are missing**

- Pass `checkIn` and `checkOut` — without them, Airbnb returns sample-stay totals only

**FREE tier hit the 25-listing cap**

- Upgrade to PAID for full market depth and calendar enrichment

***

### ⚠️ Trademark Disclaimer

This Actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by Airbnb, Inc. or any of its subsidiaries**. The name "Airbnb" is used solely in a descriptive sense to identify the public data source the Actor reads from. All trademarks, service marks, and trade names referenced in this Actor or its documentation are the property of their respective owners.

***

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

***

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community**

- For issues or questions, open an issue in the actor's repository
- Check [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <hello@sian-agency.online>

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `searchMode` (type: `string`):

Pick how you want to search Airbnb. Each mode reads its own dedicated input fields below — fields outside the chosen mode are ignored.

• **destination** — text destination (default; e.g. 'Lisbon, Portugal')
• **coordinates** — map-bounds (NE + SW lat/lng box)
• **placeId** — Google/Airbnb internal place ID
• **category** — browse by Airbnb category tag (PAID)
• **url** — paste an Airbnb search URL

## `maxResultsPerQuery` (type: `integer`):

Hard cap on listings returned per query. Auto-paginates via cursor until cap is reached or search is fully drained. Default 40 = exactly one upstream request. FREE tier is always capped at 25.

## `destination` (type: `string`):

Free-text destination, e.g. 'Lisbon, Portugal' or 'Brooklyn, NY'. Use the Airbnb autocomplete on airbnb.com to find canonical strings.

## `destinations` (type: `array`):

Array of destination strings. PAID tier only.

## `ne_lat` (type: `string`):

Northeast corner latitude of the map-bounds box. -90 to 90.

## `ne_lng` (type: `string`):

Northeast corner longitude. -180 to 180.

## `sw_lat` (type: `string`):

Southwest corner latitude. Must be less than northeast lat.

## `sw_lng` (type: `string`):

Southwest corner longitude. Must be less than northeast lng.

## `placeId` (type: `string`):

Google/Airbnb internal place ID, e.g. 'ChIJpTvG15DL1IkRd8S0KlBVNTI'.

## `category_tag` (type: `string`):

Airbnb category tag, e.g. 'Tag:4104' (Beach), 'Tag:8186' (Cabin). PAID tier only.

## `airbnbUrl` (type: `string`):

Paste an Airbnb search URL from your browser. Auto-paginates via cursor until 'Max results per query' is reached.

## `airbnbUrls` (type: `array`):

Array of Airbnb search URLs. PAID tier only.

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

ISO date YYYY-MM-DD. Today or later. When provided alongside checkOut, search applies date filtering and per-night prices populate in the calendar.

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

ISO date YYYY-MM-DD. Strictly after checkIn.

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

Number of adults (ages 13+). Default 2.

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

Number of children (ages 2-12). Default 0.

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

Number of infants (ages 2 or below). Default 0.

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

Number of pets. Default 0.

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

3-letter ISO currency code, e.g. USD, EUR, GBP. Default USD.

## `typeOfPlace` (type: `string`):

Filter by place type.

## `priceRangeMin` (type: `integer`):

Minimum nightly price (in selected currency).

## `priceRangeMax` (type: `integer`):

Maximum nightly price (in selected currency).

## `bedrooms` (type: `integer`):

Minimum number of bedrooms.

## `beds` (type: `integer`):

Minimum number of beds.

## `bathrooms` (type: `integer`):

Minimum number of bathrooms.

## `superhost` (type: `boolean`):

Restrict results to Superhost listings.

## `guestFavorite` (type: `boolean`):

Restrict results to Airbnb 'Guest favorite' listings.

## `luxuryHomes` (type: `boolean`):

Restrict results to Airbnb Luxe / luxury listings.

## `computeOccupancy` (type: `boolean`):

When ON, fetches each listing's calendar (1 extra API call per listing) and computes occupancy rate, RevPAR, and estimated annual revenue. Adds an OccupancyEnriched charge per listing. Disabled on FREE tier.

## `availabilityWindowDays` (type: `integer`):

Forward-looking calendar window for occupancy/RevPAR computation. 30 = next month, 90 = next quarter (recommended), 180 = half year, 365 = full year. Allowed: 30, 90, 180, 365.

## Actor input object example

```json
{
  "searchMode": "destination",
  "maxResultsPerQuery": 40,
  "destination": "Lisbon, Portugal",
  "ne_lat": "44.029",
  "ne_lng": "-79.317",
  "sw_lat": "43.824",
  "sw_lng": "-79.498",
  "placeId": "ChIJpTvG15DL1IkRd8S0KlBVNTI",
  "category_tag": "Tag:4104",
  "airbnbUrl": "https://www.airbnb.com/s/Lisbon--Portugal/homes",
  "checkIn": "2026-07-15",
  "checkOut": "2026-07-22",
  "adults": 2,
  "children": 0,
  "infants": 0,
  "pets": 0,
  "currency": "USD",
  "typeOfPlace": "Any_type",
  "superhost": false,
  "guestFavorite": false,
  "luxuryHomes": false,
  "computeOccupancy": false,
  "availabilityWindowDays": 90
}
```

# Actor output Schema

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

Structured Airbnb listings with computed STR KPIs.

## `htmlReport` (type: `string`):

HTML summary with run stats, STR market KPIs, distribution, and per-query totals.

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

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/airbnb-property-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 = { "destination": "Lisbon, Portugal" }

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/airbnb-property-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "destination": "Lisbon, Portugal"
}' |
apify call sian.agency/airbnb-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sian.agency/airbnb-property-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Airbnb Scraper + STR Market KPIs (ADR · Occupancy · RevPAR)",
        "description": "🏠 Airbnb scraper for STR investors — listings + ADR + occupancy + RevPAR + estimated annual revenue. Market KPIs, HTML report, calendar enrichment. Search by destination, coordinates, place ID, category, or URL. Independent tool — not affiliated with Airbnb, Inc.",
        "version": "1.0",
        "x-build-id": "3UvpqpMlyg5L7ispX"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sian.agency~airbnb-property-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sian.agency-airbnb-property-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/sian.agency~airbnb-property-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sian.agency-airbnb-property-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/sian.agency~airbnb-property-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sian.agency-airbnb-property-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchMode": {
                        "title": "🧭 Search Mode",
                        "enum": [
                            "destination",
                            "coordinates",
                            "placeId",
                            "category",
                            "url"
                        ],
                        "type": "string",
                        "description": "Pick how you want to search Airbnb. Each mode reads its own dedicated input fields below — fields outside the chosen mode are ignored.\n\n• **destination** — text destination (default; e.g. 'Lisbon, Portugal')\n• **coordinates** — map-bounds (NE + SW lat/lng box)\n• **placeId** — Google/Airbnb internal place ID\n• **category** — browse by Airbnb category tag (PAID)\n• **url** — paste an Airbnb search URL",
                        "default": "destination"
                    },
                    "maxResultsPerQuery": {
                        "title": "📊 Max results per query",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Hard cap on listings returned per query. Auto-paginates via cursor until cap is reached or search is fully drained. Default 40 = exactly one upstream request. FREE tier is always capped at 25.",
                        "default": 40
                    },
                    "destination": {
                        "title": "📍 Destination  (used when Search Mode = destination)",
                        "type": "string",
                        "description": "Free-text destination, e.g. 'Lisbon, Portugal' or 'Brooklyn, NY'. Use the Airbnb autocomplete on airbnb.com to find canonical strings.",
                        "default": "Lisbon, Portugal"
                    },
                    "destinations": {
                        "title": "📋 Bulk Destinations  (PAID, destination mode)",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Array of destination strings. PAID tier only.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "ne_lat": {
                        "title": "🧭 Northeast Latitude  (used when Search Mode = coordinates)",
                        "type": "string",
                        "description": "Northeast corner latitude of the map-bounds box. -90 to 90."
                    },
                    "ne_lng": {
                        "title": "🧭 Northeast Longitude",
                        "type": "string",
                        "description": "Northeast corner longitude. -180 to 180."
                    },
                    "sw_lat": {
                        "title": "🧭 Southwest Latitude",
                        "type": "string",
                        "description": "Southwest corner latitude. Must be less than northeast lat."
                    },
                    "sw_lng": {
                        "title": "🧭 Southwest Longitude",
                        "type": "string",
                        "description": "Southwest corner longitude. Must be less than northeast lng."
                    },
                    "placeId": {
                        "title": "🆔 Place ID  (used when Search Mode = placeId)",
                        "type": "string",
                        "description": "Google/Airbnb internal place ID, e.g. 'ChIJpTvG15DL1IkRd8S0KlBVNTI'."
                    },
                    "category_tag": {
                        "title": "🎯 Category Tag  (PAID, category mode)",
                        "type": "string",
                        "description": "Airbnb category tag, e.g. 'Tag:4104' (Beach), 'Tag:8186' (Cabin). PAID tier only."
                    },
                    "airbnbUrl": {
                        "title": "🔗 Airbnb Search URL  (used when Search Mode = url)",
                        "pattern": "^https?://(www\\.)?airbnb\\.[a-z.]+/.+",
                        "type": "string",
                        "description": "Paste an Airbnb search URL from your browser. Auto-paginates via cursor until 'Max results per query' is reached."
                    },
                    "airbnbUrls": {
                        "title": "📋 Bulk Airbnb URLs  (PAID, url mode)",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Array of Airbnb search URLs. PAID tier only.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "checkIn": {
                        "title": "📅 Check-in date (optional)",
                        "type": "string",
                        "description": "ISO date YYYY-MM-DD. Today or later. When provided alongside checkOut, search applies date filtering and per-night prices populate in the calendar."
                    },
                    "checkOut": {
                        "title": "📅 Check-out date (optional)",
                        "type": "string",
                        "description": "ISO date YYYY-MM-DD. Strictly after checkIn."
                    },
                    "adults": {
                        "title": "🧑 Adults",
                        "minimum": 1,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Number of adults (ages 13+). Default 2.",
                        "default": 2
                    },
                    "children": {
                        "title": "🧒 Children",
                        "minimum": 0,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Number of children (ages 2-12). Default 0.",
                        "default": 0
                    },
                    "infants": {
                        "title": "👶 Infants",
                        "minimum": 0,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Number of infants (ages 2 or below). Default 0.",
                        "default": 0
                    },
                    "pets": {
                        "title": "🐶 Pets",
                        "minimum": 0,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Number of pets. Default 0.",
                        "default": 0
                    },
                    "currency": {
                        "title": "💱 Currency",
                        "pattern": "^[A-Za-z]{3}$",
                        "type": "string",
                        "description": "3-letter ISO currency code, e.g. USD, EUR, GBP. Default USD.",
                        "default": "USD"
                    },
                    "typeOfPlace": {
                        "title": "🏘 Type of place (filter)",
                        "enum": [
                            "Any_type",
                            "Room",
                            "Entire_home"
                        ],
                        "type": "string",
                        "description": "Filter by place type.",
                        "default": "Any_type"
                    },
                    "priceRangeMin": {
                        "title": "💵 Min nightly price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum nightly price (in selected currency)."
                    },
                    "priceRangeMax": {
                        "title": "💵 Max nightly price",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum nightly price (in selected currency)."
                    },
                    "bedrooms": {
                        "title": "🛏 Min bedrooms",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum number of bedrooms."
                    },
                    "beds": {
                        "title": "🛏 Min beds",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum number of beds."
                    },
                    "bathrooms": {
                        "title": "🛁 Min bathrooms",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum number of bathrooms."
                    },
                    "superhost": {
                        "title": "⭐ Superhost only",
                        "type": "boolean",
                        "description": "Restrict results to Superhost listings.",
                        "default": false
                    },
                    "guestFavorite": {
                        "title": "❤️ Guest favorite only",
                        "type": "boolean",
                        "description": "Restrict results to Airbnb 'Guest favorite' listings.",
                        "default": false
                    },
                    "luxuryHomes": {
                        "title": "💎 Luxury homes only",
                        "type": "boolean",
                        "description": "Restrict results to Airbnb Luxe / luxury listings.",
                        "default": false
                    },
                    "computeOccupancy": {
                        "title": "📅 Compute occupancy & RevPAR (recommended for investors)",
                        "type": "boolean",
                        "description": "When ON, fetches each listing's calendar (1 extra API call per listing) and computes occupancy rate, RevPAR, and estimated annual revenue. Adds an OccupancyEnriched charge per listing. Disabled on FREE tier.",
                        "default": false
                    },
                    "availabilityWindowDays": {
                        "title": "📅 Availability window (days)",
                        "minimum": 30,
                        "maximum": 365,
                        "type": "integer",
                        "description": "Forward-looking calendar window for occupancy/RevPAR computation. 30 = next month, 90 = next quarter (recommended), 180 = half year, 365 = full year. Allowed: 30, 90, 180, 365.",
                        "default": 90
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
