# YellowPages Chain Locations Scraper (`axlymxp/yellowpages-chain-locations-scraper`) Actor

Build a store locator dataset for any US retail brand. Enter a name like Starbucks or AutoZone and get every YellowPages location with address, phone, GPS, categories, hours and ratings as structured JSON — ideal for site selection and competitor mapping. Pay only for the results you get.

- **URL**: https://apify.com/axlymxp/yellowpages-chain-locations-scraper.md
- **Developed by:** [axly](https://apify.com/axlymxp) (community)
- **Categories:** Business, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 dataset items

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

## YellowPages Chain Locations Scraper

**Get every US location of any retail brand — from a brand name alone.**

Type `Starbucks`, `AutoZone` or `Walgreens` and this Actor returns a complete store-locator dataset: address, phone, GPS coordinates, categories, ratings and opening hours for each location, as structured JSON.

No store-locator page to crawl, no chain IDs to look up, no per-city scripting. Enter a brand, get its footprint.

***

### Who uses this

| You are | You use it to |
| ------- | ------------- |
| **Retail / location analyst** | Map a brand's national footprint for site selection, trade-area and cannibalization analysis. |
| **Investor / alt-data analyst** | Track store counts per brand over time — schedule runs and diff the datasets to spot expansion or contraction. |
| **Competitive intelligence team** | Compare your locations against a rival's, metro by metro. |
| **Franchise / B2B sales team** | Reach every franchise location of a target brand with address and phone. |
| **GIS / PropTech developer** | A clean, mappable location dataset with GPS on every row. |

***

### What you get — output fields

| Field | Type | Description |
| ----- | ---- | ----------- |
| `brand` | string | The brand you searched for. |
| `chainId` | string | YellowPages chain identifier for that brand. |
| `ypid` | string | Stable YellowPages ID for this specific location. |
| `listingId` | string | Internal listing identifier. |
| `name` | string | Location name as listed. |
| `phone` | string | Formatted phone number for that location. |
| `address` | object | `street`, `city`, `state`, `zip` as separate fields. |
| `addressFormatted` | string | Full address on one line. |
| `latitude` / `longitude` | number | GPS coordinates — ready for mapping and spatial analysis. |
| `primaryCategory` | string | Main category heading. |
| `categories` | array | All categories this location is listed under. |
| `rating` | number | Average star rating (0–5). |
| `ratingCount` | integer | Number of ratings. |
| `reviewCount` | integer | Number of written reviews. |
| `isClaimed` | boolean | Whether the location's listing is claimed. |
| `yearEstablished` | string | Year established, where published. |
| `openNow` / `open24Hours` | boolean | Current open state and 24-hour flag. |
| `hoursText` | string | Opening hours as displayed text.¹ |
| `hours` | object | Machine-readable hours, e.g. `{"monday": "0530-2100"}`.¹ |
| `email` | string | Location email address.¹ |
| `website` | string | Location website.¹ |
| `services` / `amenities` / `paymentMethods` | array | Additional location attributes.¹ |
| `socialLinks` | array | Social profile URLs. |
| `photos` | array | Photo URLs. |
| `yellowPagesUrl` | string | Public YellowPages profile URL for the location. |
| `anchorLocation` | string | The sweep anchor city this location was found from. |
| `distanceFromAnchorMiles` | number | Distance from that anchor. |
| `scrapedAt` | string | UTC extraction timestamp (ISO 8601). |

¹ Requires **Include full location details**.

***

### How it works

YellowPages returns chain locations relative to a geographic anchor, so this Actor sweeps a list of **anchor cities** at a wide radius and merges the results, removing duplicates by location ID. The default anchors cover the contiguous US; add or narrow them to target a specific region.

You can also skip brand resolution entirely and pass `chainIds` directly if you already know them.

***

### High-value use cases

**1. Map a competitor's national footprint.**
Run a rival brand, export the GPS columns, and plot every location to see which metros they dominate and which they have not entered.

**2. Track store openings and closures.**
Schedule a monthly run per brand and diff on `ypid` — new IDs are openings, missing IDs are likely closures. A simple alternative-data signal.

**3. Site selection and white-space analysis.**
Combine two or three brands in one run and look for trade areas served by competitors but not by you.

**4. Franchise outreach lists.**
Pull every location of a franchise brand with phone and address for territory-based B2B campaigns.

**5. Build a store-locator dataset for your app.**
Get a clean, mappable location table for any brand without maintaining a scraper per retailer.

***

### Input parameters

| Parameter | Type | Default | Description |
| --------- | ---- | ------- | ----------- |
| `brands` | array | `["Starbucks"]` | Brand names. Automatically resolved to chain IDs. |
| `chainIds` | array | `[]` | Pass chain IDs directly and skip brand resolution. |
| `anchorLocations` | array | Major US metros | Cities used to sweep the country. |
| `radiusMiles` | integer | `500` | Search radius around each anchor. |
| `maxLocationsPerBrand` | integer | `2000` | Cap per brand. |
| `maxItems` | integer | `5000` | Total result cap for the run. |
| `includeDetails` | boolean | `false` | Adds hours, email, website, services and payment methods per location. |
| `proxyConfiguration` | object | off | Optional — not normally needed. |

***

### Example input

```json
{
  "brands": ["Starbucks", "AutoZone"],
  "anchorLocations": ["Seattle, WA", "Denver, CO", "Chicago, IL", "Atlanta, GA"],
  "radiusMiles": 500,
  "maxLocationsPerBrand": 1000,
  "includeDetails": false,
  "maxItems": 2000
}
```

### Example output

```json
{
  "brand": "Starbucks",
  "chainId": "100032",
  "ypid": "459125427",
  "listingId": "459125427",
  "name": "Starbucks Coffee",
  "phone": "(206) 467-2766",
  "address": {
    "street": "2401 Utah Ave S",
    "city": "Seattle",
    "state": "WA",
    "zip": "98134"
  },
  "addressFormatted": "2401 Utah Ave S, Seattle, WA 98134",
  "latitude": 47.581757,
  "longitude": -122.33532,
  "primaryCategory": "Coffee & Espresso Restaurants",
  "categories": ["Coffee & Espresso Restaurants", "Coffee & Tea", "Coffee Shops"],
  "rating": 4.5,
  "ratingCount": 2,
  "reviewCount": 2,
  "isClaimed": false,
  "yearEstablished": "1971",
  "openNow": false,
  "yellowPagesUrl": "http://www.yellowpages.com/seattle-wa/mip/starbucks-coffee-459125427",
  "anchorLocation": "Seattle, WA",
  "distanceFromAnchorMiles": 1.7,
  "scrapedAt": "2026-09-18T08:16:56Z"
}
```

***

### Scheduling, webhooks and integrations

- **Schedule** a run per brand to build a time series of store counts.
- **Webhooks** notify your systems the moment a run completes.
- **Export** to JSON, CSV, Excel, XML or JSONL — or pull from the Dataset API.
- **Integrations**: Google Sheets, Zapier, Make, Slack, Airbyte, Amazon S3 and Google Drive.

```bash
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=csv&clean=true"
```

***

### Use it from an AI assistant (MCP)

This Actor is callable over the **Model Context Protocol**, so assistants such as Claude, ChatGPT or Cursor can run it as a tool.

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/actors-mcp-server", "--actors", "axlymxp/yellowpages-chain-locations-scraper"],
      "env": { "APIFY_TOKEN": "<YOUR_APIFY_TOKEN>" }
    }
  }
}
```

Then ask: *"Get every AutoZone location in the western US with addresses and coordinates."*

***

### FAQ

**Do I need to know the chain ID?**
No. Enter the brand name and the Actor resolves it automatically. If you already have chain IDs, you can pass them directly via `chainIds`.

**How complete is the coverage?**
Coverage depends on your anchor cities and radius. The defaults sweep the contiguous US; add anchors (or increase `maxLocationsPerBrand`) for denser brands, or use a single anchor with a small radius to target one region.

**Will I get duplicate locations?**
No. Anchor searches overlap by design, and every location is de-duplicated by its YellowPages ID before being written to the dataset.

**What if a brand can't be found?**
The run logs a warning, skips that brand and continues with the rest — it does not fail.

**How fresh is the data?**
Every run fetches live data at request time, and each row carries a `scrapedAt` timestamp.

**Can I run several brands at once?**
Yes. Pass multiple names in `brands`; each row is tagged with its `brand` and `chainId` so results are easy to split.

**Is scraping this data legal?**
The Actor collects only publicly available business location information — the same data any visitor can see without logging in. No accounts, private data or logins are involved. You remain responsible for using the output in line with applicable laws.

**Can I get support?**
Yes — open an issue on the Actor's Issues tab.

# Actor input Schema

## `brands` (type: `array`):

Retail or franchise brand names to resolve to YellowPages chain IDs, e.g. Starbucks, Walgreens, AutoZone. Each brand is swept across all anchor locations.

## `chainIds` (type: `array`):

Known YellowPages chain IDs to scrape directly, skipping brand-name resolution. Starbucks is 100032.

## `anchorLocations` (type: `array`):

US metro anchors used for the geo sweep. chain\_search requires an anchor location; large radiuses overlap, and the actor deduplicates locations by ypid.

## `radiusMiles` (type: `integer`):

Radius override sent to YellowPages chain\_search for each anchor. 500 miles was verified to expand Starbucks coverage substantially.

## `maxLocationsPerBrand` (type: `integer`):

Stop collecting a brand after this many unique, deduplicated locations.

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

Global run cap across all brands and chain IDs.

## `includeDetails` (type: `boolean`):

Fetch each location's detail endpoint to enrich rows with merchant website, email, expanded hours, services, payment methods and other profile fields. Off by default for high-volume chain runs.

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

Optional. The mobile YellowPages API does not require a proxy, so this can normally stay disabled.

## Actor input object example

```json
{
  "brands": [
    "Starbucks"
  ],
  "chainIds": [],
  "anchorLocations": [
    "Seattle, WA",
    "San Francisco, CA",
    "Los Angeles, CA",
    "Phoenix, AZ",
    "Denver, CO",
    "Dallas, TX",
    "Houston, TX",
    "Chicago, IL",
    "Minneapolis, MN",
    "Atlanta, GA",
    "Miami, FL",
    "New York, NY",
    "Boston, MA"
  ],
  "radiusMiles": 500,
  "maxLocationsPerBrand": 2000,
  "maxItems": 5000,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "brands": [
        "Starbucks"
    ],
    "chainIds": [],
    "anchorLocations": [
        "Seattle, WA",
        "San Francisco, CA",
        "Los Angeles, CA",
        "Phoenix, AZ",
        "Denver, CO",
        "Dallas, TX",
        "Houston, TX",
        "Chicago, IL",
        "Minneapolis, MN",
        "Atlanta, GA",
        "Miami, FL",
        "New York, NY",
        "Boston, MA"
    ],
    "radiusMiles": 500,
    "maxLocationsPerBrand": 2000,
    "maxItems": 5000,
    "includeDetails": false,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axlymxp/yellowpages-chain-locations-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 = {
    "brands": ["Starbucks"],
    "chainIds": [],
    "anchorLocations": [
        "Seattle, WA",
        "San Francisco, CA",
        "Los Angeles, CA",
        "Phoenix, AZ",
        "Denver, CO",
        "Dallas, TX",
        "Houston, TX",
        "Chicago, IL",
        "Minneapolis, MN",
        "Atlanta, GA",
        "Miami, FL",
        "New York, NY",
        "Boston, MA",
    ],
    "radiusMiles": 500,
    "maxLocationsPerBrand": 2000,
    "maxItems": 5000,
    "includeDetails": False,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axlymxp/yellowpages-chain-locations-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 '{
  "brands": [
    "Starbucks"
  ],
  "chainIds": [],
  "anchorLocations": [
    "Seattle, WA",
    "San Francisco, CA",
    "Los Angeles, CA",
    "Phoenix, AZ",
    "Denver, CO",
    "Dallas, TX",
    "Houston, TX",
    "Chicago, IL",
    "Minneapolis, MN",
    "Atlanta, GA",
    "Miami, FL",
    "New York, NY",
    "Boston, MA"
  ],
  "radiusMiles": 500,
  "maxLocationsPerBrand": 2000,
  "maxItems": 5000,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axlymxp/yellowpages-chain-locations-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axlymxp/yellowpages-chain-locations-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/uvDmVCTKpIRNTYCOb/builds/8mPyER8Fekv22rVtc/openapi.json
