Airbnb City Supply Census
Pricing
from $0.50 / 1,000 result rows
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a month ago
Last modified
Categories
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
| Setting | Type | Default | What it does |
|---|---|---|---|
| Cities or areas | list 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 areas | list of objects | empty | Precise 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 name | true/false | true | On 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 listings | number | 240 (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 depth | number | 4 (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 area | number | 10 (max 20) | How far to read into a single area before moving on. |
| Stop an area under this many new listings | number | 4 (max 40) | A page that adds fewer new listings than this ends the area. |
| Price bands | list of objects | empty | Extra 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 types | list from a menu | empty | A further slice for areas still full after the price bands. "Entire home or apartment" is the confirmed option. |
| Check-in / Check-out date | date | empty | Optional. Set both and every listing also carries the price for that exact stay, which makes the area price summaries directly comparable. |
| Adults | number | 2 (max 16) | Guest count used when dates are set; it changes both which listings appear and what they cost. |
| Maximum listings | number | 5000 (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 lookups | number | 600 (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 area | true/false | true | Adds the per-area density and price rows. |
| Areas at a time | number | 4 (max 8) | How many map areas to work through in parallel. |
| Currency | text | USD | Three-letter code, pinned for the whole run so area price summaries are comparable. |
| Language | text | en | Language for listing text. English is the tested option. |
| Country to appear to browse from | text | empty | Two-letter country code, to see the market as a visitor from that country would. |
Output fields
Listing rows
| Field | Description |
|---|---|
listingId, listingUrl | Airbnb's own listing identifier and the link to its page |
listingName | The host's own name for the place |
title, roomTypeText, titleUnavailableForTile | Airbnb'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, longitude | Approximate map position, as Airbnb publishes it |
ratingLocalized, ratingValue, reviewCount, ratingCountUnavailable | Rating as shown, as a number, its review count, and a flag when the count was not published |
isNewListing, isGuestFavourite, isSuperhostBadged, badges | Whether the listing has no reviews yet, plus the badges it carries |
priceLine, priceLineType | The price exactly as a guest sees it, and which of Airbnb's two price formats it came in |
nightlyRate, totalPrice, originalPrice, discountPct, currency, nights | The 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 |
promotions | Free-cancellation, pay-later and length-of-stay-discount highlights |
photoUrls, photoCount, thumbnailUrl | Listing photography |
tileId, tileDepth, tileBbox, place | Which map area found the listing, and how deep in the split that area was |
discoveredUnderPriceBand, discoveredUnderRoomType | Set when the listing only surfaced under an extra slice |
checkIn, checkOut, nights, leadTimeDays | The stay the prices refer to |
scrapedAt, actorRunId | When the row was collected, and by which run |
Area summary rows (recordType: "tile")
| Field | Description |
|---|---|
tileId, parentTileId, tileDepth, tileBbox, place | Which area this is and where it sits in the split |
uniqueListings, pagesFetched, requestsUsed | How many distinct listings the area produced and how much work it took |
saturated, stillSaturated, splitInto, stopReason | Whether 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, currency | The area's price distribution |
guestFavouriteShare, newListingShare | Share of the area's listings that are Guest Favourites, and share with no reviews yet |
areaKm2, listingsPerKm2 | Size of the area and its listing density |
shardedByPriceBand, shardedByRoomType, droppedFilters | Which extra slice produced the area, and any setting Airbnb did not confirm it had applied |
Coverage report rows (recordType: "coverageReport")
| Field | Description |
|---|---|
place, rootBbox, searchQuery, placeId | What was counted, and Airbnb's own identifier for the place it matched |
tilesVisited, tilesSplit, tilesStillSaturated, maxDepthReached | How the sweep unfolded |
uniqueListings, requestsUsed, budgetExhausted | The headline count and what it cost |
coverageConfidence | high, partial or low |
completenessStatement | A 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 for | Price |
|---|---|
| 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,partialorlow. Evenhighmeans "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.


