Vrbo holds one of the largest vacation rental datasets outside Airbnb, and scraping it cleanly in 2026 requires handling dynamic JavaScript rendering, aggressive bot detection, and geo-targeted pricing that shifts based on your request IP. this guide covers the technical approach end to end.
What Vrbo’s Anti-Bot Stack Looks Like in 2026
Vrbo runs on Expedia Group infrastructure, which means you’re up against a Akamai Bot Manager layer plus server-side rendering on most listing pages. the search results endpoint (/search/keywords) returns JSON-in-HTML on initial load, then hydrates via GraphQL calls to api.vrbo.com/graphql. the GraphQL endpoint is the real prize — it returns structured property data including nightly rates, availability calendars, and review scores in a single response.
Akamai’s sensor data collection means headless Chromium without stealth patches gets flagged within 5-10 requests. you’ll see 403s or silent redirects to a CAPTCHA page. residential IPs from the rental’s target geography significantly improve pass rates — the same technique applies when you’re scraping Skyscanner flight data at scale, where geo-matched IPs affect both access and the prices returned.
The Two Extraction Paths
Path 1: GraphQL API Interception
the cleanest method is intercepting the GraphQL calls in a browser session and replaying them. open DevTools on a Vrbo search results page and filter for api.vrbo.com/graphql. you’ll see a POST with an operationName field — the most useful ones are SearchListings and PropertyAvailability.
import httpx, json
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...",
"x-vrbo-take": "50",
"content-type": "application/json",
"x-page-id": "page.search-result-pages.vrbo",
}
payload = {
"operationName": "SearchListings",
"variables": {
"request": {
"destination": {"coordinates": {"lat": 25.7617, "lng": -80.1918}},
"dates": {"checkin": "2026-07-01", "checkout": "2026-07-07"},
"paging": {"page": 1, "pageSize": 50},
}
},
"query": "... paste full query from DevTools ..."
}
resp = httpx.post("https://api.vrbo.com/graphql", headers=headers, json=payload)
listings = resp.json()["data"]["results"]["listings"]this works until Akamai’s session tokens expire or your IP gets flagged. rotate residential proxies per session, not per request — session consistency matters more than raw rotation speed.
Path 2: Playwright with Stealth
for property detail pages and availability calendars not exposed cleanly in GraphQL, use Playwright with playwright-stealth or Camoufox. set --disable-blink-features=AutomationControlled and spoof a realistic viewport. sleep intervals between 1.5-4 seconds between page loads. this is slower (roughly 200-400 listings/hour) but more reliable for long-running jobs.
Data Fields Worth Targeting
Vrbo listing data breaks into three tiers by extraction difficulty:
| Field | Source | Difficulty |
|---|---|---|
| Property ID, title, coordinates | Search GraphQL | Easy |
| Nightly rate (base + fees) | SearchListings response | Easy |
| Availability calendar (12 months) | PropertyAvailability GraphQL | Medium |
| Host response rate, review count | Property detail page | Medium |
| Exact cancellation policy text | Property detail page HTML | Hard |
| Dynamic surge pricing breakdown | Booking flow (requires session) | Hard |
the availability calendar is the highest-value field for competitive intelligence — it tells you occupancy rates indirectly when tracked over time. pulling it requires a separate GraphQL call per property ID. batch these: 50 concurrent async requests per residential IP pool is safe; beyond that you’ll see 429s with exponential backoff requirements.
for Southeast Asia inventory, you’ll often find Vrbo listings duplicated on regional OTAs. comparing coverage gaps between platforms is worth it — the approach for scraping Trip.com’s Asia inventory and Agoda hotel pricing follows a similar GraphQL interception pattern, so the same proxy and session management code generalizes.
Proxy and Rate Limit Strategy
Vrbo’s bot detection correlates IPs against Expedia Group’s shared blocklist, which includes any IP that’s triggered defenses on Hotels.com, Expedia, or Orbitz. datacenter proxies are effectively useless here. residential rotating proxies with sticky session support are the minimum viable option.
recommended setup:
- use residential proxies with city-level targeting matching your search destination (Miami proxies for Miami searches — it affects returned prices)
- set session stickiness to 10-15 minutes, matching a realistic browsing session length
- implement exponential backoff: start at 2s, double on each 429, cap at 60s
- rotate
x-page-idandx-vrbo-takeheaders to match organic browser behavior - log every 403/429 with the IP used so you can flag burnt proxies immediately
the same session-stickiness logic applies when scraping Kayak’s flight and hotel data, where Kayak’s Incapsula layer similarly correlates session behavior across requests.
Storage and Schema Design
for a production Vrbo scraper, structure your schema around property IDs as the primary key with a separate time-series table for price snapshots. a single property’s nightly rate can change 3-5x per week based on demand.
CREATE TABLE vrbo_listings (
property_id TEXT PRIMARY KEY,
title TEXT,
lat DOUBLE PRECISION,
lng DOUBLE PRECISION,
bedroom_count INT,
max_guests INT,
avg_rating NUMERIC(3,2),
review_count INT,
last_seen TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE vrbo_price_snapshots (
id BIGSERIAL PRIMARY KEY,
property_id TEXT REFERENCES vrbo_listings,
checkin DATE,
checkout DATE,
base_nightly NUMERIC(10,2),
total_fees NUMERIC(10,2),
scraped_at TIMESTAMPTZ DEFAULT now()
);index (property_id, checkin, scraped_at) for time-series queries. if you’re tracking hundreds of thousands of properties, partition vrbo_price_snapshots by month — otherwise query times degrade fast. for structured data extraction pipelines at scale, the same data modeling discipline covered in ZoomInfo public data extraction applies: separate the identity record from the mutable signal data.
Handling CAPTCHAs and Block Responses
Vrbo serves three distinct block types, each requiring a different response:
- Silent 200 with empty results: Akamai flagged the session but didn’t hard-block. rotate IP and session cookies, re-run the request.
- 302 redirect to
/security/check: a CAPTCHA challenge. solver services (2captcha, CapSolver) handle these but add 5-15 seconds per occurrence. reduce frequency by improving session realism. - 403 with
x-cache: Error from cloudfront: CDN-level block on the IP. retire that IP entirely, it’s in the blocklist.
track block rates per proxy provider and per target URL pattern separately. search endpoint blocks are more common than property detail blocks — adjust your proxy allocation accordingly.
Bottom Line
scraping Vrbo in 2026 is feasible with residential proxies, GraphQL interception, and proper session management, but it requires more infrastructure than a simple requests-based scraper. prioritize the SearchListings and PropertyAvailability GraphQL endpoints for efficiency, use city-matched proxies to get accurate pricing, and track price snapshots in a time-series schema from day one. dataresearchtools.com covers this class of travel data infrastructure in depth, including platform-specific quirks that generic scraping guides miss.