💰 $1 per 1,000 businesses. Scrape yelp.com business listings by search term or location — full business profiles · contact details · phone and website · ratings and reviews · restaurant menus · structured data for lead generation and market analysis.
Structured address on every business: street, city, state, postalCode and country
as their own fields, alongside the existing single-line location.
hours — the full week of opening hours, labelled by Yelp's own day names. hoursToday
is unchanged.
isCurrentlyOpen, photoCount, alias (the canonical /biz/<alias> slug) and isYelpAdvertiser
(true when the business advertises on Yelp).
Telegram, Discord, Slack, WhatsApp and webhook notifications now actually fire. The input
fields existed but nothing was sent.
Start URLs now accept a business page (yelp.com/biz/...), not only a search page. Pasting
one used to fail the run.
includePhotos / maxPhotos — the business's photo URLs, off by default so results stay
small for everyone who only wants photoCount.
healthScore — the latest health-inspection result Yelp shows (US), and closedUntil,
which carries a date only while a business is temporarily closed.
Memory
The default run memory is now 2 GB, up from 1 GB. Measured on the same 100-business search:
1 GB never finished the profile phase at all (killed after 29 minutes with nothing to show),
2 GB finished in 108 seconds, 4 GB in 95. 1 GB is still selectable for small runs. Note that
the Actor-start event is charged per GB, so a 2 GB run's start fee is $0.008 instead of
$0.004; on a run of any real size that is a rounding error next to what it saves.
Results now arrive during the run
Businesses are written to the dataset as their profiles finish, in batches of ten, instead of
being held in memory and written in one go at the very end. A run that is interrupted — a
timeout, a block, an aborted run — now leaves you everything it had finished, rather than
nothing at all. Measured: 30 results were readable 67 seconds into a run that ended at 70.
Incremental runs no longer re-buy what has not changed
A monitor used to fetch the full profile of every business on every run, just to discover that
nothing had changed. It now uses the search result itself as the gate: a business already in
your Saved State Key whose name, address, main photo and claim status are unchanged is not
fetched again. Measured on a 120-business search: a quiet run went from ~105 seconds to ~25,
and the run log tells you how many were skipped.
The trade-off, stated plainly: a change only the full profile would show — a new phone number,
a new website, different opening hours — is no longer picked up on a business you have already
received. A rename, a move, a new main photo and a claim all still trigger a fresh fetch and a
full updated record. Turn on Emit Unchanged to get every business back in full on every run.
Changing what a result contains now returns your businesses again
Incremental history is kept per output shape. Switching Include Full Details, photos, menus,
e-mail enrichment, Compact, Exclude Empty Fields, the description format or its maximum length
gives you every matching business back once, in the new shape, instead of an empty run saying
nothing has changed. Runs that keep the same settings are unaffected.
Note for incremental users
The first run after this release returns your businesses again. Their records changed: review
highlights now have content, the address is structured, and the fields that decide "has this
business changed" now include phone, website, categories, price band, hours, the review
quotes and the health result. After that first run, only real changes come back.
Fixed
attributes listed things the business does NOT offer. Yelp ships the negatives alongside
the positives (its own page strikes them through) and all of them were being delivered — on
one live restaurant, 18 of 47 entries, including "Offers delivery" for a business that does
not deliver. Only what the business actually offers is returned now.
reviewHighlights was empty on every result ever returned. Yelp splits each quote across
several text nodes and the parser read a field that does not exist; the quotes were on the
page the whole time. Businesses now come back with 5-8 of them.
A run whose searches were all refused now fails instead of finishing green with an empty
dataset. A refused page mid-run no longer passes for the end of the results either — the run
says so in the log instead of quietly returning a short list. A block served as an ordinary
200 response is treated as a refusal, not as "no businesses here".
Results are no longer written past the run's maximum cost limit and then remembered as
delivered. A capped run now delivers what it can pay for and leaves the rest for the next run.
Changes to a business's phone, website, categories, price range, opening hours or closed
status now come back as changed results in incremental mode. Only a rename or a move did
before. Rating and review count are deliberately not tracked — they move constantly and
would return your whole list as "changed" on every run.
Incremental state no longer grows without limit. A business not seen for 90 days is dropped
from the run's memory.
Reordering a multi-value Search Term or Location no longer starts a fresh incremental
history and re-delivers everything.
One failed browser session no longer silently downgrades every remaining business in the run
to search-result-only data.
Search results without an id are dropped instead of collapsing into one bogus record with a
broken URL.
With several search terms, each result now carries the term that actually found it.
A search that reports no further pages no longer triggers dozens of pointless requests.
Latitude/Longitude/Radius set only partly is now reported in the log instead of being
silently ignored. A radius run with Include Full Details off is now rejected with an
explanation instead of returning unfiltered businesses, and a business whose coordinates
are unknown is no longer counted as inside the radius.
The same business reached both by its page URL and through a search is now delivered — and
charged for — once.
A business whose full profile could not be fetched is no longer delivered as an
almost-empty row. It used to be charged for twice: once as a stripped result, once again
when the next run recovered it.
Turning photos, menus or e-mail enrichment on now re-delivers your businesses with the new
data instead of reporting them all unchanged.
A run that finds nothing no longer leaves its Saved State Key locked for 30 minutes, and a
run that lost its turn no longer clears the lock belonging to the run that took over.
Incremental history now survives all of the above: a run whose identity moved adopts its
earlier history instead of re-delivering everything as new.
A refused menu lookup is no longer recorded as "this business has no dishes", and neither is
a menu response that arrives in an unexpected shape.
A results page where every entry is unusable — no id, or no business name — now fails
instead of counting as an empty page, and a run that ends up delivering none of the
businesses it found fails too. Businesses that are genuinely gone still end the run normally.
An empty first page is retried once. The same search was measured returning 0 businesses on
one call and 20 on the next, so a single blink used to end the run with a clean, wrong zero.
A results page with no pagination information is treated as a broken response instead of as
"there are no more pages", which used to cut every run down to its first page.
Changes to a business's amenities, year established or popular dishes now come back as
changed results in incremental mode.
A profile that fails on a refusal, a timeout or a dropped connection is retried before the
business is given up on; only rate limits and server errors were retried before. A blocked
run now gives up in half the time it did while that retry was duplicated.
A response that stalls after its headers is now cancelled instead of holding a connection
open for the rest of the run.
Start URLs on look-alike hosts (yelp.company) or look-alike paths (/searches) are no
longer accepted as Yelp targets.
A menu entry with no name is dropped instead of being delivered as a nameless dish, and a
menu lookup that fails no longer costs you the whole business — the profile is delivered
either way.
A business the Search Radius excluded is no longer remembered as delivered, so it is
returned if its position later falls inside the radius.
Businesses Yelp reports as unclaimed now come back as isClaimed: false instead of empty.
contactEmail no longer returns the dummy address a website theme ships with. Two different
Brooklyn restaurants were both being delivered as user@domain.com; an address on the
business's own domain is now preferred, and template placeholders are dropped. An empty
field is better than a fake lead.
A single Start URL passed as plain text instead of a list is now used, rather than the run
finishing successfully with no results.
A menu or contact-email lookup that could not be READ is no longer recorded as a change. It
used to bill an updated result for the missing value and another when it came back.
A radius run now scans a sensible number of businesses even when the result limit is small,
and says in the log when the radius is what left the run empty.
Start URLs are authoritative: a URL that cannot be used stops the run instead of quietly
scraping the remaining ones or falling back to the Search Term. A Yelp search URL carrying
Yelp's own filters or sort is refused, because this scraper cannot apply them and would
otherwise return the unfiltered result set.
The same search term or URL listed twice no longer starts a fresh incremental history.
Suite and unit numbers (addressLine2) are now part of the street address.
A business-page Start URL with Include Full Details off is rejected instead of finishing
with zero results.
A business skipped by Skip Reposts is no longer remembered as delivered, so turning the
option off returns it.
A key-value store hiccup while loading incremental state no longer leaves the Saved State
Key locked for 30 minutes.
A run where every business profile failed to load now fails instead of finishing green with
an empty dataset. Businesses that no longer exist on Yelp still end the run normally.
A profile that fails to load is retried once before the business is given up on.
Requests that stall are now cancelled properly. The previous timeout could leave the
connection open, which on rare occasions hung a run to its deadline with no output.
Incremental runs no longer remember businesses the result limit cut off. They were stored
as already-seen and never delivered on later runs; now they come back on the next run.
A centre + radius run now fetches enough businesses to fill the result limit with ones
inside the radius, instead of filtering a full page down to a handful.
A centre + radius run keeps its own incremental history, so widening the radius delivers
the newly included businesses instead of treating them as already seen.
Removed
Four fields that were exact copies of a field that stays: entityName (= title),
sellerWebsite (= website), priceText (= priceRange) and descriptionText
(= description). Byte-identical on every record; together 298 bytes of a 3,636-byte row.
Nothing is lost — the twin is still there under its canonical name. (portalUrl also
duplicates url but stays: it is the standard link-back field across all our Actors.)
14 fields that were always empty for Yelp (subtitle, subcategory, descriptionHtml,
descriptionMarkdown, priceValue, priceCurrency, listingType, condition,
publishedAt, publishedAge, validThrough, sellerName, sellerType, sellerUrl).
They carried no data on any run; dropping them makes each result smaller. If your pipeline
reads one of them, it was reading null.
0.1.1 — 2026-08-17
Fixed
Runs with email enrichment enabled no longer log Attempting to charge for an unknown event 'email-enriched'. The Actor tried to bill an event that is not part of its pricing, so the charge was always rejected and the warning was written into your run log instead. Nobody was ever billed for it, no run cost changes, and email enrichment stays covered by the standard per-result fee.
0.1.0 — 2026-07-17
Initial release.
Search Yelp businesses by term + location.
Full business profile: rating, review count, phone, website, hours, categories, address,
neighborhoods, coordinates, attributes, price range, year established, specialties.
Popular dishes / menu items (opt-in, restaurants).
Contact-email enrichment from the business website (opt-in, billed per email found).