Airbnb City Supply Census avatar

Airbnb City Supply Census

Pricing

from $0.50 / 1,000 result rows

Go to Apify Store
Airbnb City Supply Census

Airbnb City Supply Census

Count Airbnb's whole supply in a city, not just the first page. It sweeps a city in many small map areas and merges them into one de-duplicated census of listings, prices, ratings, coordinates and per-area density — with a coverage report stating how complete the count is.

Pricing

from $0.50 / 1,000 result rows

Rating

0.0

(0)

Developer

Hamza

Hamza

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a month ago

Last modified

Share

Count the whole short-term-rental supply of a city on Airbnb — not the first page of it. Airbnb only ever shows a few hundred listings for any one search, so this actor splits a city into map areas, sweeps each one until it stops producing anything new, splits the crowded ones into quarters and sweeps again, and merges everything into a single de-duplicated census. You get one row per distinct listing, one summary row per map area with its density and price quartiles, and a coverage report that tells you in plain English how complete the count actually is. Built for analysts, city regulators, hosts and investors who need a supply number they can defend.

What you can do with it

  • Size a market properly. Get the real number of active listings in a city, district or island — with the areas that were still full when the sweep left them named explicitly, so nobody has to guess how much was missed.
  • Map density and price by neighbourhood. Every map area comes back with listings per square kilometre, median and 25th/75th-percentile nightly rates, and the share of listings carrying a Guest Favourite badge.
  • Track supply growth over time. Schedule it monthly on the same city and compare the counts, the new-listing share and the price quartiles per area.
  • Support regulation and compliance work. Produce an area-by-area inventory with coordinates and listing links for a licensing review or a housing study.
  • Find where to add inventory. Compare density against price: areas with a high median rate and low density are the underserved ones.
  • Build a comp set from scratch. Sweep one district with dates set and get every competing listing with its price for exactly your stay.

What you get

One row per distinct listing:

{
"recordType": "listing",
"listingId": "1411515025041166259",
"listingUrl": "https://www.airbnb.com/rooms/1411515025041166259",
"listingName": "Charming flat with a view of the Eiffel Tower",
"title": "Home in Paris",
"titleUnavailableForTile": false,
"roomTypeText": "Home",
"latitude": 48.85661,
"longitude": 2.29841,
"ratingLocalized": "5.0 (17)",
"ratingValue": 5,
"reviewCount": 17,
"ratingCountUnavailable": false,
"isNewListing": false,
"isGuestFavourite": true,
"priceLine": "$796 for 5 nights",
"priceLineType": "QualifiedDisplayPriceLine",
"nightlyRate": 159.08,
"totalPrice": 795.38,
"originalPrice": null,
"discountPct": null,
"currency": "USD",
"nights": 5,
"promotions": [{ "type": "FREE_CANCELLATION_HIGHLIGHT", "text": "Free cancellation" }],
"badges": [{ "type": "GUEST_FAVORITE", "text": "Guest favorite" }],
"photoCount": 6,
"thumbnailUrl": "https://a0.muscache.com/im/pictures/hosting/…",
"tileId": "paris-france.ne.sw",
"tileDepth": 2,
"tileBbox": "48.87750,2.37000,48.85500,2.32000",
"place": "Paris, France",
"checkIn": null,
"checkOut": null,
"scrapedAt": "2026-07-30T09:14:22.108Z"
}

One summary row per map area (recordType: "tile"):

{
"recordType": "tile",
"tileId": "paris-france.ne.sw",
"place": "Paris, France",
"tileDepth": 2,
"tileBbox": "48.87750,2.37000,48.85500,2.32000",
"parentTileId": "paris-france.ne",
"uniqueListings": 187,
"pagesFetched": 6,
"saturated": false,
"stillSaturated": false,
"splitInto": [],
"medianNightlyRate": 176.22,
"p25NightlyRate": 128.4,
"p75NightlyRate": 257.92,
"pricedListings": 184,
"currency": "USD",
"guestFavouriteShare": 0.3743,
"newListingShare": 0.1176,
"areaKm2": 9.11,
"listingsPerKm2": 20.53,
"scrapedAt": "2026-07-30T09:14:22.108Z"
}

And one coverage report per city (recordType: "coverageReport"):

{
"recordType": "coverageReport",
"place": "Paris, France",
"rootBbox": "48.90000,2.42000,48.81000,2.22000",
"tilesVisited": 21,
"tilesSplit": 5,
"tilesStillSaturated": 1,
"uniqueListings": 4821,
"budgetExhausted": false,
"maxDepthReached": 2,
"coverageConfidence": "partial",
"completenessStatement": "4821 distinct listings were found across 21 map areas in Paris, France. 1 area still returned as many listings as Airbnb will show for one area after being split as far as the settings allow, so that area holds more listings than are reported here."
}

