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

Vrbo scraper with built-in STR investor KPIs — ADR, occupancy, RevPAR, estimated annual revenue per listing. 5 search modes (location, coordinates, polygon, URL, propertyId). Granular per-event enrichment: availability, reviews, host. HTML market report included.

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

## Pricing

from $3.00 / 1,000 listing extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/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

## Vrbo Scraper + STR Market KPIs — ADR · Occupancy · RevPAR 🚀

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

#### 🎉 NEW: Built-in STR investor KPIs — ADR · Occupancy · RevPAR · Estimated Annual Revenue per Vrbo listing
##### Built for short-term-rental investors, vacation-rental property managers, and market-sizing analysts who underwrite deals from data, not gut feel.

---

### 📋 Overview

**Underwrite a vacation-rental deal in minutes, not days.** The Vrbo Property Scraper pulls every listing in your target market and ships ready-to-model STR KPIs alongside the raw data — so you can rank comps by RevPAR before you make an offer.

**Why thousands of STR investors and managers choose us:**
- ✅ **Built-in STR KPIs**: ADR, `occupancyRate`, RevPAR, `estimatedAnnualRevenue`, and `isStale` flag computed from per-listing calendar enrichment — competitors ship raw search results only.
- ⚡ **5 search modes**: Location, coordinates, polygon (lat/lon bounding box), URL, and direct property ID. Most incumbents ship 1–2.
- 🎯 **Granular pay-per-event enrichment**: Pay only for the data layer you actually need — `ListingExtracted`, `AvailabilityEnriched`, `ReviewsEnriched`, `HostEnriched`. No bundled "result" charges.
- 💰 **Tiered Idealista-style curve**: FREE $0.030 → flat **$0.003 at GOLD**. Beats every paid Vrbo incumbent at scale.
- 💎 **HTML market report per run**: KPI dashboard, ADR / occupancy distribution charts, top-host leaderboards — saved automatically, no extra cost.
- ✨ **NEW**: Polygon search — scrape only inside a custom lat/lon polygon for ski-resort zones, coastal strips, and hyperlocal neighborhoods incumbents can't target.

---

### ✨ Features

- 🏖️ **Search by Location** — City, region, country name; autocomplete-resolved
- 📍 **Search by Coordinates** — Lat/lon + radius for precise market scans
- 🗺️ **Polygon Search** — Multi-point lat/lon bounding for irregular markets
- 🔗 **URL Search** — Paste a Vrbo search URL; we parse the filters
- 🆔 **Property ID Lookup** — Direct fetch by Vrbo numeric ID
- 📅 **Calendar Enrichment** — Full forward calendar with nightly prices and availability flags
- ⭐ **Reviews Enrichment** — Paginated review feed with rating, date, and reviewer
- 👤 **Host Enrichment** — Host profile, badges (e.g. Premier Host), tenure, listing count
- 📈 **STR KPIs Per Listing** — ADR, `occupancyRate` (with host-block baseline), RevPAR, `estimatedAnnualRevenue`, `isStale`
- 📊 **HTML Market Report** — Auto-generated dashboard saved to the run's key-value store

---

### 🎬 Quick Start

Pick a search mode, hand us a location (or URL, coordinates, polygon, ID), choose which enrichments you want, and run. Results stream straight to the Apify dataset; the HTML report saves to the run's key-value store at `report.html`.

