# Airbnb Scraper (Working) — $1.50 per 1,000 Listings (`scrapersdelight/airbnb-scraper`) Actor

$1.50 per 1,000 listings — no hidden fees, no start fee. Scrape Airbnb by location with date, guest, price & room-type filters: name, price, rating, reviews, lat/lng, beds, baths, images, URL. Optional detail enrichment (amenities, host, description) + new-listing monitor. No login or API key.

- **URL**: https://apify.com/scrapersdelight/airbnb-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Travel, E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 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 Scraper (Working) — $1.50 per 1,000 Listings

**Scrape Airbnb listings by location — name, price (total + per-night), rating, review count, exact lat/lng coordinates, bedrooms/beds/baths, Superhost & Guest-favorite badges, photos, and the listing URL — with date, guest, price-band, and room-type filters. Then schedule it as a new-listing monitor with Slack/email/webhook alerts. Flat $1.50 per 1,000 listings. No login, no API key, no start fee.**

### Why this one?

| | **This actor** | Leading Airbnb scraper | Its "fast" SKU | Other Airbnb scraper |
|---|---|---|---|---|
| **Price per 1,000 listings** | **$1.50 flat** | $6–10 | $2.50 | $5 + actor-start fee |
| **Start / hidden fees** | **None** | — | — | per-start fee |
| **Failure handling** | per-page retries w/ fresh proxy session; a failed page never kills the run | 17.7% of runs failed this month (store stats) | — | — |
| **Lat/lng coordinates** | ✅ every listing, from search (no extra request) | ✅ | ✅ | ✅ |
| **Price breakdown** (nightly rate, taxes, totals) | ✅ | partial | partial | partial |
| **Date / guest / price / room-type / bedroom filters** | ✅ all server-side | ✅ | ✅ | partial |
| **Detail enrichment** (full amenities, host profile, description, full gallery) | ✅ optional, $ only when used | separate runs | ❌ | ❌ |
| **New-listing monitor + Slack/email/webhook alerts** | ✅ built in | ❌ | ❌ | ❌ |
| **Raw source object per listing** | ✅ (`raw` field — nothing trimmed) | ❌ | ❌ | ❌ |

*Competitor prices/stats as listed on their Apify store pages, June 2026 — check their pages for current numbers.*

---

### What does Airbnb Scraper do?

It extracts **stay listings** from any Airbnb search — a city, neighborhood, region, or landmark — and returns clean structured rows you can export to **JSON, CSV, Excel, or pull via API**. It reads the same data the Airbnb site itself renders (the embedded search payload in the page), so no headless browser, no login, and no API key are involved.

