Airbnb Listings Scraper avatar

Airbnb Listings Scraper

Pricing

from $2.98 / 1,000 results

Go to Apify Store
Airbnb Listings Scraper

Airbnb Listings Scraper

Scrape Airbnb listings and return structured data including listing names, nightly rates, stay totals, ratings, bedroom and bathroom details, badges, coordinates and photos. Add guest and date filters, search locations or map areas, and optionally retrieve public host details from listing pages.

Pricing

from $2.98 / 1,000 results

Rating

0.0

(0)

Developer

Axiom Works

Axiom Works

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 days ago

Last modified

Categories

Share

Returns: one row per Airbnb listing with name, title, pricePerNight, totalPrice, rating, reviewCount, bedrooms, hostName, latitude, longitude and photos. Input: {"locations": ["Lisbon, Portugal"], "adults": 2, "maxItems": 50} Best for: short-term rental market research, competitor price monitoring, travel and investment lead lists.

{
"id": "32422325",
"sourceUrl": "https://www.airbnb.com/rooms/32422325",
"name": "Brand new apartment right in the heart of Alfama.",
"title": "Apartment in Santa Maria Maior",
"pricePerNight": 124.95,
"rating": 4.82,
"reviewCount": 478,
"hostName": "BB Lisbon"
}

What does Airbnb Listings Scraper do?

Airbnb Listings Scraper is an Airbnb scraper and unofficial Airbnb API for search results. You give it one or more places (for example "Lisbon, Portugal" or "Austin, TX"), optional check-in and check-out dates, the number of guests and a price range. It returns the listings Airbnb shows for that search as clean, structured rows that you can export to JSON, CSV, Excel or HTML, or read through the Apify API.

For every listing you get the host's listing name, the card title (property type and area), the nightly rate, the stay total, any strikethrough original price, the average rating and review count, bedrooms, beds and bathrooms, the host type, coordinates and a list of photo URLs. With host details switched on, the scraper also opens each listing page to add the public host name, host id, Superhost and verified flags, guest capacity, room type and the six rating sub-scores.

You can search by place name, paste full Airbnb search URLs (including map-area URLs with bounding-box coordinates), or paste a single listing URL. The scraper works without an Airbnb account and without logging in. It only reads public pages that anyone can open in a browser.

This tool is an independent project. It is not affiliated with, endorsed by or connected to Airbnb.

What data can you get?

Each dataset row describes one listing. Fields that Airbnb does not show for a listing are returned as null.

FieldTypeDescription
idstringAirbnb numeric listing id, unique within a run
sourceUrlstringLink to the listing page
namestringListing name chosen by the host
titlestringCard title, property type and area
pricePerNightnumberNightly rate in the chosen currency
totalPricenumberStay total for the nights shown
originalTotalPricenumberTotal before discount, when Airbnb shows a strikethrough price
nightsintegerNumber of nights the price is quoted for
currencystringCurrency code of all prices
priceLabelstringRaw price text from the card
ratingnumberAverage guest rating out of 5
reviewCountintegerNumber of guest reviews
bedroomsintegerBedrooms, 0 for studios
bedsintegerNumber of beds
bathroomsnumberBathrooms, 0.5 for a half bath
bathroomLabelstringRaw bathroom text
hostTypestringBusiness host or Individual host
hostNamestringPublic host name (host details on)
hostIdstringAirbnb host id (host details on)
hostIsSuperhostbooleanSuperhost flag (host details on)
hostIsVerifiedbooleanVerified host flag (host details on)
hostPhotostringHost profile picture URL (host details on)
personCapacityintegerMaximum guests (host details on)
roomTypestringRoom type such as Entire home/apt (host details on)
descriptionstringFull listing description as plain text (host details on)
amenitiesarrayAmenities the listing offers, such as Wifi or Kitchen (host details on)
checkInTimestringHouse-rule check-in window (host details on)
checkOutTimestringHouse-rule check-out time (host details on)
subRatingsobjectAccuracy, checkin, cleanliness, communication, location and value scores (host details on)
badgesarrayCard badges such as Guest favorite
latitudenumberApproximate latitude of the listing pin
longitudenumberApproximate longitude of the listing pin
photosarrayUp to 8 listing photo URLs
thumbnailstringFirst photo URL
searchLocationstringThe location or URL that produced the row
positionintegerRank of the listing within its search
checkInstringRequested check-in date, null when Airbnb default dates were used
checkOutstringRequested check-out date, null when Airbnb default dates were used
scrapedAtstringISO timestamp of extraction