```bash
curl -X POST https://api.apify.com/v2/acts/sian.agency~vrbo-property-scraper/runs?token=[YOUR_TOKEN] \
-d '{"searchMode": "location", "query": "Miami Beach, FL", "computeAvailability": true}'
````

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Pick a search mode

Choose one of: `location`, `coordinates`, `polygon`, `url`, or `propertyId`.

#### Step 2: Toggle the enrichments you want

Flip on `computeAvailability` for KPIs, `computeReviews` for the review feed, `computeHost` for host profile. Each is opt-in and priced separately — pay only for what you need.

#### Step 3: Hit run

The first **25 listings are free** (no credit card). Watch the dataset fill in real time. Download as JSON / CSV / Excel directly from the Apify UI.

**That's it! In under 5 minutes, you'll have:**

- A clean dataset of Vrbo listings with 40+ fields
- Per-listing ADR / occupancy / RevPAR / annual revenue estimates
- An HTML market dashboard you can share with your team

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|---|---|---|---|
| `searchMode` | string | Yes | One of: `location`, `coordinates`, `polygon`, `url`, `propertyId` |
| `query` | string | Conditional | Location name (for `location` mode) |
| `latitude` / `longitude` | number | Conditional | Center point for `coordinates` mode |
| `radius` | number | Optional | Search radius in km (coordinates mode) |
| `polygon` | array | Conditional | Array of `[lat, lon]` points for `polygon` mode |
| `vrboUrl` | string | Conditional | Search URL for `url` mode |
| `propertyId` | string | Conditional | Direct Vrbo property ID for `propertyId` mode |
| `maxListings` | integer | Optional | Cap on results (default: tier-based) |
| `computeAvailability` | boolean | Optional | Enrich each listing with full calendar + STR KPIs |
| `computeReviews` | boolean | Optional | Enrich each listing with paginated reviews |
| `computeHost` | boolean | Optional | Enrich each listing with host profile |

**Example — search a destination + compute KPIs:**

```json
{
  "searchMode": "location",
  "query": "Aspen, CO",
  "maxListings": 200,
  "computeAvailability": true,
  "computeHost": true
}
```

**Example — polygon-bounded market scan:**

```json
{
  "searchMode": "polygon",
  "polygon": [
    [25.79, -80.13],
    [25.79, -80.10],
    [25.76, -80.10],
    [25.76, -80.13]
  ],
  "computeAvailability": true
}
```

***

### 📤 Output

Results are saved to the Apify dataset with **40+ fields** per listing including:

| Field | Type | Description |
|---|---|---|
| `propertyId` | string | Vrbo numeric ID (string for precision) |
| `listingTitle` | string | Listing headline |
| `propertyUrl` | string | Direct Vrbo URL |
| `city` / `region` / `country` | string | Location breakdown |
| `latitude` / `longitude` | number | Geo coordinates |
| `currentPriceNumeric` | number | Parsed nightly price |
| `currency` | string | ISO currency code |
| `ratingValue` | number | Vrbo 0–10 rating |
| `bedrooms` / `bathrooms` / `maxOccupancy` | integer | Property capacity |
| `propertyBadges` | array | E.g. `["Premier Host", "On the beach"]` |
| `photoUrls` | array | All listing photos |
| **`adr`** | number | Average daily rate over the calendar window |
| **`occupancyRate`** | number | Computed occupancy (0–1), with 10% host-block baseline |
| **`revpar`** | number | ADR × occupancyRate |
| **`estimatedAnnualRevenue`** | number | RevPAR × 365 |
| **`isStale`** | boolean | True if calendar is empty AND review count < 3 |
| `availabilityCalendar` | array | Per-day calendar (when enrichment enabled) |
| `reviewSample` | array | Paginated review feed (when enrichment enabled) |
| `hostProfile` | object | Host profile, badges, tenure (when enrichment enabled) |

**Example row (truncated):**

```json
{
  "propertyId": "1234567",
  "listingTitle": "Oceanfront 2BR · Premier Host",
  "city": "Miami Beach",
  "currentPriceNumeric": 312,
  "currency": "USD",
  "ratingValue": 9.6,
  "bedrooms": 2,
  "maxOccupancy": 4,
  "adr": 298.5,
  "occupancyRate": 0.71,
  "revpar": 211.94,
  "estimatedAnnualRevenue": 77357.6,
  "isStale": false,
  "propertyBadges": ["Premier Host", "On the beach"]
}
```

An HTML market report is also saved to `report.html` in the run's key-value store — KPI distributions, top hosts, ADR histograms, and a search-summary panel.

***

### 💼 Use Cases & Examples

#### 1. STR investor underwriting

**A short-term-rental investor sizing up a Miami Beach acquisition.**

**Input:** ZIP code or polygon around the target property
**Output:** Every comp's ADR, occupancy, RevPAR, estimated annual revenue
**Use:** Rank comps by RevPAR, find the 90th-percentile performer in the cluster, build a pro forma you can defend to a lender.

#### 2. Vacation-rental market sizing

**A property manager building a TAM model for a new destination.**

**Input:** City or region name
**Output:** Total active listings, segmented by bedroom count, amenities, host type
**Use:** Compute total addressable supply, identify undersupplied bedroom counts, plan acquisition or onboarding strategy.

#### 3. Competitor RevPAR benchmarking

**A pricing manager watching direct comps week-over-week.**

**Input:** A polygon around the manager's portfolio
**Output:** Weekly snapshots of competitor calendar fill, price changes, blackout patterns, host-block ratios
**Use:** Tune nightly pricing in PriceLabs / Wheelhouse with real comp data — not aggregator estimates.

#### 4. Destination revenue forecasting

**A market analyst building a 12-month revenue forecast for an investor deck.**

**Input:** Destination name + radius
**Output:** Aggregate ADR + occupancy curves across the next 30 / 90 / 365 days
**Use:** Forward-looking RevPAR projections, seasonality curves, peak-window pricing analysis.

#### 5. Polygon-bounded market scans

**An analyst studying a ski-resort zone or coastal strip.**

**Input:** Custom lat/lon polygon
**Output:** Only listings inside the polygon — no spillover from neighboring zip codes
**Use:** Hyperlocal supply analysis incumbents can't replicate; perfect for ski-town micro-markets, beach strips, neighborhood-level comp sets.

#### 6. Calendar-pricing audits

**An owner auditing their own pricing vs. the market.**

**Input:** Property ID + nearby comp IDs
**Output:** Full forward calendar per property with nightly price + availability
**Use:** Identify nights where you're overpriced (low occupancy ahead) or underpriced (already booked solid).

***

### 🔗 Integration Examples

#### JavaScript / Node.js

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

const run = await client.actor('sian.agency/vrbo-property-scraper').call({
  searchMode: 'location',
  query: 'Aspen, CO',
  maxListings: 200,
  computeAvailability: true
});

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

#### Python

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

run = client.actor('sian.agency/vrbo-property-scraper').call(run_input={
    'searchMode': 'location',
    'query': 'Miami Beach, FL',
    'maxListings': 100,
    'computeAvailability': True,
    'computeHost': True,
})

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item['listingTitle'], item.get('revpar'), item.get('estimatedAnnualRevenue'))
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~vrbo-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"searchMode": "location", "query": "Lake Tahoe, CA", "computeAvailability": true}'
```

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

