Airbnb Availability & Rate Scraper
Pricing
$19.99/month + usage
Airbnb Availability & Rate Scraper
Monitor Airbnb occupancy and availability across listings or cities. Retrieve booked nights, seasonal trends, and pricing signals. Designed for researchers, investors, and revenue teams needing trusted data.
Pricing
$19.99/month + usage
Rating
0.0
(0)
Developer
SimpleAPI
Maintained by CommunityActor stats
0
Bookmarked
12
Total users
0
Monthly active users
12 days ago
Last modified
Categories
Share
๐ Airbnb Availability & Rate Scraper
Scrape the forward-looking availability calendar of Airbnb listings and the real per-day fields Airbnb's own calendar returns โ check-in / check-out eligibility, the bookable flag, minimum / maximum nights, and the nightly price when it is present. From those real values it derives an honest unavailableRate and, only from real calendar prices, ADR / estimated revenue / RevPAR.
This actor is deliberately honest about what the data is and is not. Read the two notes below before using it.
โ ๏ธ Honesty notes (read these)
- This is availability, not occupancy. Airbnb's calendar tells you whether a night is available. An unavailable night can be either genuinely booked or blocked by the host โ the public calendar cannot distinguish the two. We therefore report
unavailableRate= unavailable days รท counted days, clearly labeled "includes host-blocked days; not a booking/occupancy rate." We never call unavailable nights "booked" and never emit an "occupancy rate." - Money fields come only from real prices.
adr,estimatedRevenueandrevparare computed exclusively from nightly prices that appear in the calendar payload. When a listing exposes no calendar prices, these fields arenullโ never a regional average, a search-page price, or an interpolated guess.estimatedRevenue/revparadditionally assume every unavailable night is a paid booking, which is an upper bound (it includes host-blocked nights); they are labeled as such. - Forward-only.
PdpAvailabilityCalendarreturns future availability. Past dates are clamped to today. There is no historical calendar available from this endpoint.
How it works
- curl_cffi Chrome TLS impersonation. Airbnb sits behind Akamai / PerimeterX. Plain
requests/aiohttpare blocked at the TLS (JA3) layer before reaching the app. This actor usescurl_cffiwithimpersonate="chrome"so requests replay a real Chrome handshake. - Soft-block guard + proxy escalation. An airlock / challenge / empty shell is detected and reported as a block (the run keys on the presence of the expected bootstrap container, not on loose tokens), and the actor retries on a fresh residential proxy IP.
- Dynamic persisted-query discovery. The GraphQL persisted-query hash is found by scanning the room page and its JS bundles for the hash next to
PdpAvailabilityCalendarโ no hardcoded bundle name that breaks on every Airbnb deploy. - Harvest + derive. Every already-in-payload day field is emitted; derived metrics are computed with the honesty rules above.
Input
| Field | Type | Notes |
|---|---|---|
listings | array (required) | Room URLs or bare IDs, one per line. |
startDate | date | Absolute (2026-08-01) or relative (7 days, 1 month). Empty = today. Past โ clamped to today. |
endDate | date | Absolute or relative. Empty = start + 30 days. Up to ~12 months ahead. |
billingMode | enum | per_listing (default, 1 charge/listing) or per_day. |
includeDays | boolean | Emit per-day child rows (default true). |
includeListingDetails | boolean | Best-effort title/type/capacity/beds/baths/coords (default false). |
includeHostProfile | boolean | Best-effort superhost/name/response rate (default false). |
proxyConfiguration | proxy | Default residential (recommended; datacenter is usually blocked). |
{"listings": ["https://www.airbnb.com/rooms/35329051"],"startDate": "2026-08-01","endDate": "2026-10-31","billingMode": "per_listing","includeDays": true,"proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }}
Output
Two row types share the dataset and are distinguished by type / isChild.
Parent โ type: "listing" (one per target):
{"type": "listing", "isChild": false,"roomId": "35329051", "listingUrl": "https://www.airbnb.com/rooms/35329051","windowStart": "2026-08-01", "windowEnd": "2026-10-31","totalDays": 92, "availableDays": 40, "unavailableDays": 52,"unavailableRate": 0.5652,"adr": 128.5, "priceCoverage": "40/92", "pricedDays": 40,"estimatedRevenue": 6682.0, "revpar": 72.63,"minPrice": 110.0, "maxPrice": 210.0,"currency": "USD", "scrapedAt": "2026-07-03T12:00:00Z"}
Child โ type: "day" (one per calendar day, mirrored to a per-run days-<runId> dataset):
{"type": "day", "isChild": true, "parentId": "35329051", "roomId": "35329051","date": "2026-08-01", "dayOfWeek": "Saturday", "isWeekend": true,"available": false, "availableForCheckin": false, "availableForCheckout": true,"bookable": false, "minNights": 2, "maxNights": 365,"price": null, "currency": null, "scrapedAt": "2026-07-03T12:00:00Z"}
price is a real number or null (never 0). unavailableRate, adr, estimatedRevenue, revpar are null when the underlying data is absent.
Billing
Pay-per-event. per_listing (default) charges one listing_result per listing. per_day charges one day_result per calendar-day row (~30 for a month, ~365 for a year). Day rows are always produced; billingMode only controls what is billed. See .actor/pay_per_event.json.
Keywords
airbnb scraper, airbnb availability, airbnb calendar, airbnb rates, nightly price, adr, revpar, short-term rental data, str analytics, vacation rental availability, airbnb api, booking calendar, occupancy alternative, curl_cffi, akamai bypass.
Compliance
Only publicly visible calendar data is accessed. Ensure your use complies with Airbnb's Terms of Service and applicable law.
