# Businesses Without a Website — Google Maps Lead Finder (`northvane/no-website-business-leads-google-maps`) Actor

Finds local businesses with no working website, verified instead of assumed: every listed site is actually fetched, so parked, expired and dead domains count as leads too. Returns the phone number to reach them. You are only charged for qualified leads.

- **URL**: https://apify.com/northvane/no-website-business-leads-google-maps.md
- **Developed by:** [Northvane](https://apify.com/northvane) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 qualified leads

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/actors/running/actors-in-store.md#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

## Businesses Without a Website — Google Maps Lead Finder

**Find local businesses that have no working website, and get the phone number to call them.** Give it a trade and a city — `plumber` in `Phoenix, AZ` — and it returns every business Google Maps knows about that has no web presence, with phone, address, category, rating and a one-line reason.

**You are only charged for qualified leads.** Every business the Actor checks and rejects costs you nothing. Sweeping 500 businesses to find 60 leads bills you for 60.

### The part other no-website scrapers get wrong

Every other Actor in this niche reads Google's "website" field and trusts it. That field lies, and it lies in the direction that costs you money: a business lists a domain that was parked two years ago, or expired, or redirects to a GoDaddy sale page, or now serves gambling spam. Google still shows it as having a website. Those businesses have **no working web presence** — they are the best leads on the list — and every tool in this category silently filters them out.

This Actor **actually fetches every listed website** and classifies what comes back:

| Status | What it means |
|---|---|
| `NONE_LISTED` | Google Maps lists no website at all. |
| `DEAD` | The domain does not resolve, refuses the connection, times out, or returns 404 at the root. |
| `PARKED` | A registrar or hosting parking page — GoDaddy lander, Sedo, ParkingCrew, Namecheap. |
| `FOR_SALE` | A domain marketplace page: HugeDomains, Dan, Afternic, "this domain is for sale". |
| `PLACEHOLDER` | "Coming soon", "site not published", suspended account, default nginx/Apache/WordPress page. |
| `EXPIRED` | An expired domain or hosting notice. |
| `REDIRECTED_OFF_DOMAIN` | The domain now sends visitors to a different company entirely. |
| `SUSPICIOUS_CONTENT` | The domain was re-registered and serves unrelated spam. |

In a real sample of 82 listed businesses, **11% were in one of these states** — dead, parked, or repurposed — while still appearing as normal listings upstream. Turn off **Include businesses whose listed website is dead** if you only want the businesses Maps already admits have nothing.

### What you get per lead

`name` · `phone` (E.164) · `phoneFormatted` · `address` · `category` and `categories` · `rating` · `lat` / `lng` · `placeId` and `mapsUrl` · `openState` · `listedWebsite` · `websiteStatus` · `websiteStatusReason` (the actual observation — matched signature, HTTP code, DNS failure) · `leadReason` (a plain sentence you can paste into a CRM) · `socialsFound` · `searchTerm`.

`leadReason` reads like: *"Listed website http://example-plumbing.com is a parked domain."* — so whoever makes the call knows the angle before they dial.

### Free filters

**Only businesses with a phone number**, **minimum rating**, **maximum rating** (find the ones with reputation problems as well as no website), and the dead-website toggle. Filters run before billing — a business dropped by a filter is never charged.

### How to use it

Pick trades where the no-website rate is genuinely high. Measured on live searches: **taquerias 55%, nail salons 20%, barber shops 20%, dentists 0%.** Independent food, personal-care and trade businesses are full of leads; professional services and franchises are not. Search two or three related terms at once and widen the radius (`zoom` 11) before you increase the count.

```js
const run = await client.actor('<your-username>/no-website-business-leads-google-maps').call({
    searchTerms: ['plumber', 'hvac contractor', 'roofing contractor'],
    location: 'Phoenix, AZ',
    maxPlacesPerSearch: 300,
    requirePhone: true,
});
```

Two output views in the Console: **Leads** (everything) and **Dead & parked domains** (the ones nobody else finds).

### Pricing

Pay per qualified lead. Businesses checked and rejected are free, so a wide sweep costs the same as a narrow one that happened to hit — you pay for results, not for looking.

### FAQ

**Why did a big city return few leads?** Some categories are near-saturated online. Dentists in Austin: zero out of a hundred without a website. Try trades, food, or personal care.

**Does it need a proxy?** No, not at normal volume. Turn on Apify proxy for very large sweeps.

**Is the phone number reliable?** It comes from Google Maps itself, in E.164 form, and it's the field these businesses actually maintain — a business with no website usually still answers the phone.

**Can I get their email too?** Not from here, because these businesses have no site to read one from. If you want emails from businesses that *do* have websites, use **Google Maps Email Extractor & Dead Website Checker** by the same developer.

**Does it respect robots.txt?** It reads public Google Maps results and fetches one page per listed website, with a normal browser user-agent, and does not crawl. Use it on businesses you have the right to contact.

# Actor input Schema

## `searchTerms` (type: `array`):

What to look for on Google Maps, one per line — `plumber`, `nail salon`, `roofing contractor`, `dentist`. Trades and small service businesses have the highest rate of no website.

## `location` (type: `string`):

Where to search: `Phoenix, AZ`, `Leeds, UK`, or any address Google Maps can resolve.

## `maxPlacesPerSearch` (type: `integer`):

How many businesses to look at per term. Only the ones without a working website are billed, so a wide sweep is cheap — checking 500 to find 60 leads costs you 60 rows.

## `zoom` (type: `integer`):

11 covers a whole city, 12 a large district (default), 14 a neighbourhood. Lower numbers cover more ground.

## `includeDeadWebsites` (type: `boolean`):

On by default, and it is where a third of the value is. Google Maps often lists a domain that is parked, expired, for sale or serving spam — those businesses have no working web presence either, and nobody else's lead list catches them.

## `requirePhone` (type: `boolean`):

These leads have no website, so the phone is usually the only way to reach them. Free filter.

## `minRating` (type: `number`):

Drop businesses rated below this (0 = off). Free filter.

## `maxRating` (type: `number`):

Drop businesses rated above this (0 = off). Free filter.

## `verifyWebsites` (type: `boolean`):

Leave on. With this off the Actor trusts Google's website field, which is what every other no-website scraper does — and it misses every parked and dead domain.

## `maxLeads` (type: `integer`):

0 = no limit.

## `timeoutSecs` (type: `integer`):

A site that does not answer in this window counts as dead. 12s is plenty — a working business site answers in under two.

## `maxConcurrency` (type: `integer`):

How many websites are verified in parallel.

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

Off by default and not needed at normal volume. Turn on Apify proxy if a big sweep starts getting blocked.

## Actor input object example

```json
{
  "searchTerms": [
    "nail salon"
  ],
  "location": "San Antonio, TX",
  "maxPlacesPerSearch": 30,
  "zoom": 12,
  "includeDeadWebsites": true,
  "requirePhone": false,
  "minRating": 0,
  "maxRating": 0,
  "verifyWebsites": true,
  "maxLeads": 0,
  "timeoutSecs": 12,
  "maxConcurrency": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `leads` (type: `string`):

Every business with no working website, with phone, address, category and the reason it qualified.

## `deadDomains` (type: `string`):

The subset whose listed website is parked, expired, redirected or dead.

## `summary` (type: `string`):

How many businesses were checked, how many had no site on Maps, how many had a dead site, and how many were filtered out.

# 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 = {
    "searchTerms": [
        "nail salon"
    ],
    "location": "San Antonio, TX",
    "maxPlacesPerSearch": 30,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("northvane/no-website-business-leads-google-maps").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 = {
    "searchTerms": ["nail salon"],
    "location": "San Antonio, TX",
    "maxPlacesPerSearch": 30,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("northvane/no-website-business-leads-google-maps").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 '{
  "searchTerms": [
    "nail salon"
  ],
  "location": "San Antonio, TX",
  "maxPlacesPerSearch": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call northvane/no-website-business-leads-google-maps --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,northvane/no-website-business-leads-google-maps"
        }
    }
}

```

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/akzK1S96bXp3aKHKU/builds/SCCZLbTeJrVChJpLF/openapi.json