1. **Trigger**: Weekly schedule
2. **HTTP Request**: Call the actor with your saved polygon
3. **Process**: Read the dataset, compute deltas vs. last week
4. **Action**: Push RevPAR alerts to Slack / email / a Notion database

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **25 listings per run** — full feature access, identical data quality
- No credit card required
- Perfect for testing a market before you commit

#### PAID Tier (Production Ready)

- **Unlimited** listings per run
- Volume-tiered pricing — the more you scrape, the cheaper each listing becomes
- Pay-per-event: only charged for successful results

**Headline pricing — `ListingExtracted` event:**

| Tier | Price / listing |
|---|---|
| FREE | $0.030 |
| BRONZE ($20 spend) | $0.012 |
| SILVER ($100 spend) | $0.006 |
| **GOLD ($500 spend)** | **$0.003** |
| PLATINUM ($2,000 spend) | $0.003 |
| DIAMOND ($5,000 spend) | $0.003 |

**Enrichment events** (opt-in, charged only on success): `AvailabilityEnriched`, `ReviewsEnriched`, `HostEnriched` — each follows a similar tiered curve, with GOLD floor at $0.002.

💰 **Best price on the market at scale** — every paid Vrbo incumbent charges $0.0025–$0.005 flat with no volume curve. At GOLD floor we beat them on the headline event and give you opt-in enrichment for thinner rows.