Input reference

SettingTypeDefaultWhat it does
Cities or areaslist of text["Paris, France"]The places to count, written as you would type them into Airbnb's own search box. Up to 20; each gets its own coverage report.
Exact map areaslist of objectsemptyPrecise rectangles as {"neLat": 48.90, "neLng": 2.42, "swLat": 48.81, "swLng": 2.22}, optionally with their own query. Use these to census one district, island or coastline. Up to 20.
Work out the map area from the city nametrue/falsetrueOn by default: a first sweep of the city establishes how far its listings spread, and that becomes the area the census then covers quarter by quarter. Off means the city is counted as one single search — much cheaper, but limited to the first few hundred listings.
Split an area after this many listingsnumber240 (max 320)When one area produces this many listings, it is treated as full and split into four smaller areas. Lower values split earlier and find more.
Maximum splitting depthnumber4 (max 6)How many times an area may be quartered. 4 suits a whole city; 6 is for an exhaustive audit of a dense downtown.
Maximum pages per areanumber10 (max 20)How far to read into a single area before moving on.
Stop an area under this many new listingsnumber4 (max 40)A page that adds fewer new listings than this ends the area.
Price bandslist of objectsemptyExtra slices such as [{"min": 0, "max": 120}, {"min": 120, "max": 400}], applied only to areas still full at the deepest splitting level. The most effective way to see past Airbnb's per-area ceiling. Up to 8.
Room typeslist from a menuemptyA further slice for areas still full after the price bands. "Entire home or apartment" is the confirmed option.
Check-in / Check-out datedateemptyOptional. Set both and every listing also carries the price for that exact stay, which makes the area price summaries directly comparable.
Adultsnumber2 (max 16)Guest count used when dates are set; it changes both which listings appear and what they cost.
Maximum listingsnumber5000 (max 50000)Hard cap on distinct listings for the whole run. The run stops cleanly at the cap and still writes its coverage report.
Maximum lookupsnumber600 (max 6000)Hard budget for how much reading the run may do. A dense city typically needs a few hundred.
Include an area summary for every map areatrue/falsetrueAdds the per-area density and price rows.
Areas at a timenumber4 (max 8)How many map areas to work through in parallel.
CurrencytextUSDThree-letter code, pinned for the whole run so area price summaries are comparable.
LanguagetextenLanguage for listing text. English is the tested option.
Country to appear to browse fromtextemptyTwo-letter country code, to see the market as a visitor from that country would.

Output fields

Listing rows

FieldDescription
listingId, listingUrlAirbnb's own listing identifier and the link to its page
listingNameThe host's own name for the place
title, roomTypeText, titleUnavailableForTileAirbnb's room-type-and-city line, the room type pulled out of it, and a flag when that line was not published for the area being counted
latitude, longitudeApproximate map position, as Airbnb publishes it
ratingLocalized, ratingValue, reviewCount, ratingCountUnavailableRating as shown, as a number, its review count, and a flag when the count was not published
isNewListing, isGuestFavourite, isSuperhostBadged, badgesWhether the listing has no reviews yet, plus the badges it carries
priceLine, priceLineTypeThe price exactly as a guest sees it, and which of Airbnb's two price formats it came in
nightlyRate, totalPrice, originalPrice, discountPct, currency, nightsThe rate a guest would actually pay, the stay total, the pre-discount price where Airbnb shows one, and the length of the window the price covers
promotionsFree-cancellation, pay-later and length-of-stay-discount highlights
photoUrls, photoCount, thumbnailUrlListing photography
tileId, tileDepth, tileBbox, placeWhich map area found the listing, and how deep in the split that area was
discoveredUnderPriceBand, discoveredUnderRoomTypeSet when the listing only surfaced under an extra slice
checkIn, checkOut, nights, leadTimeDaysThe stay the prices refer to
scrapedAt, actorRunIdWhen the row was collected, and by which run

Area summary rows (recordType: "tile")

FieldDescription
tileId, parentTileId, tileDepth, tileBbox, placeWhich area this is and where it sits in the split
uniqueListings, pagesFetched, requestsUsedHow many distinct listings the area produced and how much work it took
saturated, stillSaturated, splitInto, stopReasonWhether the area hit Airbnb's per-area ceiling, whether it was still hitting it after every available split, and which child areas it produced
medianNightlyRate, p25NightlyRate, p75NightlyRate, pricedListings, currencyThe area's price distribution
guestFavouriteShare, newListingShareShare of the area's listings that are Guest Favourites, and share with no reviews yet
areaKm2, listingsPerKm2Size of the area and its listing density
shardedByPriceBand, shardedByRoomType, droppedFiltersWhich extra slice produced the area, and any setting Airbnb did not confirm it had applied