- 📍 **Search any market** — `location` exactly as you'd type it on airbnb.com ("Austin, TX", "Paris, France", "Lake Tahoe").
- 🗓️ **Date-aware pricing** — set `checkIn`/`checkOut` and prices become exact stay totals for those dates, with the per-night rate and tax breakdown parsed out.
- 👨‍👩‍👧 **Guest & price filters** — adults/children/infants/pets, nightly price band, room type, min bedrooms/beds/baths. All filtered **server-side** so you only pay for listings you want.
- 🌍 **Stable currency** — defaults to USD wherever the request exits; switch to any ISO currency.
- ⭐ **Quality signals** — rating, review count, "New" flag, Superhost / Guest-favorite badges.
- 🗺️ **Exact coordinates** — latitude/longitude on every listing straight from search (great for maps, market analysis, comps).
- 🔎 **Optional deep detail** — flip `fetchDetails` for the full description, the complete grouped amenity list (including what's *not* available), the host profile (name, Superhost, rating, years hosting), exact room type, guest capacity, and the full photo gallery.
- 🔔 **New-listing monitor** — schedule it and get **Slack / email / webhook alerts** the moment a new listing appears in your search.
- 🧾 **Nothing trimmed** — every row carries the full `raw` source object, so any field Airbnb adds is yours too.

---

### What data does it extract?

For every listing:

- 🆔 `id`, 🔗 `url`, 🏷️ `name` (host's title), `type` ("Home in Central Austin"), `room_type`* ("Entire home/apt")
- 💵 `price`, `price_qualifier` (total/night), `price_amount`, `price_original` (pre-discount), `price_per_night`, `nights`, `price_breakdown[]` (nightly rate, taxes, total), `currency`
- ⭐ `rating`, `reviews_count`, `is_new_listing`, `badges[]` (Superhost, Guest favorite…)
- 🛏️ `bedrooms`, `beds`, `baths`, `room_summary[]`, `person_capacity`*
- 📍 `lat`, `lng`, `city`*
- 🖼️ `image_url`, `images[]` (~6 from search; full gallery with details)
- 📝 `description`*, 🛁 `amenities[]`* (grouped, with availability), `amenities_count`*
- 🧑‍💼 `host`* — name, user id, Superhost/verified, rating, review count, years hosting, highlights, photo
- 🗓️ `check_in` / `check_out`, `search_location`, `og_title`*, `seo_description`*
- 🧬 `raw` — the complete source object, untrimmed
- ✨ `is_new` (monitor mode), 🕒 `scraped_at`

*\* = filled by the optional `fetchDetails` enrichment.*

---

### Who is it for?

- 🏘️ **Short-term-rental investors & analysts** — comps, occupancy proxies, pricing by neighborhood (lat/lng included).
- 💰 **Dynamic-pricing & revenue managers** — competitor nightly rates for exact dates and guest counts.
- 🏨 **Hospitality & travel teams** — market supply, ratings, amenity coverage by market.
- 📊 **Data & GIS teams** — listings as points on a map, exportable to CSV/GeoJSON pipelines.
- 🔔 **Deal & inventory watchers** — alert the moment new supply appears in a market you track.

---

### Two ways to use it

1. **Bulk scrape** — pull a market's listings (up to ~270 per search — Airbnb's own page-depth cap) into one clean dataset. Slice big cities into neighborhoods or price bands to cover more.
2. **New-listing monitor** *(the recurring play)* — set `monitorMode: true`, attach an **Apify Schedule** (e.g. daily), and the actor emits/alerts **only listings new since the last run** for that exact search.

---

### How to use it (step by step)

1. Click **Try for free**.
2. Enter a **Location** (e.g. `Austin, TX`).
3. *(Optional)* add dates, guests, a nightly price band, room type, or minimum bedrooms.
4. *(Optional)* turn on **Fetch full details** for description, amenities, host profile, and the full gallery.
5. Click **Start**, then open the **Dataset** tab to view/export.
6. *(Optional)* set **monitorMode** + a **Schedule** + an alert channel to get pinged on new listings.

#### Quick start

```json
{ "location": "Austin, TX", "maxItems": 50 }
````

#### Exact-dates pricing run

```json
{
  "location": "Miami, FL",
  "checkIn": "2026-08-07",
  "checkOut": "2026-08-10",
  "adults": 2,
  "priceMax": 250,
  "maxItems": 100
}
```

#### New-listing monitor

```json
{
  "location": "Joshua Tree, CA",
  "monitorMode": true,
  "alertOnNewListing": true,
  "slackWebhookUrl": "https://hooks.slack.com/services/…"
}
```

***

### Input

| Field | What it does |
|-------|--------------|
| `location` | city / neighborhood / region, as typed on airbnb.com |
| `checkIn` / `checkOut` | stay dates (YYYY-MM-DD) — makes prices exact totals |
| `adults` / `children` / `infants` / `pets` | guest counts (server-side filter) |
| `priceMin` / `priceMax` | nightly price band |
| `roomType` | `any` · `entire_home` · `private_room` · `shared_room` · `hotel_room` |
| `minBedrooms` / `minBeds` / `minBathrooms` | minimum room counts |
| `currency` | ISO currency for all prices (default USD) |
| `fetchDetails` | add description, full amenities, host profile, full gallery |
| `maxItems` | hard cap per run (0 = all available pages, ~270/search) |
| `monitorMode`, `alertOnNewListing` | recurring new-listing watcher |
| `webhookUrl`, `slackWebhookUrl`, `emailRecipients` | alert channels |
| `proxyConfiguration`, `requestConcurrency` | proxy + parallelism |

***

### Output

Each listing is one dataset record (fields above). Export to **JSON, CSV, Excel, HTML, RSS**, or fetch via the **Apify API**.

Example record (truncated):

```json
{
  "id": "1700108021251604884",
  "url": "https://www.airbnb.com/rooms/1700108021251604884",
  "name": "Settle In | Renovated High-End E Austin 2BR Home",
  "type": "Home in Central Austin",
  "lat": 30.27438207435496,
  "lng": -97.76175846585711,
  "price": "$708 USD",
  "price_qualifier": "total",
  "price_amount": 708,
  "price_per_night": 121,
  "nights": 5,
  "price_breakdown": [
    { "description": "5 nights x $121.00 USD", "price": "$605.00 USD" },
    { "description": "Taxes", "price": "$102.85 USD" }
  ],
  "currency": "USD",
  "rating": 4.89,
  "reviews_count": 301,
  "badges": ["Superhost"],
  "bedrooms": 2,
  "beds": 2,
  "baths": 1,
  "check_in": "2026-06-21",
  "check_out": "2026-06-26",
  "image_url": "https://a0.muscache.com/im/pictures/hosting/Hosting-…jpeg",
  "images": ["…6 photos from search, full gallery with fetchDetails…"]
}
```

***

### How much does it cost?

**$1.50 per 1,000 listings — no hidden fees, no start fee, no subscription.** Pay-per-event:

| Event | What it covers | Price |
|-------|----------------|-------|
| `lot-scraped` | each listing returned | **$0.0015** |
| `lot-detail-enriched` | each optional /rooms detail fetch | $0.002 |
| `monitor-run-completed` | each scheduled watch run | $0.02 |
| `new-lot-detected` | each newly listed stay | $0.01 |
| `alert-delivered` | each Slack/email/webhook push | $0.005 |

A 1,000-listing market pull = **$1.50**. A daily monitor on one market ≈ $0.62/month plus the new listings it actually finds.

***

### Is it legal to scrape Airbnb?

Airbnb listing data here is **public** — every field is visible to a logged-out visitor, and the records are about properties, not private individuals (host name/photo are what hosts publish publicly on their own listing). That said, **Airbnb's Terms of Service prohibit automated access without permission, so scraping it is a legal gray area**. This actor collects only what a public page shows, sends no login, and respects no-auth boundaries — but you are responsible for how you use the data: review Airbnb's ToS and your local regulations (incl. GDPR if you store host personal data) before commercial use.

***

### FAQ

**Do I need an Airbnb account, login, or API key?**
No. The actor reads the same embedded data Airbnb's own search page renders for any logged-out visitor.

**How many listings can one search return?**
Airbnb serves at most ~15 pages × 18 listings ≈ 270 per search (the same cap you hit browsing the site). To cover a big city, run multiple narrower searches — neighborhoods, price bands (`priceMin`/`priceMax`), or room types — and merge the datasets.

**Are the prices accurate?**
Yes — they're the exact prices Airbnb renders for your search. Set `checkIn`/`checkOut` for date-exact stay totals, with the per-night rate and taxes parsed into `price_breakdown`. Without dates, Airbnb shows representative pricing for default dates it picks (returned in `check_in`/`check_out`).

**Can I get prices in my currency?**
Yes — set `currency` to any ISO code (EUR, GBP, AUD…). Default is USD so results never flip currency based on where the request exits.

**Does it return exact coordinates?**
Yes — `lat`/`lng` come with every listing straight from the search payload, no extra requests.

**What extra data does `fetchDetails` add?**
Full description, the complete grouped amenity list (including unavailable amenities), host profile (name, Superhost/verified, rating, review count, years hosting, highlights), exact room type, guest capacity, city, and the full photo gallery. It costs one extra request + one `lot-detail-enriched` event per listing — off by default.

**Can it monitor a market for new listings?**
Yes — `monitorMode: true` + an Apify Schedule. Each run diffs against the previous run's seen-set (persisted per search scope) and outputs/alerts only listings new to that search, via Slack, email, or webhook. Tip: Airbnb shuffles which listings fill a small window between requests, so set `maxItems: 0` (walk all ~15 pages) in monitor mode — otherwise listings rotating into a small window can look "new". Narrow the search (neighborhood / price band / room type) so the full result set fits the ~270-listing cap.

**Why do some listings show `rating: null`?**
They're new — Airbnb shows "New" instead of a rating until a listing has reviews; we flag those with `is_new_listing: true`.

**Can I filter by entire homes only / minimum bedrooms?**
Yes — `roomType: "entire_home"` and `minBedrooms` (plus `minBeds`, `minBathrooms`) are applied server-side by Airbnb, so filtered-out listings never count against your bill.

**What happens if a page fails mid-run?**
Every request retries up to 4× with a fresh proxy session; a page that still fails is skipped and the run continues — you get every listing that was reachable instead of a failed run.

**How fast is it?**
\~18 listings per ~1.5s request — 250 listings in well under a minute without details.

**How do I export the data?**
JSON, CSV, Excel, HTML, or RSS from the Dataset tab, or via the Apify API. The `raw` field carries the untrimmed source object for anything not flattened.

**Is scraping Airbnb allowed?**
See the legal section above — public data, but Airbnb's ToS restricts automated access; that judgment and compliance are yours.

***

### You might also like

- 🏨 Hotel & travel marketplace scrapers
- 🏘️ Real-estate listing & rental-market scrapers
- 📊 Price-monitoring and market-analysis actors

***

### Feedback

Found a missing field or want a new filter? Open an issue on the actor — fast fixes and feature requests welcome.

# Actor input Schema

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

Where to search — city, neighborhood, region, or address, exactly as you'd type it on airbnb.com, e.g. 'Austin, TX', 'Paris, France', 'Brooklyn, NY', 'Lake Tahoe'.

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

Optional check-in date (YYYY-MM-DD). When set with check-out, prices are exact stay totals for those dates and only available listings are returned.

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

Optional check-out date (YYYY-MM-DD). Pair with check-in.

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

Number of adult guests (0 = unspecified).

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

Number of child guests.

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

Number of infants.

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

Number of pets (filters to pet-friendly listings).

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

Only listings at/above this nightly price (in the selected currency). Leave empty for no floor.

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

Only listings at/below this nightly price. Leave empty for no cap.

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

Restrict to a listing type (server-side filter).

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

Only listings with at least this many bedrooms (server-side filter).

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

Only listings with at least this many beds.

## `minBathrooms` (type: `integer`):

Only listings with at least this many bathrooms.

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

Currency for all prices (ISO code, e.g. USD, EUR, GBP, CAD). Defaults to USD so results are stable regardless of where the request exits.

## `fetchDetails` (type: `boolean`):

Visit each listing's /rooms/{id} page for the full record: description, complete amenity list (grouped, incl. unavailable ones), host profile (name, Superhost, rating, years hosting), exact room type, guest capacity, city, and the FULL photo gallery. One extra request per listing.

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

Hard cap on listings scraped this run (cost/safety guard). Defaults to 50 for a fast first run — set 0 to walk every available page (~270 listings per search; narrow with filters to cover more of a market).

## `monitorMode` (type: `boolean`):

Recurring watcher: diff against the prior run's seen listings (per search scope) and output/alert ONLY listings new to this search. Pair with an Apify Schedule.

## `alertOnNewListing` (type: `boolean`):

In monitor mode, deliver an alert for each new listing via the channels below.

## `webhookUrl` (type: `string`):

POST endpoint for new-listing alert payloads (Make / Zapier / n8n / custom). One JSON body per alert.

## `slackWebhookUrl` (type: `string`):

Slack incoming-webhook URL for formatted new-listing cards (photo + price + rating).

## `emailRecipients` (type: `array`):

Email addresses for the new-listing digest (sent via apify/send-mail).

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

Proxy settings. Datacenter rotation works today; if you scrape at heavy volume and see empty pages, switch to residential.

## `requestConcurrency` (type: `integer`):

Max parallel requests for detail fetches. Keep modest to stay under the radar.

## `diagnose` (type: `boolean`):

Dev only. Dumps the raw embedded JSON + parsed first row to the key-value store (DEBUG\_SEARCH\_JSON / DEBUG\_DETAIL\_JSON), logs a pagination check, then exits. Leave off for normal runs.

## Actor input object example

```json
{
  "location": "Austin, TX",
  "adults": 0,
  "children": 0,
  "infants": 0,
  "pets": 0,
  "roomType": "any",
  "currency": "USD",
  "fetchDetails": false,
  "maxItems": 50,
  "monitorMode": false,
  "alertOnNewListing": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "requestConcurrency": 5,
  "diagnose": false
}
```

# Actor output Schema

## `items` (type: `string`):

The dataset of scraped Airbnb listings (one listing per row).

# 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": "Austin, TX",
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/airbnb-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "location": "Austin, TX",
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/airbnb-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 '{
  "location": "Austin, TX",
  "maxItems": 50
}' |
apify call scrapersdelight/airbnb-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Airbnb Scraper (Working) — $1.50 per 1,000 Listings",
        "description": "$1.50 per 1,000 listings — no hidden fees, no start fee. Scrape Airbnb by location with date, guest, price & room-type filters: name, price, rating, reviews, lat/lng, beds, baths, images, URL. Optional detail enrichment (amenities, host, description) + new-listing monitor. No login or API key.",
        "version": "0.1",
        "x-build-id": "CS0OsNYigp3PI7kTi"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapersdelight~airbnb-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapersdelight-airbnb-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/scrapersdelight~airbnb-scraper/runs": {
            "post": {
                "operationId": "runs-sync-scrapersdelight-airbnb-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/scrapersdelight~airbnb-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-scrapersdelight-airbnb-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",
                "required": [
                    "location"
                ],
                "properties": {
                    "location": {
                        "title": "Location",
                        "type": "string",
                        "description": "Where to search — city, neighborhood, region, or address, exactly as you'd type it on airbnb.com, e.g. 'Austin, TX', 'Paris, France', 'Brooklyn, NY', 'Lake Tahoe'."
                    },
                    "checkIn": {
                        "title": "Check-in date",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "type": "string",
                        "description": "Optional check-in date (YYYY-MM-DD). When set with check-out, prices are exact stay totals for those dates and only available listings are returned."
                    },
                    "checkOut": {
                        "title": "Check-out date",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "type": "string",
                        "description": "Optional check-out date (YYYY-MM-DD). Pair with check-in."
                    },
                    "adults": {
                        "title": "Adults",
                        "minimum": 0,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Number of adult guests (0 = unspecified).",
                        "default": 0
                    },
                    "children": {
                        "title": "Children",
                        "minimum": 0,
                        "maximum": 15,
                        "type": "integer",
                        "description": "Number of child guests.",
                        "default": 0
                    },
                    "infants": {
                        "title": "Infants",
                        "minimum": 0,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Number of infants.",
                        "default": 0
                    },
                    "pets": {
                        "title": "Pets",
                        "minimum": 0,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Number of pets (filters to pet-friendly listings).",
                        "default": 0
                    },
                    "priceMin": {
                        "title": "Min price per night",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only listings at/above this nightly price (in the selected currency). Leave empty for no floor."
                    },
                    "priceMax": {
                        "title": "Max price per night",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Only listings at/below this nightly price. Leave empty for no cap."
                    },
                    "roomType": {
                        "title": "Room type",
                        "enum": [
                            "any",
                            "entire_home",
                            "private_room",
                            "shared_room",
                            "hotel_room"
                        ],
                        "type": "string",
                        "description": "Restrict to a listing type (server-side filter).",
                        "default": "any"
                    },
                    "minBedrooms": {
                        "title": "Min bedrooms",
                        "minimum": 0,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Only listings with at least this many bedrooms (server-side filter)."
                    },
                    "minBeds": {
                        "title": "Min beds",
                        "minimum": 0,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Only listings with at least this many beds."
                    },
                    "minBathrooms": {
                        "title": "Min bathrooms",
                        "minimum": 0,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Only listings with at least this many bathrooms."
                    },
                    "currency": {
                        "title": "Currency",
                        "type": "string",
                        "description": "Currency for all prices (ISO code, e.g. USD, EUR, GBP, CAD). Defaults to USD so results are stable regardless of where the request exits.",
                        "default": "USD"
                    },
                    "fetchDetails": {
                        "title": "Fetch full details",
                        "type": "boolean",
                        "description": "Visit each listing's /rooms/{id} page for the full record: description, complete amenity list (grouped, incl. unavailable ones), host profile (name, Superhost, rating, years hosting), exact room type, guest capacity, city, and the FULL photo gallery. One extra request per listing.",
                        "default": false
                    },
                    "maxItems": {
                        "title": "Max listings per run",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Hard cap on listings scraped this run (cost/safety guard). Defaults to 50 for a fast first run — set 0 to walk every available page (~270 listings per search; narrow with filters to cover more of a market).",
                        "default": 50
                    },
                    "monitorMode": {
                        "title": "Monitor mode (new-listing watcher)",
                        "type": "boolean",
                        "description": "Recurring watcher: diff against the prior run's seen listings (per search scope) and output/alert ONLY listings new to this search. Pair with an Apify Schedule.",
                        "default": false
                    },
                    "alertOnNewListing": {
                        "title": "Alert on new listings",
                        "type": "boolean",
                        "description": "In monitor mode, deliver an alert for each new listing via the channels below.",
                        "default": true
                    },
                    "webhookUrl": {
                        "title": "Webhook URL",
                        "type": "string",
                        "description": "POST endpoint for new-listing alert payloads (Make / Zapier / n8n / custom). One JSON body per alert."
                    },
                    "slackWebhookUrl": {
                        "title": "Slack webhook URL",
                        "type": "string",
                        "description": "Slack incoming-webhook URL for formatted new-listing cards (photo + price + rating)."
                    },
                    "emailRecipients": {
                        "title": "Email recipients",
                        "type": "array",
                        "description": "Email addresses for the new-listing digest (sent via apify/send-mail).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "proxyConfiguration": {
                        "title": "Proxy",
                        "type": "object",
                        "description": "Proxy settings. Datacenter rotation works today; if you scrape at heavy volume and see empty pages, switch to residential.",
                        "default": {
                            "useApifyProxy": true
                        }
                    },
                    "requestConcurrency": {
                        "title": "Request concurrency",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Max parallel requests for detail fetches. Keep modest to stay under the radar.",
                        "default": 5
                    },
                    "diagnose": {
                        "title": "Diagnostic mode (dev)",
                        "type": "boolean",
                        "description": "Dev only. Dumps the raw embedded JSON + parsed first row to the key-value store (DEBUG_SEARCH_JSON / DEBUG_DETAIL_JSON), logs a pagination check, then exits. Leave off for normal runs.",
                        "default": false
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