🔗 [View live pricing on the actor page](https://apify.com/sian.agency/vrbo-property-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: How many listings can I process?**
A: FREE tier: 25 per run. PAID tier: unlimited. The tier curve drops the per-listing price at $20, $100, $500, $2,000, and $5,000 of lifetime spend.

**Q: How are ADR, occupancy, and RevPAR computed?**
A: From each listing's forward calendar. ADR = mean nightly price across the window. `occupancyRate` = (unavailable nights ÷ window) − 10% host-block baseline (so we don't count blocked nights as bookings). RevPAR = ADR × occupancyRate. `estimatedAnnualRevenue` = RevPAR × 365.

**Q: What's the `isStale` flag?**
A: `true` when the forward calendar shows full availability **and** the review count is < 3 — a strong signal the listing is inactive or new and shouldn't be counted in comp sets.

**Q: Does the polygon mode support irregular shapes?**
A: Yes. Pass any closed lat/lon polygon (array of `[lat, lon]` points). We hand it to Vrbo's geo-bounded search.

**Q: What output formats are available?**
A: JSON, CSV, Excel, RSS, JSONL, XML — export directly from the Apify dataset UI or via the API.

**Q: Does it work with private or unlisted properties?**
A: No, only publicly accessible Vrbo listings are supported.