Some notes on how the values behave:

  • Prices depend on the dates, currency and number of guests you choose. When you give no dates, Airbnb quotes its own default stay, and nights tells you how many nights that is.
  • pricePerNight is the nightly rate Airbnb shows in the price breakdown. Taxes and fees are part of totalPrice where Airbnb includes them.
  • Coordinates are the obfuscated pin Airbnb publishes, accurate to roughly a hundred metres, not an exact address.
  • Hotels and some room types have no bedroom line on the card, so bedrooms can be null.
  • New listings without reviews have a null rating.

How to use

  1. Open the Actor in Apify Console and go to the Input tab.
  2. Enter one or more places in Locations, for example Lisbon, Portugal. You can add several; results are merged and de-duplicated by listing id.
  3. Optionally set check-in and check-out dates, adults, children, infants and pets. Dates must be in the future and use the format YYYY-MM-DD.
  4. Optionally set a minimum and maximum nightly price and a currency.
  5. Choose Max listings. The limit counts all locations together.
  6. Leave Include host details on if you need host names and sub-ratings. Switch it off for a faster run that makes one request per page of 18 listings instead of one per listing.
  7. Click Start. Results appear in the Output tab while the run is going.

Airbnb returns at most 270 listings per search (15 result pages of 18). For a large city, split the search into neighbourhoods ("Alfama, Lisbon") or use map-area URLs from the Airbnb website to cover the city in pieces. Each piece can return its own 270 listings.

If the place name is not recognised, Airbnb would normally show unrelated listings from around the world. The scraper detects this, skips that location, logs a warning and returns nothing for it, instead of filling your dataset with the wrong places. The run still ends successfully and the status message names the location that was not found.

Input

FieldTypeDescription
locationsarray of stringsPlaces to search, for example Lisbon, Portugal
startUrlsarrayAirbnb search URLs or single listing URLs
checkInstringCheck-in date, YYYY-MM-DD
checkOutstringCheck-out date, YYYY-MM-DD, after check-in
adultsintegerAdults, 1-16, default 2
childrenintegerChildren, 0-16, default 0
infantsintegerInfants, 0-5, default 0
petsintegerPets, 0-5, default 0
minPriceintegerMinimum nightly price in the chosen currency
maxPriceintegerMaximum nightly price in the chosen currency
currencystringUSD, EUR, GBP, CAD, AUD, JPY, CHF, MXN, BRL or INR
maxItemsintegerMaximum listings in total, 1-1000, default 50
includeHostDetailsbooleanOpen each listing page for host fields, default true
proxyConfigurationobjectApify Proxy settings

Example input:

{
"locations": ["Lisbon, Portugal", "Porto, Portugal"],
"checkIn": "2027-03-12",
"checkOut": "2027-03-15",
"adults": 2,
"currency": "EUR",
"minPrice": 50,
"maxPrice": 300,
"maxItems": 100,
"includeHostDetails": true,
"proxyConfiguration": { "useApifyProxy": true }
}

You can also pass full URLs:

{
"startUrls": [
{ "url": "https://www.airbnb.com/s/Barcelona--Spain/homes?adults=2" },
{ "url": "https://www.airbnb.com/rooms/32422325" }
],
"maxItems": 25
}

Search URLs keep the filters already in the link, and the Actor fills in anything missing from your input. A listing URL returns that one listing; its price fields are null because a listing page alone carries no quote for a stay.

Output

Results are stored in the default dataset. The Overview view shows photo, name, title, price per night, currency, rating, reviews, bedrooms, beds, bathrooms, host name, host type, coordinates and link. A real record from a test run:

{
"id": "32422325",
"sourceUrl": "https://www.airbnb.com/rooms/32422325",
"name": "Brand new apartment right in the heart of Alfama.",
"title": "Apartment in Santa Maria Maior",
"pricePerNight": 124.95,
"totalPrice": 401.88,
"originalTotalPrice": 470,
"nights": 3,
"currency": "USD",
"rating": 4.82,
"reviewCount": 478,
"bedrooms": 1,
"beds": 2,
"bathrooms": 1,
"bathroomLabel": "1 bath",
"hostType": "Business host",
"badges": [],
"hostName": "BB Lisbon",
"hostIsVerified": true,
"personCapacity": 4,
"roomType": "Entire home/apt",
"description": "<full plain-text description of the listing>",
"amenities": ["Wifi", "Kitchen", "Air conditioning"],
"checkInTime": "Check-in after 3:00 PM",
"checkOutTime": "Checkout before 12:00 PM",
"subRatings": {
"accuracy": 4.75,
"checkin": 4.73,
"cleanliness": 4.69,
"communication": 4.71,
"location": 4.62,
"value": 4.46
},
"latitude": 38.71167,
"longitude": -9.12559,
"thumbnail": "https://a0.muscache.com/im/pictures/7410b1e6-ec06-45c6-87ff-2346cea9fe5f.jpg",
"searchLocation": "Lisbon, Portugal",
"position": 2,
"checkIn": null,
"checkOut": null,
"scrapedAt": "2026-10-03T12:00:00.000Z"
}

Every run also writes a RUN_SUMMARY record to the key-value store with the number of listings, the locations that were not recognised and the final status message.

How much does it cost?

You are charged per result, which means per listing pushed to the dataset. The unit price is shown on the Pricing tab of this Actor, and Apify platform usage such as compute and proxy traffic is billed according to your plan. The number of results is capped by maxItems, so you can always limit what a run can spend by setting a lower value. Turning host details off reduces run time and platform usage.

Use with AI agents (MCP)

You can call this Actor from any MCP-compatible assistant through the Apify MCP server. Add this to your client configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=axiomworks/airbnb-listings-scraper"
}
}
}

Example prompts:

  • "Find 30 Airbnb listings in Lisbon for two adults and list name, price per night and rating."
  • "Scrape Airbnb stays in Austin, TX from 2027-03-12 to 2027-03-15 for four guests and show the five best rated."
  • "Compare the nightly price of Airbnb homes in Tulum and Hallstatt between 50 and 400."

The input field descriptions are written so that an agent can fill them in without further help.

Integrations and API

Run the Actor from code with the Apify client libraries or the REST API.

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("axiomworks/airbnb-listings-scraper").call(run_input={
"locations": ["Lisbon, Portugal"],
"adults": 2,
"maxItems": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["name"], item["pricePerNight"], item["currency"])

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('axiomworks/airbnb-listings-scraper').call({
locations: ['Lisbon, Portugal'],
adults: 2,
maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length);

cURL

curl -X POST "https://api.apify.com/v2/acts/axiomworks~airbnb-listings-scraper/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"locations": ["Lisbon, Portugal"], "adults": 2, "maxItems": 20}'

You can also connect the dataset to Google Sheets, Make, Zapier, n8n or a webhook, and schedule runs to track prices over time.

FAQ

How many listings can I get per search? Airbnb shows up to 270 listings per search. To go beyond that, run several narrower searches, such as neighbourhoods or map-area URLs.

Why is bedrooms or hostType sometimes null? Airbnb's search cards show only some of these lines for a given search. The Actor fills gaps from the listing page when host details are on, but hotels and some rooms simply have no bedroom count.

Why do I get different prices than on the website? Airbnb prices depend on dates, guests, currency and the visitor's region. Set the same dates, guests and currency in the input to get comparable numbers. Without dates Airbnb quotes its own default stay.

What happens with past dates? They are dropped with a warning and Airbnb's default stay is used, so the run does not fail.

Do I need an Airbnb account? No. The Actor reads public pages only and never logs in.

What if Airbnb blocks requests? Requests that are blocked are retried a few times on a fresh proxy session with a pause. If the datacenter proxy is not enough, switch the proxy setting to residential.

Can I scrape a single listing? Yes. Put the listing URL in startUrls. You get that listing's name, title, rating, bedrooms, host and sub-rating fields.

Does it return reviews or calendars? No. This Actor returns search-result listings. Availability calendars are a separate tool.

The Actor collects data that is publicly visible without logging in. Host names are public profile names shown on listing pages. Laws differ by country and by what you do with the data. Personal data, such as a host's name, falls under privacy law like the GDPR in many places, so keep only what you need and have a lawful reason to use it. Airbnb's terms of service restrict automated access, and you are responsible for using the data in line with the rules that apply to you. This is general information, not legal advice; ask a lawyer if you are unsure.

Feedback

If a field is missing, a search returns something unexpected, or you need an extra field, open an issue from the Actor page in Apify Console. Include the input you used and the run link so the problem can be reproduced.