# Yelp Business Profiles Scraper (`automation-lab/yelp-business-profiles-scraper`) Actor

Search Yelp by keyword or category and location, or extract exact business URLs. Export public identity, ratings, contacts, address, hours, categories, prices, and canonical profile URLs.

- **URL**: https://apify.com/automation-lab/yelp-business-profiles-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 60.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Yelp Business Profiles Scraper

Search Yelp by keyword or category and location, or supply business profile URLs directly.
The Actor returns normalized public business identity, categories, rating summary, address,
phone and website when visible, opening hours, price indicator, and canonical Yelp URL.

Use this Yelp scraper for repeatable local-business prospecting and market research without
manually copying profile pages into a spreadsheet.

### What does Yelp Business Profiles Scraper do?

The Actor supports two complementary routes:

1. Search Yelp with one or more keyword/category and location pairs.
2. Extract exact businesses from canonical `yelp.com/biz/...` URLs.

Each accepted business becomes one typed record in the default Apify dataset.
Search results are deduplicated by Yelp alias, including across multiple searches.
Sponsored results are excluded by default and can be included explicitly.

The Actor does not scrape reviews. If your job is review and reputation analysis, use the
related Yelp Business Reviews Scraper listed below.

### Who is it for?

**Local sales teams** build focused prospect lists by trade, service, or neighborhood.

**Market researchers** compare category density, ratings, review volume, and price signals.

**Agencies** map public business profiles before campaign planning or territory reviews.

**Data teams** schedule recurring extraction into a warehouse, spreadsheet, CRM, or BI tool.

**Developers** call a stable Actor input/output contract instead of maintaining page parsers.

### Why use this Actor?

- Searches and direct business URLs work in the same run.
- Output is normalized into stable business-profile fields.
- Full public profile pages enrich search results with contacts and weekly hours when visible.
- `maxItems` is enforced across all inputs, so run size is predictable.
- Duplicate aliases are saved only once.
- Invalid URLs and malformed searches fail with clear errors.
- Missing public fields are returned as `null` or empty arrays, not invented values.
- The implementation uses lightweight HTTP rather than a full browser or paid proxy route.

### What Yelp business data is extracted?

| Field | Meaning |
| --- | --- |
| `businessId` | Stable Yelp business identifier when exposed |
| `alias` | Alias in the Yelp profile URL |
| `name` | Public business name |
| `categories` | Yelp category labels |
| `rating` | Current rating summary shown by Yelp |
| `reviewCount` | Current public review count |
| `priceRange` | Yelp price indicator such as `$$`, when visible |
| `address` | Street, city/region/postal display, and combined address |
| `phone` | Public telephone number, when visible |
| `website` | Business website linked by Yelp, when visible |
| `hours` | Weekday opening intervals and current status when shown |
| `canonicalUrl` | Canonical Yelp business profile URL |
| `photoUrl` | Representative public Yelp photo URL, when visible |
| `isClosed` | Closed-business signal when Yelp exposes it |
| `sourceSearch` | Search term and location that discovered the record |
| `scrapedAt` | ISO 8601 extraction timestamp |

Yelp does not expose every field for every listing. Consumers should treat contact, website,
price, hours, photo, and closure fields as nullable.

### How to get started

1. Open the Actor input page.
2. Keep the prefilled San Francisco coffee-shop search or replace it.
3. Add more `{ "term", "location" }` pairs if needed.
4. Optionally add exact Yelp business URLs under **Yelp business URLs**.
5. Set **Maximum business profiles** to the output size you need.
6. Leave sponsored results disabled for organic research, or enable them intentionally.
7. Click **Start**.
8. Open the **Business profiles** dataset view.
9. Export JSON, CSV, Excel, XML, or RSS from Apify Dataset storage.

A small first run is recommended so you can confirm the category, location, and output fields
before scheduling a larger recurring job.

### Input parameters

#### `searches`

An array of objects with:

- `term`: a business keyword or category, for example `coffee shops` or `plumbers`.
- `location`: a city, neighborhood, postal code, or region, for example `Austin, TX`.

Both values must be non-empty. A term can contain up to 120 characters and a location up to
160 characters.

#### `startUrls`

Optional canonical Yelp business URLs matching `/biz/<alias>`.
URLs from non-Yelp hosts and non-business Yelp routes are rejected.

#### `maxItems`

Maximum unique business records saved across every search and direct URL.
Allowed range: 1–100. Default: 20.

#### `includeAds`

When `false` (default), sponsored search sections are excluded.
When `true`, sponsored businesses may be included and deduplicated with organic results.

At least one search or direct business URL is required.

### Input examples

Search one local category:

```json
{
  "searches": [
    { "term": "coffee shops", "location": "San Francisco, CA" }
  ],
  "maxItems": 5,
  "includeAds": false
}
```

Extract one exact business profile:

```json
{
  "searches": [],
  "startUrls": [
    { "url": "https://www.yelp.com/biz/gary-danko-san-francisco" }
  ],
  "maxItems": 1
}
```

Build a multi-market list:

