# No Website Leads - Businesses Without a Real Website (`sandy_yclept/no-website-leads`) Actor

Find local businesses on Google Maps without a real website: none listed, only a Facebook or booking page, a free builder site, or a dead or parked domain. No website leads with phone and address. Charged per lead; the search is billed per place by the Google Maps scraper it runs, $0.50 per 1,000.

- **URL**: https://apify.com/sandy\_yclept/no-website-leads.md
- **Developed by:** [Rafal Sav](https://apify.com/sandy_yclept) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 no-website leads

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

### What does No Website Leads do?

**No Website Leads** finds **local businesses on Google Maps that have no real website** — the leads a web design agency is looking for. Type a trade and a place — `handyman`, `hair salon`, `auto repair` in `Houston, TX, USA` — and you get one record per business that has **no website listed**, only a **Facebook, Instagram, Linktree or booking page**, a site on a **website builder's free subdomain**, or a **dead, parked or broken domain**. Each record carries the business's **phone, address, category, rating and number of reviews** from Google Maps, and **the reason it counts as a lead**.

You **pay only for leads you can reach** — a business with a phone number on Google Maps, or the page it uses instead of a website. Businesses with a working website cost nothing.

It runs on the [Apify platform](https://apify.com): API access, scheduling, integrations (Make, Zapier, n8n, Google Sheets) and run monitoring included.

### Why use it?

- **More leads from the same search.** Tools that keep only places with an empty website field miss every business whose "website" is an Instagram profile, a Fresha booking page, a free Wix or Square site, or a domain that expired years ago. On 300 businesses from Google Maps, **95 had no real website; 35 of them listed one** — 58% more leads than the empty-field filter finds in the same search (September 2026, details below).
- **Every website is checked the way a customer would reach it.** Its DNS, every spelling a browser tries (`www.` or not, `https` or plain `http`), where the domain forwards, the page it shows — parked, expired, suspended, never built, a web server's default page — and the networks of the big domain-parking services.
- **Nothing uncertain is sold.** A website that refuses the check, fails on the server or does not answer in time is `unknown`, and never a lead: a firewall saying "no" says the site exists.
- **Deep searches by default.** Businesses without a website rank low on Google Maps: **9% of the first ten places were leads, 44% of places 61-100**. The Actor reads 100 places per search term unless you change it.
- **Only reachable leads are billed.** 92 of the 95 leads had a phone number on Google Maps or a page to message; the other 3 are returned free.

### Use cases

- **Web design and development agencies** and freelancers — businesses that need a first website, or a real one.
- **Local SEO and marketing agencies** — businesses whose Google listing points at a dead page or a social profile.
- **Website builders, hosting and domain resellers** — owners of expired domains and free builder sites ready for an upgrade.

### How to use it

1. Enter one or more **Search terms** — trades, as you would type them into Google Maps — and a **Location**.
2. Keep **Places per search term** at 100 or more: the leads sit deep in the results.
3. Optionally narrow **Which businesses count as leads**.
4. Click **Start**. Leads appear in the dataset as the websites are checked; download them as JSON, CSV, Excel or HTML.

Already have places from a Google Maps scrape? Give its dataset instead of search terms, and nothing is paid for finding them again.

### Input

| Field | What it does |
|---|---|
| Search terms | What you would type into Google Maps, one per line: `handyman`, `hair salon`, `auto repair`. |
| Location | Where to search: a city and country work best (`Houston, TX, USA`, `Birmingham, United Kingdom`). |
| Places per search term | How many places to take per term (default 100). Also caps what the search costs. |
| Which businesses count as leads | Any of the four lead types below (all by default). |
| Also return businesses that have a website | Return every place with its `lead_type`, not only the leads. Only leads are charged. |
| Language | Language of the names, categories and addresses Google Maps returns. |
| Where the places come from | `scraperlink` (default; compass takes over when it finds nothing) or `compass`. |
| Google Maps dataset | Places you already have — any Google Maps export with a name and a website field. |

### Output

One record per lead. The values below are illustrative:

```json
{
  "name": "Lone Star Handyman",
  "category": "Handyman",
  "phone": "+17135550142",
  "address": "Houston, TX",
  "city": "Houston",
  "country_code": "US",
  "lead_type": "broken_website",
  "lead_reason": "the domain does not resolve: no DNS record for a website",
  "website": "https://lonestarhandyman.example/",
  "page_url": null,
  "rating": 4.8,
  "reviews_count": 37,
  "google_maps_url": "https://www.google.com/maps/search/?api=1&query=Lone%20Star%20Handyman&query_place_id=...",
  "place_id": "ChIJ...",
  "search_string": "handyman in Houston, TX, USA",
  "rank": 64,
  "billed": true
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

| `lead_type` | Meaning | Example `lead_reason` |
|---|---|---|
| `no_website` | Google Maps lists no website. | `Google Maps lists no website` |
| `platform_page` | The "website" is a page on a platform — Facebook, Instagram, Linktree, Booksy, Fresha, Treatwell, Vagaro, Yelp… — or the domain forwards to one. `page_url` holds the page. | `the domain forwards to https://linktr.ee/…` |
| `builder_subdomain` | A site on a website builder's subdomain, no domain of its own: wixsite.com, square.site, blogspot.com, carrd.co, Google Sites… | `a site on square.site, no domain of its own` |
| `broken_website` | The domain does not exist, is parked or for sale, has expired, shows a placeholder or a server's default page, has an invalid SSL certificate, or its homepage is not found. | `a parked domain: it points at a domain parking service` |

With **Also return businesses that have a website** on, you also get `has_website`, `unknown` (the check was refused, failed on the server or timed out) and `closed` (permanently closed on Google Maps) — never charged.

| Field | Meaning |
|---|---|
| `phone`, `address`, `city`, `country_code`, `category` | As Google Maps shows them. |
| `rating`, `reviews_count` | Google rating and number of reviews: an established business with 50 reviews and no website is a warm lead. |
| `website` | What Google Maps lists as the website, without tracking parameters. |
| `page_url` | The page the business uses instead of a website of its own. |
| `billed` | Whether this lead was charged. |
| `search_string`, `rank` | The search that found it, and its position in the results. |

### Accuracy

On **September 26, 2026** we took 100 places for each of three searches — `handyman in Houston, TX`, `auto repair in Phoenix, AZ` and `hair salon in Birmingham, UK` — and checked every website with this Actor's engine:

| Of 300 businesses | |
|---|---|
| No website on Google Maps | 60 |
| Only a social or booking page (Instagram 3, Facebook 3, Fresha 3, Linktree 2, Booksy 2, Treatwell 1) | 14 |
| A site on a builder's subdomain | 6 |
| Broken: 9 domains that no longer exist, 4 parked, 1 expired certificate, 1 homepage not found | 15 |
| **Leads** | **95 (32%)** |
| Reachable (phone on Google Maps or a page) | 92 |

Each of the 35 leads that listed a website was reviewed, and every domain called dead was confirmed with DNS on both spellings. By trade: handymen 46%, hair salons 32%, auto repair 17%. By position in the results: 3 of 32 places in the first ten, 53 of 120 among places 61-100. Restaurants rarely qualify: none of the first ten places for restaurants in four cities did.

### How much does it cost?

Two things are paid, both only for what is delivered:

- **Lead — $0.002** (~$2 per 1,000), charged by this Actor for each business without a real website that has a phone number on Google Maps or a page it uses instead. A business with a working website, one that could not be checked, a closed one, or one with no phone and no page: **$0**.
- **The Google Maps search.** It runs in a separate run on your account, which bills its own places. By default that is [scraperlink's Google Maps Scraper](https://apify.com/scraperlink/google-maps-scraper) — **$0.50 per 1,000 places** on the Free and Starter plans, $0.40 on higher ones, at least 10 per search term — and when it finds nothing, [compass's Google Maps Scraper](https://apify.com/compass/crawler-google-places) takes over — $4 per 1,000 places on the Free plan. Their paid add-ons are never switched on. Checking a dataset you already have skips this part entirely.

100 handymen in Houston cost about **$0.05** for the search plus **about $0.09** for 44 leads — **about $0.003 per lead**, all in. On our test the search came to **$0.0016 per lead**; the share of leads depends on the trade (see Accuracy).

### Tips

- **Choose trades where small operators dominate**: handymen, cleaners, hair and beauty salons, mobile mechanics, landscapers, removals.
- **Search towns and suburbs one by one** — `handyman` in `Katy, TX, USA`, then `Pasadena, TX, USA` — to cover a metro area.
- **Sort by `reviews_count`**: an established business with many reviews and no website is the warmest lead.
- **Check a business before you pitch it.** A business may have a website it never added to Google Maps; the `lead_reason` says exactly what was found.

### FAQ

#### Why does a business with a website on Google Maps show up as a lead?

Because that website is not one a customer can use. `lead_reason` says why: the domain does not exist, is parked or for sale, forwards to a Facebook page, is a free builder site, shows an invalid SSL certificate… Every spelling a browser would try is tested before a site is called broken.

#### Why are some places missing from the results?

Only leads are returned, unless **Also return businesses that have a website** is on. A website that refused the check or did not answer in time is `unknown` — never sold as a lead, because it may well work.

#### Can I use my own list of places?

Yes: give a Google Maps dataset — from [Google Maps Scraper](https://apify.com/compass/crawler-google-places) or any export with a name and a website per place — in **Google Maps dataset**. To get emails from businesses that *do* have a website, use [Google Maps Email Extractor](https://apify.com/sandy_yclept/google-maps-email-extractor).

#### Is this legal?

Google Maps business listings are public, and this Actor opens only the page a listing links to — and its homepage when that page is gone — respecting `robots.txt`. What you do with the data is your responsibility: a sole trader's phone number is personal data under GDPR, and cold calls and messages are regulated (for example the TCPA and the Do Not Call registry in the US, the TPS in the UK).

### Related Actors

- [Website Contact & Email Scraper](https://apify.com/sandy_yclept/website-contact-email-scraper) — emails, phone numbers and social profiles from any list of websites, priced per contact.
- [Impressum Email Scraper](https://apify.com/sandy_yclept/impressum-email-scraper) — the same for German websites: the Impressum read first, `DE` phone numbers, the authorities a legal page must name left out.
- [Google Maps Email Extractor](https://apify.com/sandy_yclept/google-maps-email-extractor) — local businesses from a Google Maps search, each with the email from its own website.
- [Shopify Store Leads & Emails](https://apify.com/sandy_yclept/shopify-store-leads) — Shopify stores by product keyword and country, with each store's email and its currency, catalogue size and shipping countries.

### Disclaimer

This Actor is a **tool**. You are responsible for complying with GDPR and local marketing law, Google's and the target sites' Terms of Service, and `robots.txt`. It does not build or sell contact databases. It is not affiliated with Google.

### Support

Found a business marked as a lead that has a working website, or one we missed? Open an issue on the **Issues** tab — accuracy reports shape the roadmap directly.

# Actor input Schema

## `searchStringsArray` (type: `array`):

What you would type into Google Maps, one term per line: "handyman", "hair salon", "auto repair". Every term is searched in the location below. The places are found by a Google Maps scraper that bills its own places to your account in a separate run - see "Where the places come from" and the README for prices.

## `locationQuery` (type: `string`):

Where to search, as free text: a city and country work best ("Houston, TX, USA", "Birmingham, United Kingdom"). One location per run. Leave it empty when the search terms already say where.

## `maxCrawledPlacesPerSearch` (type: `integer`):

How many Google Maps places to take for each search term. Businesses without a website rank low: 9% of the first ten places were leads in our test, 44% of places 61-100 - so take 100 or more. The Google Maps search bills every place it returns, so this also caps what the search costs. Checking the websites takes about a second per place.

## `leadTypes` (type: `array`):

The kinds of "no real website" to return and pay for. All four by default. A business with a working website, or one whose website could not be checked, is never a lead.

## `includeAllPlaces` (type: `boolean`):

Return every place found, each with its lead\_type - has\_website, unknown or closed included - rather than the leads only. Only leads are ever charged.

## `language` (type: `string`):

Language of the place names, categories and addresses Google Maps returns. Emails and websites are the same in any language.

## `placeSource` (type: `string`):

Which Google Maps scraper finds the places, in a run of its own on your account. scraperlink/google-maps-scraper: $0.50 per 1,000 places on the Free and Starter plans ($0.40 on higher ones), at least 10 per search term; when it finds nothing, compass/crawler-google-places takes over. compass/crawler-google-places: $4 per 1,000 places on the Free plan, closest to Google Maps' own ranking. The websites are checked the same way from either.

## `mapsDatasetId` (type: `string`):

A dataset from an earlier Google Maps scrape - Google Maps Scraper's, or any export with a name and a website field per place. Its places are checked instead of a new search, and nothing is paid for finding them again. Given together with search terms, both are read and duplicates are merged.

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

Optional proxy for fetching pages. Apify Proxy's datacenter IPs are included in every Apify plan, the Free plan too; residential proxies are billed separately. Left disabled, the Actor connects directly, and retries sites that refuse it through Apify Proxy (see below).

## `proxyFallback` (type: `boolean`):

Every cloud run has a datacenter IP address, and some sites turn those away. A site that refuses or drops the direct connection is retried once through Apify Proxy's datacenter IPs (included in every Apify plan, the Free plan too), then once more directly. Sites that answer directly never go through the proxy, and robots.txt is respected either way. Has no effect when a proxy is configured above.

## Actor input object example

```json
{
  "searchStringsArray": [
    "handyman",
    "hair salon"
  ],
  "locationQuery": "Birmingham, United Kingdom",
  "maxCrawledPlacesPerSearch": 100,
  "leadTypes": [
    "no_website",
    "platform_page",
    "builder_subdomain",
    "broken_website"
  ],
  "includeAllPlaces": false,
  "language": "en",
  "placeSource": "scraperlink",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "proxyFallback": true
}
```

# Actor output Schema

## `results` (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 = {
    "searchStringsArray": [
        "handyman"
    ],
    "locationQuery": "Houston, TX, USA",
    "maxCrawledPlacesPerSearch": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("sandy_yclept/no-website-leads").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 = {
    "searchStringsArray": ["handyman"],
    "locationQuery": "Houston, TX, USA",
    "maxCrawledPlacesPerSearch": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("sandy_yclept/no-website-leads").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 '{
  "searchStringsArray": [
    "handyman"
  ],
  "locationQuery": "Houston, TX, USA",
  "maxCrawledPlacesPerSearch": 100
}' |
apify call sandy_yclept/no-website-leads --silent --output-dataset

```

## MCP server setup

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

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/BH7x2a47dFVF3oetE/builds/8sC7TNMLYMdq6lEbs/openapi.json