Coverage report rows (recordType: "coverageReport")

FieldDescription
place, rootBbox, searchQuery, placeIdWhat was counted, and Airbnb's own identifier for the place it matched
tilesVisited, tilesSplit, tilesStillSaturated, maxDepthReachedHow the sweep unfolded
uniqueListings, requestsUsed, budgetExhaustedThe headline count and what it cost
coverageConfidencehigh, partial or low
completenessStatementA plain-English sentence, ready to paste into a report, saying what was covered and what was not

The same coverage report is also saved to the run's key-value store under COVERAGE_REPORT.

Pricing

This actor is pay-per-event. You are charged for what it produces, not for how long it runs.

What you pay forPrice
Each row written to the dataset — every listing, every area summary, every coverage report$0.0005 ($0.50 per 1,000)
Each map area swept to exhaustion and summarised$0.004

Listing rows arrive dozens at a time, so they are priced as a commodity per thousand. An area summary is different: it only exists after that area has been read page after page until it stopped producing new listings, which is the expensive part of a census. That is why sweeping an area is the one thing charged separately — and why turning area summaries off makes a run cheaper.

Worked example: a 12,000-listing city covered by about 120 map areas comes to roughly $6.48 — $6.00 of listing rows plus $0.48 of area sweeps, and a few cents for the summary rows themselves. A single district with dates set, around 600 listings over 8 areas, is about $0.34.

Limits & what this actor cannot do

  • A city census cannot be proven complete. Airbnb shows only a few hundred listings for any single search and starts repeating itself past that point, which is exactly why the census works through many small map areas and merges them. Every run therefore ships a coverage report naming the areas that were still full when it left them, and a confidence level of high, partial or low. Even high means "as complete as public search results allow" — Airbnb publishes no total to check against.
  • Airbnb's map pins are capped at 20 per area and mostly repeat the listings already in the main results, so they are treated as a bonus and never as a source in their own right.
  • Listings with no reviews yet show "New" instead of a rating. They are flagged as new rather than reported as unrated.
  • A map area counted without a place name loses its room-type line and its review counts. The actor always supplies a place name for this reason, and where one genuinely cannot be supplied the affected rows say so explicitly instead of looking like missing data.
  • Prices are for a stay window, not a nightly list price. With dates set, the price is for exactly those dates. With no dates, Airbnb quotes a default window and the row records how many nights that was. Cleaning and service fees are not published separately — the totals are already all-in and cannot be broken down.
  • Coordinates are approximate, as Airbnb publishes them, not exact street addresses.
  • Counts are a snapshot. Supply changes daily, and repeating a run on the same city will not return an identical number.
  • Non-English languages are accepted but untested. English is the tested option.
  • Speed depends on the size of the job and on how quickly the source site responds. No fixed throughput is promised.
  • Airbnb's terms prohibit automated access. You are responsible for using the data lawfully and in line with the source site's terms, and for any local rules that apply to the market you are studying.

FAQ

Do I need an Airbnb account? No. None at all.

Does it need a login, personal details or anything from my browser? No. Nothing is required beyond the settings above.

Is the data complete? It is as complete as Airbnb's public search results allow, and the actor tells you exactly how complete rather than implying it got everything. Read the coverage report: coverageConfidence is only high when no area was still full at the end and the run finished within its own limits. tilesStillSaturated names how many areas held more than could be seen.

How do I get a more complete count? Three settings, in order of effect: lower "Split an area after this many listings", raise "Maximum splitting depth", and add price bands. Then raise "Maximum lookups" so the run has room to do the extra work. Supplying tight map areas yourself, one district at a time, gives the most complete result of all.

Can I schedule it? Yes. A monthly run on the same city with the same settings gives a comparable supply series — listing counts, density per square kilometre, price quartiles and new-listing share per area. Keep the settings identical between runs, since changing the splitting depth changes how much is found.

Why does one listing appear under a map area it does not sit in? Airbnb occasionally returns a listing just outside the requested rectangle. Rows keep their real coordinates, so you can filter by position yourself. Every listing is reported once for the whole run regardless of how many areas returned it.

What do the price quartiles per area mean? They are computed from the listings that area actually produced, in the currency you chose. With dates set they describe that specific stay; with no dates they describe Airbnb's default window, and the number of nights is on every row.