```json
{
  "searches": [
    { "term": "plumbers", "location": "Austin, TX" },
    { "term": "plumbers", "location": "San Antonio, TX" }
  ],
  "maxItems": 40,
  "includeAds": false
}
```

### Output example

A current direct-profile run produced this shape (photo URL shortened for readability):

```json
{
  "businessId": "WavvLdfdP6g8aZTtbBQHTw",
  "alias": "gary-danko-san-francisco",
  "name": "Gary Danko",
  "categories": ["Restaurants", "New American"],
  "rating": 4.5,
  "reviewCount": 6139,
  "priceRange": null,
  "address": {
    "street": "800 N Point St",
    "cityStatePostal": "San Francisco, CA 94109",
    "formatted": "800 N Point St, San Francisco, CA 94109"
  },
  "phone": "(415) 749-2060",
  "website": "http://www.garydanko.com",
  "hours": [
    { "day": "Mon", "intervals": ["5:00 PM - 10:00 PM"], "status": "Closed now" }
  ],
  "canonicalUrl": "https://www.yelp.com/biz/gary-danko-san-francisco",
  "photoUrl": "https://s3-media0.fl.yelpcdn.com/bphoto/...",
  "isClosed": false,
  "sourceSearch": null,
  "scrapedAt": "2026-08-18T07:55:00.000Z"
}
```

Search-discovered records populate `sourceSearch`; direct-URL records use `null`.

### How much does it cost to extract Yelp business profiles?

The Actor uses pay-per-event pricing:

- one `start` event per run;
- one `item` event per business profile saved.

The start event is **$0.001**. The per-item event has six volume tiers, so its unit price decreases on higher Apify plans. The BRONZE item rate is **$0.0026 per saved business profile**; the exact rate for your plan is shown on the Actor pricing tab.

As a planning formula:

```text
estimated charge = $0.001 + (saved business profiles × your plan's item rate)
```

BRONZE examples:

| Saved profiles | Estimated charge |
| ---: | ---: |
| 1 | USD 0.0036 |
| 10 | USD 0.0270 |
| 100 | USD 0.2610 |

On the FREE tier, the item rate is $0.00299, so the same 10-profile run is USD 0.0309. You are not charged an item event for a duplicate, rejected, failed, or empty profile.

### Local prospecting and market-research workflows

#### Build a category prospect list

Search a category and city, export CSV, then filter by rating, review volume, or public contact
availability before importing selected records to your CRM.

#### Compare local markets

Run the same term across several locations. Group records by `sourceSearch.location` and compare
business count, category mix, ratings, and review volume.

#### Monitor public profile changes

Schedule a Task with exact `startUrls`. Store each run in your warehouse and compare rating,
review count, phone, website, address, and hours over time.
The Actor returns snapshots; it does not calculate changes or send alerts itself.

#### Enrich an existing Yelp URL list

Send canonical Yelp URLs from a spreadsheet or database, then join the returned records on
`canonicalUrl` or `businessId`.

### Export and integration options

Apify datasets can be downloaded as JSON, JSONL, CSV, Excel, XML, or RSS.
Common destinations include:

- Google Sheets through Make or Zapier;
- Airtable and CRM lead tables;
- BigQuery, Snowflake, PostgreSQL, or object storage;
- internal territory dashboards;
- scheduled webhooks and downstream Actors;
- Python, JavaScript, or command-line data pipelines.

Use `businessId` where available for durable joins. Use `canonicalUrl` as the portable fallback.

### Run through the Apify API

Replace `<APIFY_TOKEN>` with your token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~yelp-business-profiles-scraper/runs?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searches":[{"term":"plumbers","location":"Austin, TX"}],"maxItems":10}'
```

To wait for completion and receive dataset items:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~yelp-business-profiles-scraper/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searches":[{"term":"coffee shops","location":"San Francisco, CA"}],"maxItems":5}'
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/yelp-business-profiles-scraper').call({
  searches: [{ term: 'plumbers', location: 'Austin, TX' }],
  maxItems: 10,
  includeAds: false,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("automation-lab/yelp-business-profiles-scraper").call(run_input={
    "searches": [{"term": "plumbers", "location": "Austin, TX"}],
    "maxItems": 10,
    "includeAds": False,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with Apify MCP

Add this Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/yelp-business-profiles-scraper"
```

#### Claude Desktop, Cursor, and VS Code

