Nextdoor Business & Reviews Scraper
Pricing
Pay per event
Nextdoor Business & Reviews Scraper
Scrape public Nextdoor business listings, neighbor recommendations and city demographics. No login, no session cookies, nothing that expires.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Oswaldo Carabano
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 hours ago
Last modified
Categories
Share
Extract public Nextdoor business listings, neighbor recommendations and city demographics as structured JSON, CSV or Excel.
No login. No session cookies. No browser. Nothing you have to refresh, and nothing that expires between runs.
Why that matters more than it sounds
Most Nextdoor scrapers ask you for your session cookies. That works on the day you set it up and breaks when the cookies expire — and when it breaks, there is nothing you can do about it except paste new cookies and hope.
This Actor reads only what Nextdoor's own servers hand to a signed-out visitor. There is no account, no session and no cookie jar, so there is nothing to go stale. A run today behaves like a run in six months.
That is a deliberate design constraint, not a missing feature. It also means the Actor cannot reach anything behind Nextdoor's login — see What this Actor will not do.
What you get
One row per business in the main dataset, with its recommendations nested inside. Two ready-made views: Businesses (one row each) and Recommendations (one row per recommendation, business as context).
City data, posts and any error rows go to their own separate datasets — cities,
posts, errors — so the main table never has blank rows in it.
1 · business — the primary dataset
34 fields per business: name, categories, phone, email, website, full address with ZIP, coordinates, opening hours, verification status, gallery, Nextdoor's own summary of what neighbors say, and more.
Measured fill rates — counted over 741 distinct businesses across 5 cities and 12 categories. These are counts from real runs, not estimates:
| Field | Filled |
|---|---|
phone_number | 93.9 % |
categories | 84.2 % |
website_url | 77.2 % |
email | 62.6 % |
hours_open_status | 57.4 % |
recommendations_summary | 47.4 % |
description | 46.6 % |
gallery_urls | 44.5 % |
An earlier version of this page quoted higher numbers for some fields, measured on a sample of 30. At n = 741 several came out lower — opening hours most of all, 57 % rather than 77 %. The table above is the one to trust, and it is the one we will keep correcting as the sample grows. Anything not listed here is not promised.
Anything not on that list is not promised. address_postal_code is derived by this
Actor, because Nextdoor does not expose a ZIP field anywhere in its schema.
2 · recommendation — with a classifier you will not find elsewhere
Nextdoor's recommendation feed mixes three different things that all look alike: people praising a business, people asking for one, and people just saying thanks. Scrape it raw and your "500 reviews" are largely neighbors asking "anyone know a good plumber?" — which is worthless as review data and poisonous as sentiment input.
Every row gets a kind field:
kind | What it is |
|---|---|
recommendation | Actual praise or criticism of a business |
service_request | Someone looking for a provider, not reviewing one |
thanks | Acknowledgement with no substance about the business |
unknown | Below the confidence threshold — flagged, not guessed |
How much this matters, measured across two real runs (891 recommendations): 50 %
came back service_request — neighbors asking for a provider — against 19 %
actual recommendations. Scrape the feed raw and half your "review data" is noise
pointing the wrong way.
Accuracy: 95.6 % on a hand-labelled validation set. Each row also carries
kind_confidence and kind_signals, so you can raise the bar yourself instead of
trusting a black box.
A note on wording. Nextdoor calls these recommendations, not reviews. They are free-text posts from neighbors, they have no star rating, and Nextdoor anonymizes the author (typically a first name and last initial). If you need numeric ratings, this is not that dataset. What you get is what people actually wrote — which for most local-market research is the more useful half.
Measured over the same 741 businesses: 42.4 % have at least one recommendation,
averaging 2.5 each across all businesses. Plan for that — more than half of any
local category has none, and those businesses are still returned with
recommendations_count: 0 so your row count stays predictable.
3 · city — demographics and market context
Residents, average income and age, homeowner percentage, safety / friendliness / affordability scores, all 54 business categories Nextdoor tracks, up to 852 neighborhoods, and counts of classifieds, local groups and events.
4 · posts dataset — optional
Business posts are corporate content published by the businesses themselves. Neighbor posts are off by default — see Privacy.
Where each thing lands
| Dataset | Contents |
|---|---|
| default | one row per business, recommendations nested inside |
cities | one row per city: demographics, scores, neighborhoods |
posts | business posts and, if enabled, neighbor posts |
errors | anything that failed, for traceability — never charged |
Input
Paste a city and go. Every field has a sensible default, and the defaults are
deliberately small: a first run finishes in about a minute and costs under $0.50, so
you can see the real data before committing to a full sweep. Raise
maxBusinessesPerCity when you want one.
{"cities": ["san-clemente--ca"],"categories": ["Dentist", "Plumber"],"maxBusinessesPerCity": 50,"includeRecommendations": true,"includeCityData": true}
City slugs follow Nextdoor's own format: city-name--state, lowercase, two-letter
state. Leave categories empty to sweep all 54 categories a city exposes.
How Nextdoor orders a city directory — worth 30 seconds
Nextdoor's category directory is ordered by distance. It serves every business in the city you asked for, and once that list runs out it keeps going into neighbouring towns. The switch is abrupt, not a gradual blend.
We measured it on san-clemente--ca, asking for 200 dentists, and counted how many
of each block of 25 were actually in San Clemente:
| Results | In San Clemente |
|---|---|
| 1–75 | 96–100 % |
| 76–200 | 0 % |
San Clemente simply has ~72 dentists. Everything past that point is the surrounding trade area — San Juan Capistrano, Dana Point, Ladera Ranch, Laguna Niguel.
What this means for you in practice:
- Keep
maxBusinessesPerCitynear what a city plausibly holds and you get that city, full stop. Our 120-business run came back 92 % San Clemente with no filtering. - Set it far higher and the surplus is regional overflow. Useful if you want the trade area — surprising if you didn't.
onlyRequestedCity: truekeeps only the city you named. Filtering happens during discovery, so you are never charged for a dropped business, and the Actor stops paging once the city is exhausted instead of burning through the region.
Every row carries address_city either way, so you can always split it yourself.
When you request several categories, the per-city limit is split evenly between them, and whatever a small category cannot fill is handed to the others. Ask for plumbers and dentists and you get both, not 200 dentists.
You can also skip discovery entirely and pass business URLs directly in
directBusinessUrls.
Pricing
Pay per result. You are never charged for a row that was not delivered, and error rows are never charged at all.
| Event | Price |
|---|---|
| Actor start | $0.00001 — effectively free |
business | $0.008 |
city | $0.008 |
recommendation | $0.002 |
post | $0.001 |
Starting the Actor costs $0.00001 — Apify does not allow a literal $0 event — so a
run that finds nothing costs you a hundred-thousandth of a dollar, which is as close
to nothing as the platform permits. Set
maxBusinessesPerCity, or a spend limit on the run, and the Actor stops cleanly at
the limit — no half-written rows.
Speed and politeness
Measured on the platform: ~3,300 businesses/hour end-to-end at the default concurrency of 5 — that is 120 businesses plus 393 recommendations plus city data in 130 seconds, discovery included. The extraction stage alone runs at ~4,900/hour.
The Actor deliberately caps concurrency at 5 and keeps a delay between requests. Pushing harder triggers rate limiting that costs more time than it saves — we measured a ~4 minute cooldown after tripping it — so when Nextdoor pushes back, the whole run pauses for minutes rather than hammering through a penalty window. Slower than a scraper that ignores this, and it finishes; faster in practice.
Requests go out through US residential IPs. You do not need to configure a proxy.
Data freshness
Results may be served from a shared cache, which makes runs faster and cheaper. Every row tells you exactly what you got:
from_cache— whether this row came from cachefetched_at— when the data was actually read from Nextdoordata_age_hours— how old it is
Set maxCacheAgeDays: 0 to force a fresh fetch on every row.
What this Actor will not do
Stated plainly so you can judge fit before spending anything:
- No logged-in content. No private groups, no member feeds, no direct messages, nothing that requires an account.
- No free-text business search. Nextdoor requires a login for that, so discovery runs through the public category directory instead. You find businesses by city and category, not by arbitrary keyword.
- No star ratings. Nextdoor recommendations do not have them.
- No de-anonymized authors. Author names are passed through exactly as Nextdoor publishes them and are never cross-referenced, enriched or resolved to real people.
- No addresses for businesses that hid theirs. When a business sets its address
to private — common for people working out of their homes — every address field
comes back
nullwith a warning, even though the coordinates are technically visible in the page source. - United States only in this version.
Privacy and personal data
Business contact details are published by the businesses themselves, for the purpose of being contacted.
Neighbor content is treated differently. includeCityPosts is off by default
because neighbor posts carry partial real names alongside a specific neighborhood,
and sometimes describe local safety incidents. includeAuthorNeighborhood is a
separate opt-in on top, because a partial name plus a precise neighborhood can
identify a real person in a small community. If you turn these on, you are
responsible for how you use the results — including under CCPA, if that applies to
you.
Removal requests: if you are a business owner or resident and want your information excluded from future runs, email privacy@actorstack.dev and it will be added to an exclusion list.
Not affiliated with Nextdoor
This Actor is an independent tool. It is not affiliated with, endorsed by, sponsored by or connected to Nextdoor, Inc. in any way. "Nextdoor" is a trademark of its owner, used here only to describe what this Actor reads.
It collects only data that Nextdoor's servers serve publicly to visitors who are not signed in. You are responsible for complying with the laws that apply to you when you use the output.
Output sample
Every field is always present. A field that exists but is empty comes back as
explicit null — keys are never dropped, so your parser never has to guess.
The nested recommendations omit scraped_at, _type, _warnings and
business_id, because the business row already carries all four and the
Recommendations view lifts the nested keys up to the top level — two keys with the
same name would silently overwrite each other.