# Airbnb Listings Scraper & Competitor Analysis (`zapticx/airbnb-market-intelligence`) Actor

Scrape dated Airbnb listings, compare market prices, analyze competitors, and benchmark an optional target property against comparable listings.

- **URL**: https://apify.com/zapticx/airbnb-market-intelligence.md
- **Developed by:** [Zapticx](https://apify.com/zapticx) (community)
- **Categories:** Real estate, Travel, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.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 & Competitor Analysis

Scrape Airbnb listings and turn them into practical competitor insights. Get normalized nightly
and total pricing, comparable-market statistics, price positioning, confidence metrics, and
optional target-listing benchmarking in one run.

This Actor combines Airbnb listings extraction with competitor and comparable analysis. It keeps
observed source data separate from Actor-derived market intelligence, so you receive usable
benchmarks without opaque claims about bookings, occupancy, or revenue.

### What this Actor does

**Airbnb search → comparable listings → normalized prices → market benchmark → optional target
comparison**

Provide a location or Airbnb search-results URL, exact stay dates, guest details, and optional
comparable filters. The Actor collects up to 240 unique listings, preserves nightly-versus-total
price semantics, scores eligible listings relative to relevant comparables, and writes a market
summary after the listing records. Add a public Airbnb room URL to receive a target benchmark too.

### Why use it?

Many Airbnb scrapers stop at rows of listing data. This Actor also answers practical questions:

- What is the median nightly price for this exact stay?
- Is a listing priced below, near, or above its comparable sample?
- How large and specific was that sample?
- Does the available data support low, medium, or high confidence?
- How does one target listing compare with the market median and quartiles?

The methodology is deterministic and documented. Missing evidence stays null and includes reason
codes instead of being guessed.

### Target listing benchmarking

Add `targetListingUrl` to compare one listing with its best available collected segment. For
example, a result might show: “My property is $114/night versus a $152 comparable median,
approximately 25% below the market sample.” The output also reports quartiles, percentile,
price position, review strength, value score when confidence permits, and sample quality.

If the target already appears in search results, the Actor reuses it. Otherwise it requests the
public listing page once and reports whether reuse occurred.

### Key features

- Dated searches by location or Airbnb search-results URL
- Normalized listing, property-type, rating, review, and pricing fields
- Separate `nightlyPrice` and `totalPrice` with source provenance
- Market median, P25, P75, distributions, and coverage
- Tie-aware price percentile and price delta from the comparable median
- Plain-language price position: budget, below market, market, above market, or premium
- Transparent review strength and value score
- Comparable tiers based on property category and bedrooms
- Per-listing and market confidence with reason codes
- Optional benchmark for one public target listing
- Explicit limitations and transparent null handling
- Apify datasets ready for JSON, CSV, Excel, APIs, and automation workflows

### Who is it for?

Airbnb hosts, property managers, short-term rental analysts, investors doing comparable research,
hospitality consultants, researchers, and agencies building market or client reports.

Common uses include dated rate benchmarking, competitor-set research, target-listing reviews,
market snapshots, portfolio pricing checks, research datasets, and automated reporting pipelines.

### Input

#### Market and stay

| Field | Required | Description |
| --- | --- | --- |
| `location` | One market input | City, neighborhood, or region. Use this or `searchUrl`, not both. |
| `searchUrl` | One market input | HTTPS Airbnb search-results URL used instead of `location`. |
| `checkIn` | Yes | Future arrival date (`YYYY-MM-DD`) or relative date such as `30 days`. |
| `checkOut` | Yes | Departure date after check-in, absolute or relative. Dates are required because Airbnb prices are stay-specific. |

#### Guests and comparable filters

| Field | Required | Description |
| --- | --- | --- |
| `adults` | No | Adult guests; default 2. |
| `children` | No | Child guests; default 0. |
| `infants` | No | Infant guests; default 0. |
| `pets` | No | Pets; default 0. |
| `bedrooms` | No | Exact bedroom filter. Missing or different bedroom counts are excluded when set. |
| `roomTypes` | No | Any of `entire_place`, `private_room`, `shared_room`, or `hotel_room`. |
| `priceMin` | No | Minimum normalized nightly price in the selected currency. |
| `priceMax` | No | Maximum normalized nightly price in the selected currency. |
| `currency` | No | Requested ISO currency; default `USD`. |
| `maxResults` | No | Unique listing cap from 1–240; default 100. |

#### Benchmark and proxy

| Field | Required | Description |
| --- | --- | --- |
| `targetListingUrl` | No | Public Airbnb room URL to benchmark against the collected market. |
| `proxyConfiguration` | No | Apify Proxy or custom proxy fallback. Direct access is attempted first. |

#### Example inputs

##### Basic Miami market analysis

```json
{
  "location": "Miami Beach, United States",
  "checkIn": "2027-03-10",
  "checkOut": "2027-03-14",
  "adults": 2,
  "currency": "USD",
  "maxResults": 100
}
```

##### Dubai one-bedroom market

```json
{
  "location": "Dubai, United Arab Emirates",
  "checkIn": "2027-02-08",
  "checkOut": "2027-02-12",
  "adults": 2,
  "bedrooms": 1,
  "roomTypes": ["entire_place"],
  "currency": "AED",
  "maxResults": 100
}
```

##### Target listing benchmark

```json
{
  "location": "Miami Beach, United States",
  "checkIn": "2027-03-10",
  "checkOut": "2027-03-14",
  "adults": 2,
  "bedrooms": 1,
  "currency": "USD",
  "maxResults": 100,
  "targetListingUrl": "https://www.airbnb.com/rooms/12345678"
}
```

### Output

The default dataset contains three self-identifying record types:

1. `listing` — one normalized listing plus pricing provenance and relative intelligence.
2. `target_benchmark` — written only when a target URL is supplied and acquired successfully.
3. `market_summary` — written last, with pricing, reviews, distributions, coverage, confidence,
   exclusions, and limitations.

Abbreviated, sanitized examples are included with the repository in `examples/outputs`.

```json
{
  "recordType": "listing",
  "listingId": "12345678",
  "title": "Condo in South Beach",
  "normalizedPropertyType": "condo",
  "bedrooms": 1,
  "rating": 4.89,
  "reviewCount": 227,
  "pricing": {
    "nightlyPrice": 113.75,
    "totalPrice": 455.0,
    "currency": "USD",
    "nightlyPriceSource": "derived_from_total"
  },
  "intelligence": {
    "pricePercentile": 0.0,
    "priceDeltaFromMedianPercent": -32.89,
    "pricePosition": "budget",
    "reviewStrength": 86.55,
    "valueScore": 91.93,
    "comparableSampleSize": 19,
    "comparableTier": "category_and_bedrooms",
    "confidence": "medium"
  }
}
```

### Understanding the intelligence

- **Price percentile** shows the listing's midpoint rank from 0 to 100 within its selected
  comparable sample. Lower means less expensive.
- **Price delta from median** shows the money and percentage difference from that sample's median.
- **Price position** maps percentile bands to a readable label from `budget` to `premium`.
- **Review strength** combines observed rating quality with review volume relative to the market.
- **Value score** combines review strength and relative affordability. It is a transparent ranking
  signal—not a revenue, occupancy, or return forecast.
- **Comparable tier** says exactly how the sample was selected.
- **Confidence** summarizes sample size, segmentation, and coverage. Reason codes explain every
  label and unavailable metric.

#### Methodology in brief

Price percentile uses a tie-aware midpoint rank:
`100 × (prices below + 0.5 × equal prices) / sample size`. Price delta is the subject nightly
price minus the comparable median; the percent form divides that delta by a positive median.
Price-position bands are 0–20 budget, above 20–40 below market, above 40–60 market, above 60–80
above market, and above 80 premium.

Review strength is 70% rating quality above 4.0 and 30% log-scaled review volume relative to the
market review-count P95, clamped to 0–100. Value score is 60% review strength plus 40% relative
affordability (`100 - pricePercentile`), also clamped to 0–100. It is suppressed at low or
insufficient confidence. The complete production specification—including eligibility, coverage,
rounding, and all reason codes—is maintained in `docs/methodology.md` in the repository.

### How comparable listings are selected

The Actor tries the most specific viable segment first:

**category + exact bedrooms → category → exact bedrooms → broader dated market**

Each tier needs at least eight eligible records. The target is excluded from its own sample.
Price-relative metrics are suppressed below eight comparables. Value score is more conservative:
it is suppressed at low or insufficient confidence.

### Market summary

The final `market_summary` includes minimum, maximum, average, median, P25, and P75 prices;
rating and review summaries; price, bedroom, and property-type distributions; coverage rates;
duplicates removed; truncation; comparison quality; exclusion reasons; and limitations.

Median and quartiles describe the collected eligible sample—not the entire Airbnb market.

### Data quality and limitations

- Results are a collected Airbnb search sample, not complete market coverage.
- Search-card fields such as bedrooms, bathrooms, ratings, or reviews can be absent.
- Prices are specific to the requested dates, guests, filters, and currency.
- `nightlyPrice` and `totalPrice` are distinct; provenance fields explain observed or derived use.
- Currency is never inferred from a symbol such as `$` alone.
- Confidence and comparable sample size should accompany every interpretation.
- Null metrics mean evidence was missing or quality rules suppressed the calculation; inspect
  `unavailableReasons` and `limitations`.
- The Actor does not claim known bookings, occupancy, revenue, returns, or official Airbnb metrics.
- Airbnb can change public response structures; resilient parsing, retries, and quality reporting
  reduce but cannot eliminate that dependency.

### Integrations

Use Apify dataset exports and APIs with Make, n8n, Zapier, Google Sheets, Airtable, webhooks, or
custom Python and JavaScript workflows. These integrations consume normal Apify datasets; no
separate proprietary dashboard is required.

### Performance

During production testing, a typical 100-listing benchmark completed in approximately 16–20
seconds, used roughly 60–65 MB peak memory, and required no residential proxy traffic. Actual
duration and network usage vary by market, response size, retries, target acquisition, and Airbnb
availability. Direct HTTP is attempted first; a configured proxy is a retry fallback.

### Pricing

**Pricing:** $2 per 1,000 successfully returned Airbnb listings, plus a minimal Actor-start
charge. Market summaries and target benchmarks are included at no additional event charge.

- **100 listings:** approximately **$0.20** total ($0.00005 Actor start + 100 × $0.002)
- **240 listings:** approximately **$0.48** total ($0.00005 Actor start + 240 × $0.002)

### FAQ

#### Are check-in and check-out dates required?

Yes. Airbnb pricing changes by stay, and one exact date range is necessary for a meaningful
nightly and total-price comparison.

#### Is nightly price the same as total price?

No. The Actor preserves the displayed meaning. It derives a nightly amount from an explicit total
only when the night count is known, and records that provenance.

#### Does a percentile of 20 mean 20% cheaper than the median?

No. Percentile is a rank. Use `priceDeltaFromMedianPercent` for the percentage price difference.

#### Why is value score null?

It requires both price percentile and review strength, and it is deliberately suppressed when
comparison confidence is low or insufficient.

#### Can I benchmark a listing outside the search results?

Yes. Supply its public Airbnb room URL. The Actor will attempt one additional target-page request
when the listing was not collected in search.

#### Does this estimate occupancy or revenue?

No. It reports observed public listing data and deterministic comparative metrics only.

#### Can I search without dates?

No. Required dates are a V1 quality rule that prevents mixing ambiguous price contexts.

#### How many listings should I request?

Eight is the minimum for price-relative metrics. Larger samples generally improve coverage and
confidence; 100 is the default and 240 is the V1 cap.

# Actor input Schema

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

City, neighborhood, or region. Use either Location or Airbnb search URL, not both.

## `searchUrl` (type: `string`):

Optional Airbnb search-results URL to use instead of Location. Room/listing URLs are not accepted here.

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

Required arrival date in the future. Use YYYY-MM-DD or a relative value such as 30 days.

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

Required departure date. It must be later than check-in. Use YYYY-MM-DD or a relative value such as 34 days.

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

Number of adult guests.

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

Number of child guests.

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

Number of infant guests.

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

Number of pets.

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

Optional exact bedroom count. Listings with missing or different bedroom counts are excluded when this filter is set.

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

Optional Airbnb room-type filters.

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

Optional minimum normalized nightly price in the selected currency.

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

Optional maximum normalized nightly price in the selected currency.

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

Three-letter currency requested from Airbnb. Only prices in this currency enter the benchmark.

## `maxResults` (type: `integer`):

Maximum unique normalized listings. More results improve benchmark quality but may require more requests.

## `targetListingUrl` (type: `string`):

Leave blank for market analysis only. When provided, use a public Airbnb room URL such as https://www.airbnb.com/rooms/12345678.

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

Apify Proxy or custom proxy configuration. Credentials are never written to logs or output.

## Actor input object example

```json
{
  "location": "Miami Beach, United States",
  "searchUrl": "https://www.airbnb.com/s/Miami-Beach--Florida--United-States/homes",
  "checkIn": "2027-03-10",
  "checkOut": "2027-03-14",
  "adults": 2,
  "children": 0,
  "infants": 0,
  "pets": 0,
  "bedrooms": 1,
  "priceMin": 75,
  "priceMax": 350,
  "currency": "USD",
  "maxResults": 10,
  "targetListingUrl": "https://www.airbnb.com/rooms/12345678",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

The complete default dataset containing listing, optional target\_benchmark, and market\_summary records. Use the dataset view selector for Listing intelligence, Market summary, Target benchmark, or All fields.

# 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": "Miami Beach, United States",
    "checkIn": "30 days",
    "checkOut": "34 days",
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("zapticx/airbnb-market-intelligence").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": "Miami Beach, United States",
    "checkIn": "30 days",
    "checkOut": "34 days",
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("zapticx/airbnb-market-intelligence").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": "Miami Beach, United States",
  "checkIn": "30 days",
  "checkOut": "34 days",
  "maxResults": 10
}' |
apify call zapticx/airbnb-market-intelligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zapticx/airbnb-market-intelligence"
        }
    }
}

```

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/MdE7KoyuH5b3EmhrX/builds/ODLDtcZADj6Dc170C/openapi.json