Use this same MCP configuration in **Claude Desktop**, **Cursor**, or **VS Code**:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/yelp-business-profiles-scraper"
    }
  }
}
```

Example prompts:

- "Find five Yelp coffee shop profiles in San Francisco and return names, ratings, and URLs."
- "Extract the address, phone, website, and hours for these Yelp business URLs."
- "Build a ten-business plumber prospect list for Austin and format it as a table."

### Limits and expected behavior

- The Actor extracts public Yelp business profile data, not Yelp account or login data.
- It does not return reviews, reviewer data, emails, or private owner information.
- Yelp may omit phone, website, price, address details, photos, or opening hours.
- If profile-detail enrichment is rate-limited during a search run, the Actor preserves useful search-profile identity, category, rating, review-count, address, and URL records; contact, website, hours, and photo fields can remain empty for the affected records.
- Search ranking and profile values can change between runs.
- `maxItems` is capped at 100 per run.
- The default timeout is 15 minutes; large runs may need a smaller scope if upstream responses
  are unusually slow.
- Results are deduplicated by business alias, not by company ownership or physical address.
- Search results reflect the location interpretation returned by Yelp.
- Sponsored businesses are included only when `includeAds` is enabled.
- An unrecognized upstream page shape fails the run rather than returning misleading empty data.

### Legality and responsible use

Only collect and use data you are authorized to process.
Review Yelp's terms, applicable robots guidance, privacy requirements, and local laws for your
intended use.

Public business contact details are not blanket permission for unsolicited outreach.
Apply appropriate consent, suppression, retention, and opt-out practices.
Do not use this Actor for harassment, discrimination, surveillance, or attempts to access
private Yelp or business-owner accounts.

This Actor is an independent automation tool and is not affiliated with or endorsed by Yelp.

### Troubleshooting

#### The run says an input is required

Provide at least one valid `searches` entry or one canonical Yelp `/biz/` URL.
An empty object is intentionally rejected.

#### A start URL is rejected

Use a public Yelp business profile URL such as `https://www.yelp.com/biz/<alias>`.
Search pages, review anchors without a `/biz/` path, and other hosts are not direct-profile inputs.

#### A field is null or an array is empty

Check the public profile. Yelp does not show every contact, price, category, or hours field on
every business. The Actor does not infer missing values.

#### I received fewer records than expected

The source may have fewer matching organic profiles, and duplicates across searches are saved
once. Enable sponsored results only if those records fit your workflow.

#### The run failed on an upstream page

Retry once after checking Apify's status page and the run log. Persistent recognized-payload
errors indicate that the public source changed and should be reported with the run ID and input.
Do not add a proxy unless requested by a future Actor version; the current route does not use one.

### Frequently asked questions

#### Does the Actor require a Yelp API key or login?

No. It extracts fields visible on public Yelp search and business profile surfaces.

#### Can it search by category and location?

Yes. Put the category in `term` and the city, neighborhood, postal code, or region in `location`.

#### Can I supply exact business URLs?

Yes. Use `startUrls`, alone or together with searches.

#### Does it scrape reviews?

No. This Actor returns profile and rating-summary records. Use Yelp Business Reviews Scraper for
individual reviews and owner responses.

#### Can I schedule recurring monitoring?

Yes. Create an Apify Task from your input and schedule it. Persist consecutive datasets in your
own destination to calculate changes.

#### Are all contact fields guaranteed?

No. Contact, website, address, price, hours, photo, and closure signals depend on what Yelp shows
publicly for each business.

### Related Automation Lab Actors

- [Yelp Business Reviews Scraper](https://apify.com/automation-lab/yelp-business-reviews-scraper)
  extracts individual public reviews, ratings, reviewer metadata, dates, photos, and owner
  responses from supplied Yelp business URLs.

Use Business Profiles Scraper for discovery and normalized business records. Use Business Reviews
Scraper when the buyer job is reputation and review analysis.

# Actor input Schema

## `searches` (type: `array`):

Keyword or category and location pairs to search on Yelp.

## `startUrls` (type: `array`):

Optional canonical Yelp /biz/ profile URLs to extract directly.

## `maxItems` (type: `integer`):

Maximum unique business profile records saved across all searches and URLs.

## `includeAds` (type: `boolean`):

Include sponsored Yelp search results in addition to organic businesses.

## Actor input object example

```json
{
  "searches": [
    {
      "term": "coffee shops",
      "location": "San Francisco, CA"
    }
  ],
  "startUrls": [
    {
      "url": "https://www.yelp.com/biz/gary-danko-san-francisco"
    }
  ],
  "maxItems": 20,
  "includeAds": false
}
```

# Actor output Schema

## `overview` (type: `string`):

Normalized Yelp business profile records.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searches": [
        {
            "term": "coffee shops",
            "location": "San Francisco, CA"
        }
    ],
    "startUrls": [
        {
            "url": "https://www.yelp.com/biz/gary-danko-san-francisco"
        }
    ],
    "maxItems": 20,
    "includeAds": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/yelp-business-profiles-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searches": [{
            "term": "coffee shops",
            "location": "San Francisco, CA",
        }],
    "startUrls": [{ "url": "https://www.yelp.com/biz/gary-danko-san-francisco" }],
    "maxItems": 20,
    "includeAds": False,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/yelp-business-profiles-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searches": [
    {
      "term": "coffee shops",
      "location": "San Francisco, CA"
    }
  ],
  "startUrls": [
    {
      "url": "https://www.yelp.com/biz/gary-danko-san-francisco"
    }
  ],
  "maxItems": 20,
  "includeAds": false
}' |
apify call automation-lab/yelp-business-profiles-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/yelp-business-profiles-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ldn5bpwKwTDBL86PI/builds/ghbnjI1LySZ1xv3hr/openapi.json