**Q: Is this legal?**
A: Yes — we only extract publicly available data. See our [legal section](#-is-it-legal-to-scrape-data) below.

**Q: How long does processing take?**
A: ~1–2 seconds per listing including all enrichments. A 200-listing destination scan with full KPI enrichment runs in 4–6 minutes.

***

### 🐞 Troubleshooting

**The dataset is empty after a successful run.**

- Check `searchMode` matches the field you provided (e.g. `location` mode needs `query`; `polygon` mode needs `polygon`).
- For `propertyId` mode, ensure the ID is the numeric Vrbo property ID (not the URL slug).
- On FREE tier, only 25 results return per run — if your search has < 25 matches, that's the full set.

**STR KPIs (`adr`, `occupancyRate`, `revpar`) are missing.**

- Flip `computeAvailability` to `true`. KPIs are computed from the calendar enrichment, which is opt-in to keep low-tier scans cheap.

**Polygon search returns 0 results.**

- Ensure the polygon is closed (first and last points equal — we auto-close if not) and contains at least 3 distinct points.
- Polygons must be in `[latitude, longitude]` order, not `[lon, lat]`.

**A listing's `ratingValue` looks low (e.g. 4.8).**

- Vrbo ratings are on a **0–10 scale** (not 0–5 like Airbnb). 4.8 means "needs improvement"; 9.6 is "exceptional".

***

### ⚖️ 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/).

***

### ⚠️ Trademark Disclaimer

**Vrbo®** is a registered trademark of **Expedia Group, Inc.** This Apify Actor is an **independent third-party scraping tool**. It is **not affiliated with, endorsed by, sponsored by, or connected to** Vrbo, Expedia Group, or any of their subsidiaries. The Vrbo® name appears in this listing under nominative fair use, solely to identify the public platform whose publicly available listing data this tool helps you collect.

This tool does not provide access to Vrbo's internal systems, private APIs, partner data, or proprietary services. Users are responsible for ensuring their use complies with Vrbo's Terms of Service and all applicable laws.

***

### 🤝 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 the [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@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 Vrbo. Each mode reads its own dedicated input fields below — fields outside the chosen mode are ignored.

• **location** — text destination (default; e.g. 'Miami, Florida')
• **coordinates** — center point (lat/lng + radius)
• **polygon** — geo polygon (list of lat,lng vertices)
• **url** — paste a Vrbo search or property URL
• **propertyId** — direct lookup by Vrbo property ID

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

Hard cap on listings returned per query. Auto-paginates 50 listings/page until cap is reached or search is fully drained. Vrbo caps searches at 300 total results. FREE tier is always capped at 25.

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

Free-text destination, e.g. 'Miami, Florida' or 'Orlando, FL'. Use the Vrbo destination box on vrbo.com to find canonical strings.

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

Array of location strings. PAID tier only.

## `latitude` (type: `string`):

Center-point latitude. -90 to 90.

## `longitude` (type: `string`):

Center-point longitude. -180 to 180.

## `polygon` (type: `string`):

Semicolon-separated lat,lng vertex pairs forming a closed polygon. First and last vertices should match. Example: '25.78,-80.19;25.80,-80.18;25.79,-80.16;25.77,-80.17;25.78,-80.19'.

## `vrboUrl` (type: `string`):

Paste a Vrbo search URL or a single property URL from your browser. Auto-paginates through search results.

## `vrboUrls` (type: `array`):

Array of Vrbo search or property URLs. PAID tier only.

## `propertyId` (type: `string`):

Vrbo numeric property ID. Returns 1 row per ID with the full detail bundle.

## `propertyIds` (type: `array`):

Array of Vrbo property IDs. PAID tier only.

## `computeAvailability` (type: `boolean`):

When ON, fetches each listing's forward-looking calendar (1 extra API call per listing) and computes occupancy rate, ADR, RevPAR, and estimated annual revenue. Adds an AvailabilityEnriched 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.

## `fetchReviews` (type: `boolean`):

When ON, fetches the latest reviews for each listing (1 extra API call per listing, 10 reviews per page). Adds a ReviewsEnriched charge per listing. Disabled on FREE tier.

## `maxReviewsPerListing` (type: `integer`):

Cap on reviews returned per listing. Reviews are paginated 10/page upstream. Default 10 = first page only.

## `fetchHost` (type: `boolean`):

When ON, fetches the full host profile for each listing (1 extra API call per listing). Adds a HostEnriched charge per listing. Disabled on FREE tier.

## Actor input object example

```json
{
  "searchMode": "location",
  "maxResultsPerQuery": 50,
  "location": "Miami, Florida",
  "latitude": "25.7617",
  "longitude": "-80.1918",
  "polygon": "25.78,-80.19;25.80,-80.18;25.79,-80.16;25.77,-80.17;25.78,-80.19",
  "vrboUrl": "https://www.vrbo.com/search?destination=Miami&regionId=2297",
  "propertyId": "92983848",
  "computeAvailability": false,
  "availabilityWindowDays": 90,
  "fetchReviews": false,
  "maxReviewsPerListing": 10,
  "fetchHost": false
}
```

# Actor output Schema

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

Structured Vrbo 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 = {
    "location": "Miami, Florida"
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/vrbo-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 = { "location": "Miami, Florida" }

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/vrbo-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 '{
  "location": "Miami, Florida"
}' |
apify call sian.agency/vrbo-property-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Vrbo Scraper + STR Market KPIs (ADR · Occupancy · RevPAR)",
        "description": "Vrbo scraper with built-in STR investor KPIs — ADR, occupancy, RevPAR, estimated annual revenue per listing. 5 search modes (location, coordinates, polygon, URL, propertyId). Granular per-event enrichment: availability, reviews, host. HTML market report included.",
        "version": "1.0",
        "x-build-id": "4Bhw5moF5gRjfhzr7"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sian.agency~vrbo-property-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sian.agency-vrbo-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~vrbo-property-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sian.agency-vrbo-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~vrbo-property-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sian.agency-vrbo-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": [
                            "location",
                            "coordinates",
                            "polygon",
                            "url",
                            "propertyId"
                        ],
                        "type": "string",
                        "description": "Pick how you want to search Vrbo. Each mode reads its own dedicated input fields below — fields outside the chosen mode are ignored.\n\n• **location** — text destination (default; e.g. 'Miami, Florida')\n• **coordinates** — center point (lat/lng + radius)\n• **polygon** — geo polygon (list of lat,lng vertices)\n• **url** — paste a Vrbo search or property URL\n• **propertyId** — direct lookup by Vrbo property ID",
                        "default": "location"
                    },
                    "maxResultsPerQuery": {
                        "title": "📊 Max results per query",
                        "minimum": 1,
                        "maximum": 300,
                        "type": "integer",
                        "description": "Hard cap on listings returned per query. Auto-paginates 50 listings/page until cap is reached or search is fully drained. Vrbo caps searches at 300 total results. FREE tier is always capped at 25.",
                        "default": 50
                    },
                    "location": {
                        "title": "📍 Location  (used when Search Mode = location)",
                        "type": "string",
                        "description": "Free-text destination, e.g. 'Miami, Florida' or 'Orlando, FL'. Use the Vrbo destination box on vrbo.com to find canonical strings.",
                        "default": "Miami, Florida"
                    },
                    "locations": {
                        "title": "📋 Bulk Locations  (PAID, location mode)",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Array of location strings. PAID tier only.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "latitude": {
                        "title": "🧭 Latitude  (used when Search Mode = coordinates)",
                        "type": "string",
                        "description": "Center-point latitude. -90 to 90."
                    },
                    "longitude": {
                        "title": "🧭 Longitude",
                        "type": "string",
                        "description": "Center-point longitude. -180 to 180."
                    },
                    "polygon": {
                        "title": "🔷 Polygon  (used when Search Mode = polygon)",
                        "type": "string",
                        "description": "Semicolon-separated lat,lng vertex pairs forming a closed polygon. First and last vertices should match. Example: '25.78,-80.19;25.80,-80.18;25.79,-80.16;25.77,-80.17;25.78,-80.19'."
                    },
                    "vrboUrl": {
                        "title": "🔗 Vrbo URL  (used when Search Mode = url)",
                        "pattern": "^https?://(www\\.)?vrbo\\.[a-z.]+/.+",
                        "type": "string",
                        "description": "Paste a Vrbo search URL or a single property URL from your browser. Auto-paginates through search results."
                    },
                    "vrboUrls": {
                        "title": "📋 Bulk Vrbo URLs  (PAID, url mode)",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Array of Vrbo search or property URLs. PAID tier only.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "propertyId": {
                        "title": "🆔 Property ID  (used when Search Mode = propertyId)",
                        "type": "string",
                        "description": "Vrbo numeric property ID. Returns 1 row per ID with the full detail bundle."
                    },
                    "propertyIds": {
                        "title": "📋 Bulk Property IDs  (PAID, propertyId mode)",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Array of Vrbo property IDs. PAID tier only.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "computeAvailability": {
                        "title": "📅 Compute occupancy & RevPAR  (recommended for investors)",
                        "type": "boolean",
                        "description": "When ON, fetches each listing's forward-looking calendar (1 extra API call per listing) and computes occupancy rate, ADR, RevPAR, and estimated annual revenue. Adds an AvailabilityEnriched 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.",
                        "default": 90
                    },
                    "fetchReviews": {
                        "title": "💬 Fetch reviews",
                        "type": "boolean",
                        "description": "When ON, fetches the latest reviews for each listing (1 extra API call per listing, 10 reviews per page). Adds a ReviewsEnriched charge per listing. Disabled on FREE tier.",
                        "default": false
                    },
                    "maxReviewsPerListing": {
                        "title": "💬 Max reviews per listing",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Cap on reviews returned per listing. Reviews are paginated 10/page upstream. Default 10 = first page only.",
                        "default": 10
                    },
                    "fetchHost": {
                        "title": "🧑‍💼 Fetch host details",
                        "type": "boolean",
                        "description": "When ON, fetches the full host profile for each listing (1 extra API call per listing). Adds a HostEnriched charge per listing. Disabled on FREE tier.",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
