# MerchantCircle Business Data & Lead Scraper (`b2b_leads/merchantcircle-real-time-data-scraper`) Actor

Live MerchantCircle local business data: keyword + location search, full profiles, reviews & email discovery. Phones, websites, addresses, hours, ratings streamed to your dataset in real time. Free trial: 2 results per run.

- **URL**: https://apify.com/b2b_leads/merchantcircle-real-time-data-scraper.md
- **Developed by:** [Emmanuel](https://apify.com/b2b_leads) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## MerchantCircle Real-Time Data

Live local business intelligence from MerchantCircle — keyword + location search, full business profiles, customer reviews, and contact details for lead generation. Structured JSON streamed to your dataset in real time.

> **Free trial:** free Apify plans get **2 results per run**. Paid plans are uncapped. See Delivery & limits below.

### Who this is for

Agencies, local SEO teams, sales prospectors, and CRM builders who need fresh US small-business leads with phones, addresses, websites, hours, and reviews.

**Use cases:**

- Build outreach lists by trade + city (plumbers in Brooklyn, dentists in Austin)
- Enrich a CRM with phones, websites, addresses, and hours
- Monitor ratings and review volume across local competitors
- Power local-SEO audits with categories, photos, and review counts
- Feed AI agents with structured business profiles
- Track new businesses appearing for a keyword + ZIP

### Features

| Checkbox | What you get |
|---|---|
| 🔍 Business Search (default on) | Keyword + location tasks, fast cards: name, phone, address, photo |
| ✨ Enrich with full lead details | Same search row enriched in place (`detailsFetched: true`): website, hours, categories, rating, review count |
| ✉️ Discover emails from business websites | Checks each business website homepage for a public contact email, filled into the `email` column (off by default; adds a little extra time per record) |
| 🏢 Business Details | Full profile for explicit business URLs |
| ⭐ Reviews | Capped customer reviews per business: reviewer, rating, date, text |
| 🔗 Scrape By URL | Any MerchantCircle search, category hub, or business URL, auto-detected |
| 🔔 Webhooks | JSON or Slack push per record, in addition to the dataset |

### Input reference

- `country` (select, default `US`): market region. MerchantCircle is US-first; keep `US`.
- `enableBusinessSearch` (bool, default `true`)
- `searchTasks` (array, default `[{ keyword: "plumber", location: "Brooklyn, NY 11223" }]`): one task per keyword + location pair.
- `searchKeywords` + `searchLocation`: simple mode alternative to `searchTasks`.
- `searchMaxResults` (int 1–200, default `10`): max businesses per task.
- `searchFetchLeadDetails` (bool, default `false`): enrich each search row in place. Adds a little extra time per record.
- `enableBusinessDetails` (bool, default `false`) + `businessUrls` (stringList): full profiles.
- `enableReviews` (bool, default `false`) + `reviewBusinessUrls` (stringList, falls back to `businessUrls`) + `reviewsMaxPerBusiness` (int 1–100, default `20`).
- `enableScrapeByUrl` (bool, default `false`) + `scrapeUrls` (stringList).
- `webhookUrl` (string, default `""`), `webhookFormat` (`json` | `slack`, default `json`).
- `proxyConfiguration` (proxy editor, default Residential US).

Empty input still runs a useful demo: Business Search on, one plumber task, 10 rows.

Each enabled checkbox with empty required fields throws a clear feature-level error (e.g. Business Search on with no tasks).

### Output fields

One row per business (`business_search`, `business_details`), one row per review (`review`), structured rows for `scrape_by_url`. Filter views by `featureType`.

**Business fields:** `business_name`, `phone`, `website`, `email`, `street_address`, `city`, `region`, `postal_code`, `full_address`, `latitude`, `longitude`, `categories`, `about`, `hours`, `rating`, `review_count`, `logo_url`, `image_urls`, `position`, `detailsFetched`.

**Review fields:** `business_name`, `reviewer_name`, `review_rating`, `review_date`, `review_text`, `position`.

**Scrape By URL:** `pageType` (`search` | `hub` | `business`), `business_name`, `phone`, `data`.

### Webhook guide

Set `webhookUrl` to receive each record twice: once in the dataset, once POSTed to your URL.

- `json`: full record object — best for Zapier, Make, n8n, custom bots.
- `slack`: friendly message with business name, phone, location, rating, and link.

Delivery is fire-and-forget: failures never stop the run or dataset writes.

### MCP / AI-agent usage

Connect via the Apify MCP server, then ask:

> "Find 10 plumbers in Brooklyn NY on MerchantCircle with phones and websites, and send the top-rated ones to my webhook."

The agent maps this to `enableBusinessSearch` + `searchTasks` + `searchFetchLeadDetails`.

### FAQ

- **Which proxy should I use?** Residential US (the default) for the most reliable results at scale.
- **How does the free trial work?** Free Apify plans are capped at 2 results per run with an upgrade notice; the run still exits cleanly with a `paywall` summary on OUTPUT.
- **How fresh is the data?** Every run collects live directory results at run time — what you see is what is listed now.
- **Do enriched searches duplicate rows?** No. Enrichment merges into the same `business_search` row (`detailsFetched: true`).
- **Is anything filtered out?** No. Every discovered business is exported.
- **Where do emails come from?** MerchantCircle listings do not publish email addresses, so the `email` column is filled by checking each business's own website homepage when email discovery is on. Businesses without a website (or without a public email on it) return `email: null` — never guessed, never faked.

### Delivery & limits

- Streams each record as collected; RAM stays light on large runs.
- Run timeout: 10,000 seconds.
- Free-tier: max 2 items in `limit` mode with an upgrade warning; 0 items in owner-configured `block` mode.
- PPE: charges event `result` per dataset row (override with `PPE_EVENT_NAME`).

# Actor input Schema

## `country` (type: `string`):

MerchantCircle is a US local business directory. Keep US for the most reliable results.

## `enableBusinessSearch` (type: `boolean`):

Live keyword + location search across MerchantCircle — plumbers, dentists, restaurants, salons, and more. On by default and prefilled so you can click Start and get results in seconds.

## `searchTasks` (type: `array`):

One task per keyword + location pair, e.g. plumber in Brooklyn, NY 11223. Required when Business Search is on.

## `searchKeywords` (type: `array`):

Alternative to search tasks: keywords only, paired with searchLocation below.

## `searchLocation` (type: `string`):

Shared location used with searchKeywords, e.g. Brooklyn, NY 11223.

## `searchMaxResults` (type: `integer`):

Maximum businesses to return for each keyword + location task (1–200). Default 10 — perfect for instant demo runs.

## `searchFetchLeadDetails` (type: `boolean`):

When on, each search result stays ONE row (featureType business_search, detailsFetched=true) but is enriched with full address, website, hours, categories, rating, and review count. Adds a little extra time per record. When off, you get fast search cards with name, phone, address, and image. Every discovered business is always saved — never filtered out.

## `discoverEmails` (type: `boolean`):

When on, each business with a website gets its homepage checked for a public contact email, filled into the email column. Adds a little extra time per record. MerchantCircle listings themselves do not publish emails, so this is how the email column gets filled.

## `enableBusinessDetails` (type: `boolean`):

Fetch the full profile for specific MerchantCircle businesses by URL.

## `businessUrls` (type: `array`):

Full MerchantCircle business URLs (https://www.merchantcircle.com/...).

## `enableReviews` (type: `boolean`):

Collect customer reviews for specific MerchantCircle businesses by URL.

## `reviewBusinessUrls` (type: `array`):

Business URLs to collect reviews from. Leave empty to reuse Business URLs above.

## `reviewsMaxPerBusiness` (type: `integer`):

Maximum reviews to collect per business (1–100).

## `enableScrapeByUrl` (type: `boolean`):

Paste any MerchantCircle URL — search page, category hub, or single business.

## `scrapeUrls` (type: `array`):

Any MerchantCircle search, category, or business URL.

## `webhookUrl` (type: `string`):

Optional. Every record is always saved to the run dataset — this webhook is an ADDITIONAL real-time push. Each new row is also POSTed to this URL (Slack, Discord, Zapier, Make, n8n, custom outreach bot).

## `webhookFormat` (type: `string`):

json = full record object; slack = Slack-friendly message payload.

## `proxyConfiguration` (type: `object`):

Residential proxy recommended for the most reliable results at scale.

## Actor input object example

```json
{
  "country": "US",
  "enableBusinessSearch": true,
  "searchTasks": [
    {
      "keyword": "plumber",
      "location": "Brooklyn, NY 11223"
    }
  ],
  "searchKeywords": [],
  "searchLocation": "Brooklyn, NY 11223",
  "searchMaxResults": 10,
  "searchFetchLeadDetails": false,
  "discoverEmails": false,
  "enableBusinessDetails": false,
  "businessUrls": [],
  "enableReviews": false,
  "reviewBusinessUrls": [],
  "reviewsMaxPerBusiness": 20,
  "enableScrapeByUrl": false,
  "scrapeUrls": [
    "https://www.merchantcircle.com/search?q=plumber&qn=Brooklyn%2C+NY+11223"
  ],
  "webhookUrl": "",
  "webhookFormat": "json",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `allResults` (type: `string`):

Full dataset for this run (every featureType).

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

Core fields across features, including detailsFetched for search rows.

## `search` (type: `string`):

featureType=business_search only. One business = one row; full details are merged when "Enrich with full lead details" is enabled.

## `details` (type: `string`):

featureType=business_details — only from the Business Details feature (specific URLs), not from search enrichment.

## `reviews` (type: `string`):

featureType=review — one row per customer review.

## `scrape_by_url` (type: `string`):

No description

# 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 = {
    "country": "US",
    "enableBusinessSearch": true,
    "searchTasks": [
        {
            "keyword": "plumber",
            "location": "Brooklyn, NY 11223"
        }
    ],
    "searchKeywords": [],
    "searchLocation": "Brooklyn, NY 11223",
    "searchMaxResults": 10,
    "searchFetchLeadDetails": false,
    "discoverEmails": false,
    "enableBusinessDetails": false,
    "businessUrls": [],
    "enableReviews": false,
    "reviewBusinessUrls": [],
    "reviewsMaxPerBusiness": 20,
    "enableScrapeByUrl": false,
    "scrapeUrls": [
        "https://www.merchantcircle.com/search?q=plumber&qn=Brooklyn%2C+NY+11223"
    ],
    "webhookFormat": "json",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("b2b_leads/merchantcircle-real-time-data-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 = {
    "country": "US",
    "enableBusinessSearch": True,
    "searchTasks": [{
            "keyword": "plumber",
            "location": "Brooklyn, NY 11223",
        }],
    "searchKeywords": [],
    "searchLocation": "Brooklyn, NY 11223",
    "searchMaxResults": 10,
    "searchFetchLeadDetails": False,
    "discoverEmails": False,
    "enableBusinessDetails": False,
    "businessUrls": [],
    "enableReviews": False,
    "reviewBusinessUrls": [],
    "reviewsMaxPerBusiness": 20,
    "enableScrapeByUrl": False,
    "scrapeUrls": ["https://www.merchantcircle.com/search?q=plumber&qn=Brooklyn%2C+NY+11223"],
    "webhookFormat": "json",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("b2b_leads/merchantcircle-real-time-data-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 '{
  "country": "US",
  "enableBusinessSearch": true,
  "searchTasks": [
    {
      "keyword": "plumber",
      "location": "Brooklyn, NY 11223"
    }
  ],
  "searchKeywords": [],
  "searchLocation": "Brooklyn, NY 11223",
  "searchMaxResults": 10,
  "searchFetchLeadDetails": false,
  "discoverEmails": false,
  "enableBusinessDetails": false,
  "businessUrls": [],
  "enableReviews": false,
  "reviewBusinessUrls": [],
  "reviewsMaxPerBusiness": 20,
  "enableScrapeByUrl": false,
  "scrapeUrls": [
    "https://www.merchantcircle.com/search?q=plumber&qn=Brooklyn%2C+NY+11223"
  ],
  "webhookFormat": "json",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call b2b_leads/merchantcircle-real-time-data-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,b2b_leads/merchantcircle-real-time-data-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/W6Okj2jbWejc6EnQO/builds/U0FU5hvJp00hs2Qi2/openapi.json
