Documentation
Airbnb Vrbo CLI
airbnb-pp-cli
Install
npx -y @mvanhorn/printing-press-library install airbnbInstalls the CLI binary and the agent skill for Claude Code, Codex, Cursor, Gemini CLI, Copilot, and more. Add --cli-only or --skill-only for one half. Requires Node.
Documentation
Skip the Airbnb platform fee. Find the host's direct booking site for any Airbnb listing.
Search Airbnb from the terminal, run cheapest on a listing to extract the host's brand, web-search for their direct booking site, and report the lowest of three prices side-by-side. Cross-platform match, price-drop watchlist, host portfolio analysis, and trip planning all built on a local store that compounds over time. Every scrape persists: airbnb_listing search/get, cheapest, compare, plan, and watch check write the listings they fetch into the local SQLite store, and record a dated price snapshot whenever a real price is scraped — so price history and wishlist diff accrue from normal use.
VRBO is currently disabled. VRBO's anti-bot protection (Akamai) blocks the scraper, and the previous fallback path returned hardcoded placeholder data with the queried city stamped on top — fake results labeled as if they were real. Every VRBO entry point now returns "vrbo is temporarily disabled — pending Akamai workaround". The VRBO source code stays in tree so re-enabling is a flag flip plus the Akamai workaround. Use this CLI for Airbnb work; expect VRBO to come back in a future release.
Renamed from
airbnb-vrbo-pp-clitoairbnb-pp-cli. Existing users get an automatic one-time state migration on first run (the~/.airbnb-vrbo-pp-clidirectory is renamed in place to~/.airbnb-pp-cli; the same applies to the SQLite cache under~/.local/share).AIRBNB_VRBO_*env vars are still read but emit a deprecation warning; switch toAIRBNB_PP_*. The legacy paths will be dropped in a future release.
Created by @mvanhorn (Matt Van Horn). Contributors: @tmchow (Trevin Chow), @bobeglz (bobe).
Authentication
Public search and listing detail need no auth. Authenticated features (Airbnb wishlists, trip history) use cookie import via auth login --chrome. The web-search backend is pluggable: Parallel.ai (paid, best), DuckDuckGo HTML (free default), Brave Search API (free tier), or Tavily (free tier).
Quick Start
# Verify reachability and which search backend is active.
airbnb-pp-cli doctor
# Find listings on Airbnb.
airbnb-pp-cli airbnb search 'Lake Tahoe' --checkin 2026-05-16 --checkout 2026-05-19 --guests 4
# Same query, VRBO side.
airbnb-pp-cli vrbo search 'Lake Tahoe' --checkin 2026-05-16 --checkout 2026-05-19 --guests 4
# The headline command. Find the host's direct booking site and the cheapest of three sources.
airbnb-pp-cli cheapest 'https://www.airbnb.com/rooms/37124493?check_in=2026-05-16&check_out=2026-05-19'
# One call: search both platforms, find direct sites, return ranked-by-savings list.
airbnb-pp-cli plan 'Lake Tahoe' --checkin 2026-05-16 --checkout 2026-05-19 --guests 4 --budget 1500
Unique Features
These capabilities aren't available in any other tool for this API.
Host-direct arbitrage
-
cheapest— Given an Airbnb or VRBO listing URL, find the host's direct booking site and report the cheapest of three sources.When a user names an Airbnb/VRBO listing, this is the right tool to reach for. Returns a structured comparison of OTA fees vs direct booking with actionable URLs.
airbnb-pp-cli cheapest 'https://www.airbnb.com/rooms/37124493?check_in=2026-05-16&check_out=2026-05-19' --agent -
plan— Search Airbnb and VRBO in parallel for a city/dates/budget, then run cheapest on the top results, return a ranked-by-savings list.The agent-friendly trip planner. One call returns ranked results across both platforms with direct-booking URLs and savings amounts.
airbnb-pp-cli plan 'Lake Tahoe' --checkin 2026-05-16 --checkout 2026-05-19 --guests 4 --budget 1500 --agent -
compare— Side-by-side: OTA total (with cleaning + service + tax fees) vs direct booking total, with dollar and percent savings.Use when an agent needs to justify a booking recommendation with concrete savings numbers.
airbnb-pp-cli compare 'https://www.airbnb.com/rooms/37124493' --checkin 2026-05-16 --checkout 2026-05-19 --json -
find-twin— Reverse image search a listing's photos to find the same property on direct booking sites or alternate platforms.When host extraction fails (vague host name), reverse image search is the most reliable signal.
airbnb-pp-cli find-twin 'https://www.airbnb.com/rooms/37124493' --json
Cross-platform
-
match— Given a listing on Airbnb (or VRBO), find the same property on the other platform via geocode + amenities + photo signal.Cross-platform price discrimination is real; the same condo can cost 15 percent less on VRBO. This finds it.
airbnb-pp-cli match 'https://www.airbnb.com/rooms/37124493' --json
Local state that compounds
-
watch— Add saved listings to a watchlist with target prices;watch checkre-scrapes each and records a dated price snapshot whenever a real price comes back; cron-friendly exit code 7 signals a genuine drop.Use when a user is shopping a specific listing and waiting for a price drop. Schedule
watch checkdaily; act on exit code 7. A listing whose price is unavailable for the chosen dates is reported underno_priceand never counts as a hit (no false exit 7). Subcommands:watch add,watch list,watch remove,watch check.airbnb-pp-cli watch add 'https://www.airbnb.com/rooms/37124493' --max-price 350 --checkin 2026-05-16 --checkout 2026-05-19 airbnb-pp-cli watch remove 'https://www.airbnb.com/rooms/37124493' # or: watch remove 37124493 -
host portfolio— Given a host or property management company name, list every known listing under them across Airbnb and VRBO.Discover bulk patterns: which PMCs operate in this city, which have direct sites, where to focus arbitrage.
airbnb-pp-cli host portfolio 'Vacasa' --json --select listings.title,listings.location -
wishlist diff— Track price changes on Airbnb wishlists over time; report which saved listings dropped, by how much, and over what window.User saved a listing months ago and forgot. This surfaces price movement so they can act before booking.
airbnb-pp-cli wishlist diff --since 2026-04-01 --json -
fingerprint— Stable hash from photos + amenities + host + city; used by match for dedupe; exposed for power-user export workflows.Build your own external joins on listings; stable across sessions.
airbnb-pp-cli fingerprint 'https://www.airbnb.com/rooms/37124493'
Usage
Run airbnb-pp-cli --help for the full command reference and flag list.
Commands
airbnb_listing
Airbnb listings (search and detail) via SSR HTML scrape (openbnb pattern, no auth required).
airbnb-pp-cli airbnb_listing get- Get full Airbnb listing detail (amenities, house rules, location, highlights, description, policies, host) via SSR HTML scrape.airbnb-pp-cli airbnb_listing search- Search Airbnb listings by location, dates, and guest count via the public SSR HTML page (openbnb pattern). Walks niobeClientData[0][1] Apollo cache to extract structured results.
airbnb_wishlist
Airbnb wishlists (read user's saved listings; requires auth login --chrome).
airbnb-pp-cli airbnb_wishlist items- Get items in a specific wishlist by listing IDs.airbnb-pp-cli airbnb_wishlist list- List the user's wishlists via Airbnb's GraphQL persisted query.
host
Host identity extraction (the linchpin of host-direct arbitrage).
airbnb-pp-cli host extract- Extract the host's brand or display name from a listing URL across both platforms. Uses propertyManagement.name (PMC) > host.displayName > description bio > photo signal.airbnb-pp-cli host portfolio- List every known listing under one host or PMC across Airbnb and VRBO from the local store.
vrbo_listing
VRBO listings (search and detail) via /graphql with Akamai warmup pattern.
airbnb-pp-cli vrbo_listing get- Get full VRBO property detail via the propertyDetail GraphQL operation (operation name discovered at runtime). Falls back to PLUGIN_STATE SSR scrape for basic fields.airbnb-pp-cli vrbo_listing search- Search VRBO properties via the propertySearch GraphQL operation. Uses Akamai warmup (GET / first, wait 1.5s, then POST).
Output Formats
# Human-readable table (default in terminal, JSON when piped)
airbnb-pp-cli airbnb_listing get
# JSON for scripting and agents
airbnb-pp-cli airbnb_listing get --json
# Filter to specific fields
airbnb-pp-cli airbnb_listing get --json --select id,name,status
# Dry run — show the request without sending
airbnb-pp-cli airbnb_listing get --dry-run
# Agent mode — JSON + compact + no prompts in one flag
airbnb-pp-cli airbnb_listing get --agent
Agent Usage
This CLI is designed for AI agent consumption:
- Non-interactive - never prompts, every input is a flag
- Pipeable -
--jsonoutput to stdout, errors to stderr - Filterable -
--select id,namereturns only fields you need - Previewable -
--dry-runshows the request without sending - Read-only by default - this CLI does not create, update, delete, publish, send, or mutate remote resources
- Offline-friendly - the
searchcommand andhost portfolio/wishlist diffread from the local SQLite store;syncrefreshes it by re-scraping what the store already knows - Agent-safe by default - no colors or formatting unless
--human-friendlyis set
Exit codes: 0 success, 2 usage error, 3 not found, 4 auth error, 5 API error, 7 rate limited, 10 config error.
Sync
Airbnb has no public paginated collection to mirror, so sync does not page a remote API. Instead, sync (with no --resources) re-scrapes what the store already knows — every watchlist entry (with its saved dates) and every previously-scraped listing — and persists a fresh dated price snapshot whenever a real price comes back. Seed the store first via watch add, airbnb_listing search/get, or cheapest; then schedule sync to keep price history current. When the store is empty, sync says so honestly (a sync_warning with reason empty_store) and makes no network calls.
The authenticated Airbnb wishlist sync is a separate, opt-in resource — it requires imported Chrome cookies and is never part of the default run:
airbnb-pp-cli auth login --chrome # one-time: import cookies
airbnb-pp-cli sync --resources airbnb_wishlist # auth-gated; without cookies this is an auth error, not a 404
The standalone wishlist sync command remains the other auth-gated path to pull wishlists; wishlist diff reports the price movement those snapshots accumulate.
Freshness
This CLI owns bounded freshness for registered store-backed read command paths. In --data-source auto mode, covered commands check the local SQLite store before serving results; stale or missing resources trigger a bounded refresh, and refresh failures fall back to the existing local data with a warning. --data-source local never refreshes, and --data-source live reads the API without mutating the local store.
Set AIRBNB_PP_NO_AUTO_REFRESH=1 to disable the pre-read freshness hook while preserving the selected data source.
Covered command paths:
airbnb-pp-cli airbnb_wishlistairbnb-pp-cli airbnb_wishlist itemsairbnb-pp-cli airbnb_wishlist list
JSON outputs that use the generated provenance envelope include freshness metadata at meta.freshness. This metadata describes the freshness decision for the covered command path; it does not claim full historical backfill or API-specific enrichment.
Health Check
airbnb-pp-cli doctor
Verifies configuration, credentials, and connectivity to the API.
Configuration
Config file: ~/.config/airbnb-pp-cli/config.toml
Troubleshooting
Authentication errors (exit code 4)
- Run
airbnb-pp-cli doctorto check credentials Not found errors (exit code 3) - Check the resource ID is correct
- Run the
listcommand to see available items
API-specific
- VRBO returns 'Bot or Not?' challenge — The CLI uses Surf with Chrome TLS impersonation and a warmup pattern by default. If you still see challenges: run airbnb-pp-cli doctor --probe vrbo to verify the warmup is firing; reduce request rate with --rate 0.3 (req/sec).
- cheapest returns 'no direct site found' — Try --search-backend parallel or --search-backend brave for higher-quality results; ensure PARALLEL_API_KEY or BRAVE_SEARCH_API_KEY is set in env.
- Airbnb wishlist commands fail with auth error — Run airbnb-pp-cli auth login --chrome to import your Chrome cookies; airbnb-pp-cli auth status verifies.
- watch check exits with code 7 — Code 7 means at least one watched listing scraped a real price at or below its threshold — that is the success path. It fires only on a genuine price drop. A listing whose price is unavailable for the chosen dates is reported under
no_price(reasonno_price_data) and never triggers exit 7. Check hits with airbnb-pp-cli watch list --since 24h.
Discovery Signals
This CLI was generated with browser-captured traffic analysis.
- Target observed: https://a0.muscache.com/airbnb/static/packages/web/en/e67b.b1e4978dd5.js
- Capture coverage: 66 API entries from 299 total network entries
- Reachability: standard_http (65% confidence)
- Protocols: rpc_envelope (80% confidence), rest_json (75% confidence)
- Auth signals: api_key — headers: X-Airbnb-API-Key, X-Goog-Api-Key
- Generation hints: has_rpc_envelope, weak_schema_confidence
- Candidate command ideas: create_GetViewportInfo — Derived from observed POST /$rpc/google.internal.maps.mapsjs.v1.MapsJsInternalService/GetViewportInfo traffic.; create_StaysPdpSections — Derived from observed POST /api/v3/StaysPdpSections/{hash} traffic.; create_get_data_layer_variables — Derived from observed POST /api/v2/get-data-layer-variables traffic.; create_js — Derived from observed POST /js/ traffic.; create_marketing_event_tracking — Derived from observed POST /api/v2/marketing_event_tracking traffic.; create_messages — Derived from observed POST /tracking/jitney/logging/messages traffic.; create_realtimeconversion — Derived from observed POST /track/realtimeconversion traffic.; get_GetConsentFlagsQuery — Derived from observed GET /api/v3/GetConsentFlagsQuery/{hash} traffic.
Warnings from discovery:
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
- empty_payload: API-looking request returned an empty or null payload; schema confidence is weak.
Sources & Inspiration
This CLI was built by studying these projects and resources:
- openbnb-org/mcp-server-airbnb — TypeScript (443 stars)
- Apify ecomscrape/vrbo-property-search-scraper — JavaScript
- Apify easyapi/vrbo-property-listing-scraper — JavaScript
- Apify jupri/vrbo-property — JavaScript
- markswendsen-code/mcp-vrbo — TypeScript
- vedantparmar12/airbnb-mcp — TypeScript
- Edioff/vrbo-scraper — Python
- Stevesie VRBO API — Documentation
Generated by CLI Printing Press
For agents: pass /documentation/airbnb/agents.md to install this CLI from a prompt.