Export Yelp reviews for a list of businesses
Franchise owners, agencies and analysts often need the reviews of dozens of locations in one table, and Yelp’s website has no export.
arcadium/yelp-reviews reads the public reviews of each business you list, newest first, with the full text and the owner’s reply. Reviewer names and photos are never returned.
Cost of this example on the Apify Free plan: 500 × $0.0003 = $0.15 ($0.115 on the Apify Gold plan and higher), plus $0.001 per GB of memory when the run starts.
What you need
- An Apify account and API token.
- A list of Yelp business links (
https://www.yelp.com/biz/...), for example a CSV with aurlcolumn.
Step 1: Run it in the Apify Store (no code)
- Open arcadium/yelp-reviews on the Apify Store and sign in (a free Apify account works).
- Paste the business links into Business URLs, one per line.
- Set Max reviews per business, for example 50.
- Turn on Include business summary row for one free row per business with its overall rating and review count.
- Optional: set a maximum cost per run in the run options as a hard cap.
- Click Start. Rows appear in the Output tab; export them as JSON, CSV or Excel.
The same input as JSON (paste it in the JSON tab of the input form):
{
"startUrls": [
{
"url": "https://www.yelp.com/biz/tartine-bakery-san-francisco-3"
}
],
"maxReviewsPerBusiness": 50,
"includeBusinessSummary": true
}
Step 2: Call it over the Apify API
One HTTP call runs the actor and returns its rows. It suits runs up to about five minutes; for longer runs start the run asynchronously and read the dataset when it finishes.
curl -X POST "https://api.apify.com/v2/acts/arcadium~yelp-reviews/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"startUrls":[{"url":"https://www.yelp.com/biz/tartine-bakery-san-francisco-3"}],"maxReviewsPerBusiness":50,"includeBusinessSummary":true}'
Step 3: Run it from Python
With apify-client 3.x, call() returns a Run object: read the dataset id as run.default_dataset_id (older examples use run["defaultDatasetId"], which no longer works).
# pip install "apify-client>=3"
import csv, os
from apify_client import ApifyClient
with open("businesses.csv") as f: # one column named url
urls = [{"url": r["url"]} for r in csv.DictReader(f) if r["url"].strip()]
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/yelp-reviews").call(run_input={
"startUrls": urls, "maxReviewsPerBusiness": 50, "includeBusinessSummary": True,
})
rows = list(client.dataset(run.default_dataset_id).iterate_items()) # apify-client 3.x
keys = ["productName", "entityId", "date", "ratingOverall", "text", "vendorResponse", "language", "reviewUrl"]
with open("yelp-reviews.csv", "w", newline="") as f:
w = csv.DictWriter(f, fieldnames=keys, extrasaction="ignore")
w.writeheader()
w.writerows(r for r in rows if r.get("rowType") == "review")
for e in (r for r in rows if r.get("rowType") == "error"):
print("could not read:", e.get("input"), e.get("code"))
Step 4: Run it from JavaScript
// npm install apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/yelp-reviews').call({
"startUrls": [
{
"url": "https://www.yelp.com/biz/tartine-bakery-san-francisco-3"
}
],
"maxReviewsPerBusiness": 50,
"includeBusinessSummary": true
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
Step 5: Ask an AI assistant (MCP)
Apify’s hosted MCP server turns the actor into one tool. Add it to Claude, Cursor, VS Code or any MCP client:
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=arcadium/yelp-reviews",
"headers": {
"Authorization": "Bearer <APIFY_TOKEN>"
}
}
}
}Then ask, for example:
Use arcadium/yelp-reviews to read the 30 newest reviews of https://www.yelp.com/biz/tartine-bakery-san-francisco-3 and summarise what people praise and what they complain about.
More clients and the local setup on the MCP page.
Only new reviews next time
Add "onlyNewReviews": true and a stateKey (for example franchise-west) and run the same list weekly: reviews already delivered under that key are skipped and not charged.
Output fields
Every row has a rowType; filter on it first. Failed inputs come back as free rows with a code and message. The fields this tutorial uses, from the actor’s dataset schema:
| Field | What it holds |
|---|---|
rowType | Kind of row. Filter on this first. Values: 'review': one review (charged). 'business-summary': one row per business with its overall rating and review count (free). 'coverage': stated total vs delivered and why reading stopped (free). 'error': an input could not be read; see code and message (free). |
productName | Name of the reviewed hotel, business, product or app. |
entityId | The site's own id of the reviewed entity (place id, product id, app id). |
reviewId | Stable review id in the form '<Platform>___<native id>'. Use it to deduplicate between runs. |
reviewUrl | Link to the single review, null when the site has none. |
date | Date the review was written, ISO format yyyy-mm-dd. Null if unknown. |
ratingOverall | Overall rating on a 0 to 5 scale (Booking: its 1-10 score divided by 2, original in extras.score10). Null when missing. |
text | Review text in the language it was written in. Null when the review has no text. |
language | Language of the review text as a two-letter code, null if unknown. |
vendorResponse | Reply of the owner, vendor, developer or employer, null when there is none. |
All fields: Yelp Reviews Scraper guide.
Cost per run
Pay per event: you pay for the rows delivered, at the actor’s live Apify price on 2026-11-01. Error, coverage and summary rows are free.
| What | Rows | Price per row (Free plan) | Subtotal |
|---|---|---|---|
| Review: 10 businesses x 50 reviews | 500 | $0.0003 | $0.15 |
Cost of this example on the Apify Free plan: 500 × $0.0003 = $0.15 ($0.115 on the Apify Gold plan and higher), plus $0.001 per GB of memory when the run starts. Higher Apify plans pay less per row. The Store page always has the current price.
Limitations
- Yelp search result pages are not supported: you need the business links (or ids) first.
- Only reviews Yelp recommends are public; the ones its filter hides are not available.
- Public reviews only, nothing behind a login. Yelp shows "recommended" reviews; the ones Yelp's filter hides ("not currently recommended") are not available.
- Reviewer names, photos, locations and profile data are never returned. Neither is the business phone number.
- Businesses are found from their page URL, alias or ID. Search result pages are not supported.
- Reviews are not translated;
textis always what the reviewer wrote. - Review photos are links only and are off unless you ask for them.
ELITES_DESC(elite reviewers first) is Yelp's own sort and can time out on very large businesses; use the other sorts there.- Yelp changes its site from time to time. The actor adapts on its own in most cases; if a run fails for several businesses at once, try again later or open an issue.
- You are responsible for using the data in line with Yelp's terms and the law where you live.
Links
- Yelp Reviews Scraper: fields, price table and sample output
- How to use Yelp Reviews Scraper: every input field, n8n, LangChain
- arcadium/yelp-reviews on the Apify Store
- All tutorials