Airbnb Scraper: Listings, Prices & Availability by Location
Pricing
Pay per event
Airbnb Scraper: Listings, Prices & Availability by Location
Export Airbnb listings for any city or search URL with prices, ratings, reviews, rooms and coordinates; add dates for real stay prices and availability, or listing URLs for host, amenities and rules. $3 per 1,000 listings, plus $2 per 1,000 with details; no login.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Changefeeds Tools
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
- What you get: one row per Airbnb listing for a city or a pasted airbnb.com search URL: name, price and its breakdown, rating, reviews, bedrooms, beds, coordinates and badges.
- Add dates for real stay prices and availability, or pass listing URLs for full details: description, amenities, house rules, host and sub-ratings. No Airbnb account or login.
- Price: $3 per 1,000 listings, or $5 per 1,000 with details. Proxy included; failed inputs are free.
Sample output
The prefilled input (Lisbon, Portugal, 10 listings, no dates), run on
2026-10-23. First five rows:
| name | area | rating (reviews) | bedrooms / beds | price | dates Airbnb priced |
|---|---|---|---|---|---|
| Liberdade Boutique @ Chic Condo/ Parking/Lift/AC T | Santo António | 4.98 (49) | 1 / 1 | $862 USD total | 2026-11-22 to 11-27 |
| Chiado Trindade 19 Apartments - 2A Castelão | Santa Maria Maior | 4.95 (187) | 1 / 2 | $870 USD total, originally $1,002 USD | 2026-11-09 to 11-14 |
| CityLux 1 bedroom Fast Internet with Lift/Elevator | Santa Maria Maior | 4.93 (223) | 1 / 2 | $788 USD total | 2026-11-02 to 11-07 |
| Boutique Apartment in Cais do Sodré • Time Out | São Paulo | new (0) | 1 / 2 | $915 USD total | 2026-11-04 to 11-09 |
| Time Out Market - AC - Elevator | São Paulo | 4.87 (491) | 1 / 2 | $625 USD total | 2026-12-01 to 12-06 |
The fifth row in full (images cut to one):
{"type": "listing","id": "26302507","url": "https://www.airbnb.com/rooms/26302507?check_in=2026-12-01&check_out=2026-12-06&adults=2","name": "Time Out Market - AC - Elevator","title": "Apartment in São Paulo","subtitle": "Time Out Market - AC - Elevator","roomType": null,"propertyType": "Apartment","area": "São Paulo","city": null,"lat": 38.70682,"lng": -9.14765,"rating": 4.87,"reviewsCount": 491,"isNew": false,"isSuperhost": null,"guestFavorite": true,"price": {"amount": 625,"currency": "USD","qualifier": "total","nights": null,"originalAmount": null,"label": "$625 USD total","checkIn": "2026-12-01","checkOut": "2026-12-06","datesChosenByAirbnb": true,"breakdown": [{ "description": "5 nights x $115.91 USD", "amount": 579.57, "text": "$579.57 USD" },{ "description": "Taxes", "amount": 44.88, "text": "$44.88 USD" },{ "description": "Total", "amount": 624.45, "text": "$624.45 USD" }],"notes": []},"available": null,"unavailableReason": null,"priceError": null,"images": ["https://a0.muscache.com/im/pictures/7e8f1a7a-2c4e-4060-9ddb-1cb10552b5ee.jpg"],"badges": ["Guest favorite"],"paymentMessages": [],"bedrooms": 1,"beds": 2,"bathrooms": 1,"guests": null,"propertyId": null,"searchInput": "Lisbon, Portugal","position": 5,"hasDetails": false,"detailsError": null,"description": null,"amenities": null,"houseRules": null,"highlights": null,"host": null,"subRatings": null,"scrapedAt": "2026-10-23T03:56:55.264Z"}
area is Airbnb's own neighbourhood label (São Paulo is a former parish of central
Lisbon, around Cais do Sodré). price.amount is the rounded figure from the search card; breakdown
carries Airbnb's exact lines, and nights stays null when the card's label does
not state it.
With includeDetails on, or for any listingUrls row, the same row also
carries the listing page's fields (from a live run on 2026-09-30, shortened):
{"roomType": "Entire home/apt","propertyType": "Entire rental unit","city": "Porto","isSuperhost": true,"guests": 2,"hasDetails": true,"description": "Beautiful studio apartment set in a fully renovated 18th-century building, with air conditioning for heating and cooling…","amenities": ["River view", "Garden view", "Hair dryer", "Shampoo", "…38 in total"],"houseRules": ["Check-in: 3:00 PM - 12:00 AM", "Checkout before 11:00 AM", "Self check-in with keypad", "2 guests maximum", "No pets"],"highlights": ["Top 10% of homes", "Self check-in", "Vibrant neighborhood"],"host": { "id": "245989121", "name": "Isabel & Igor", "isSuperhost": true, "isVerified": true, "rating": 4.9, "reviewsCount": 4616, "yearsHosting": 7, "responseRate": "Response rate: 100%", "responseTime": "Responds within an hour" },"subRatings": { "accuracy": 4.93, "checkIn": 4.97, "cleanliness": 4.91, "communication": 4.98, "location": 4.95, "value": 4.89 }}
How to run in 30 seconds
- Click Try for free. The input already holds
Lisbon, Portugaland 10 listings. - Click Start. Our test run of that input took 17 seconds and cost $0.03 (10 listings).
- Open the Output tab, or export the dataset as CSV, JSON or Excel.
For your own search, replace the place name, or paste a search URL copied from airbnb.com (its filters are kept). Add Check-in and Check-out dates for prices you can compare, and raise Max listings per location (up to 270).
Pricing
- $0.003 per listing row (
listing-returned), $3 per 1,000. - $0.002 extra per listing with details (
details-added): search results withincludeDetailson, and everylistingUrlsrow, since those always come from the listing page. So $5 per 1,000 with details. A search row whose listing page could not be read is delivered withdetailsErrorand charged as a plain listing. - Proxy traffic is included. Failed inputs (
not_found,invalid,blocked,error) are free. - If you set a maximum total charge, the actor checks the remaining budget
before each page, stops cleanly once it is reached, and records
"max_total_charge_reached"inOUTPUT.stopped_reason.
FAQ
Do I need an Airbnb account? No. Only public, logged-out pages.
Can I use my own search with filters? Yes. Set up the search on airbnb.com (any country domain), copy the URL from the address bar and put it in Locations or search URLs. Its filters are kept; your dates, guests, currency and price fields are added only where the URL does not already set them.
Why are the dates different on every row? You gave no dates, so Airbnb
priced each result for its own sample stay. The row says so with
price.datesChosenByAirbnb: true. Give dates for comparable prices.
Why fewer listings than "Over 1,000 homes"? Airbnb shows at most 15 pages per search (see Limits). Split the search into price bands.
Why is price null? On a listing URL without dates, Airbnb shows no price.
With dates, the listing may be unavailable for them (see available and
unavailableReason), or the booking-box call failed (priceError).
Limits
- Airbnb shows at most 15 pages of 18 results per search, and the pages
overlap. A live 15-page run for "Lisbon, Portugal" returned 242 unique
listings, although Airbnb says "Over 1,000 homes". Such a search is marked
truncatedand listed inOUTPUT.truncated_inputs. To get more, run the same place in price bands (minPrice/maxPrice, e.g. 0-80, 80-150, 150-300, 300+), by neighbourhood, or with smaller map-area search URLs.maxItemsis capped at 270 for this reason. - Prices are what the card or booking box shows, in the format Airbnb uses
for your currency and region; depending on the region that may be before
taxes.
price.breakdownandprice.notescarry Airbnb's own lines. Hotels can show "Price may vary by room type". isSuperhostisnullon plain search rows unless the card shows a Superhost badge; search cards do not say when a host is not one. The listing page (includeDetails) gives the real value.- Listing URLs get a price only with dates. With dates, the actor makes one
more request for the booking box; if that fails, the row still arrives with
priceError. - Search results include what Airbnb puts in them, such as "Featured hotel"
placements (
badges,propertyIdset). - Not supported: vanity
/h/...links (use the/rooms/<id>URL), experiences, review text, calendars beyond the dates you give, and anything that needs a login. The actor never solves CAPTCHAs; a challenged request is retried from a new proxy IP up to 8 times, then reported as a freeblockedrow. - It stays polite: search pages one at a time, at most 2 listing pages in flight, at least 500 ms between requests, 20 s timeouts, HTTP 429/5xx retried with backoff (up to 3 retries, Retry-After honoured up to 60 s).
- Airbnb changes its site. The actor reads the data embedded in Airbnb's
pages and finds the booking-box query id in Airbnb's current JavaScript at run
time. A layout change can still break a field until the actor is updated; a
page without the expected data becomes an
errorrow, never a silently empty result.
Input reference
| Field | Type | Default | What it does |
|---|---|---|---|
locations | list of strings | A place name per line ("Lisbon, Portugal"), or a full airbnb.com/s/... search URL copied from your browser. A pasted URL is used as-is, with all its filters (room type, amenities, map area). | |
listingUrls | list of strings | airbnb.com/rooms/<id> URLs (any Airbnb country domain) or bare numeric ids. One detail row each. | |
checkIn / checkOut | YYYY-MM-DD | none | Optional; give both or neither. With dates, search prices are for your stay and listing URLs also get a price and availability. |
adults | integer 1-16 | 2 | Guests. Changes which listings show and their prices. |
currency | 3-letter code | USD | EUR, GBP, JPY, ... A pasted search URL that already has currency= keeps its own. |
minPrice / maxPrice | integer | none | Airbnb's own per-night price filter, in currency. Searches only. |
maxItems | integer 1-270 | 100 | Max listings per location. |
includeDetails | boolean | false | Also open each search result's listing page and add the detail fields (one extra page per listing; see Pricing). |
proxy | proxy settings | Apify Proxy, residential | Airbnb blocks many datacenter IPs, so requests go through residential proxy by default. |
Priced for your dates, with details:
{ "locations": ["Porto, Portugal"], "checkIn": "2026-11-20", "checkOut": "2026-11-23", "currency": "EUR", "minPrice": 60, "maxPrice": 150, "includeDetails": true, "maxItems": 50 }
Specific listings, with availability:
{ "listingUrls": ["https://www.airbnb.com/rooms/12537150", "1144816383633864634"], "checkIn": "2026-11-28", "checkOut": "2026-12-03" }
Output reference
A listing URL with dates it is booked for comes back as
"available": false, "unavailableReason": "Those dates are not available", "price": null.
With dates it is free for, price holds the booking-box total, with
"available": true.
A failed input gets a free status row instead:
{ "type": "status", "input": "https://www.airbnb.com/rooms/1", "source": "listingUrls", "status": "not_found", "error": "Listing 1 not found (removed, unlisted, or never existed).", "checkedAt": "2026-09-30T05:37:53.680Z" }
not_found: the listing is gone, or Airbnb did not recognise the place name (it fell back to a generic map area).invalid: not a place, search URL, listing URL or id (a/rooms/URL put inlocationsis pointed atlistingUrls), or a duplicate listing.blocked: Airbnb's bot protection refused the request from every proxy IP tried.error: any other HTTP or network failure.
The key-value store record OUTPUT holds a run summary: counts by type,
charged_events, stopped_reason, truncated_inputs, and per location the
search URL used, Airbnb's own heading ("Over 1,000 homes in Lisbon"), pages
fetched and why it stopped. Every run leaves at least one dataset row, so a
quiet run is never mistaken for a broken one.