# Google Maps No-Website Leads Finder (`i-scraper/google-maps-no-website-leads`) Actor

Find contactable US local businesses with no website listed, social-only or directory-only presence, broken websites, or missing online booking — with evidence for every result.

- **URL**: https://apify.com/i-scraper/google-maps-no-website-leads.md
- **Developed by:** [i-Scraper](https://apify.com/i-scraper) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 93.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 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.

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

## Google Maps No-Website Leads Finder

Find active, contactable US local businesses with a clear digital-sales opportunity — not just a blank website column.

This Actor searches Google Maps and returns qualified prospects with evidence for each classification. Use it for web design, local SEO, online booking, automation, and agency lead-generation workflows.

### What you can find

- Businesses with no website listed on Google Maps
- Businesses using only Facebook, Instagram, or another social profile
- Businesses using only a directory or hosted booking profile
- Listed websites that are broken or parked
- Appointment-based businesses with no detected online booking

Every result includes the Google Place ID, Maps URL, contact details, opportunity reasons, completed checks, confidence, and a transparent score.

### Important evidence rule

`no_website_listed_on_maps` means exactly what it says: Google Maps does not list a website for that business.

The MVP does not search the wider web for an unlisted owned website. It therefore does not claim that the business has no website anywhere.

Blocked pages, timeouts, temporary server errors, and unsafe URLs are returned as `verification_inconclusive` instead of false broken-site claims.

### Example input

```json
{
  "searches": [
    {
      "query": "hair salon",
      "location": "Austin, Texas, USA",
      "radiusKm": 10
    }
  ],
  "mode": "verified",
  "opportunityTypes": [
    "no_website_listed",
    "social_only",
    "directory_only",
    "website_broken",
    "missing_booking"
  ],
  "maxBusinessesToCheck": 100,
  "maxQualifiedLeads": 50,
  "minRating": 3.8,
  "minReviewCount": 10,
  "requirePhone": true,
  "excludeClosed": true,
  "excludeChains": true,
  "bookingAudit": true,
  "onlyNew": false
}
```

The MVP supports United States locations and English booking signals. `radiusKm` defines a 1–50 km circle around the location center.

### Verification modes

#### Verified

Checks the listed URL with bounded redirects, retries, response-size limits, and private-network protection. It classifies owned, social-only, directory-only, broken, parked, and inconclusive web presence. For applicable categories, it also looks for Maps booking links, known provider domains, buttons, iframes, scripts, and schema.org actions.

#### Fast

Uses Google Maps fields and deterministic URL-domain classification only. It does not fetch listed websites, so `website_broken` and `missing_booking` are not available.

### Only New monitoring

Use `onlyNew` when scheduling the Actor from n8n, Make, or Apify Scheduler:

```json
{
  "searches": [
    {
      "query": "dentist",
      "location": "Phoenix, Arizona, USA",
      "radiusKm": 15
    }
  ],
  "onlyNew": true,
  "monitorId": "phoenix-dentists",
  "recheckAfterDays": 7
}
```

The first run returns all current qualified leads and creates the baseline. Later runs with the same monitor ID suppress every lead already returned by that monitor. A known but previously unqualified business is returned once if it later becomes qualified.

`recheckAfterDays` does not schedule the Actor. Your integration controls the schedule. It tells the Actor how long it may reuse a conclusive website check for a known, not-yet-returned business. A changed Maps website URL is checked immediately; inconclusive checks are retried on the next run.

Use the same monitor ID only with identical searches and qualification settings. To change the monitor definition or start over, choose a new monitor ID.

Only New still reruns Google Maps acquisition. It prevents duplicate output and avoids unnecessary website checks; it cannot make Google Maps return only unseen places.

Delivery is at-least-once across platform crashes. For robust downstream workflows, deduplicate by `monitorId + placeId`. Concurrent runs using the same monitor ID are not supported in the MVP.

### Output

The default dataset contains qualified opportunities unless `includeUnqualified` is enabled for diagnostics. Useful fields include:

- `placeId`, `name`, category, address, coordinates, Maps URL, and phone
- rating and review count
- listed and resolved website URLs
- `webPresenceType`, `websiteStatus`, and structured `websiteCheck`
- `bookingStatus`, provider names, and structured `bookingCheck`
- `opportunityReasons` with machine-readable codes and evidence
- transparent `opportunityScore` and `scoreComponents`
- `isNew`, `changeType`, `monitorId`, and `firstSeenAt`
- `checksCompleted`, confidence, source, and check timestamp

The default Key-Value Store also contains:

- `OUTPUT` — run counts, charged qualified-lead counts, and charge-limit status
- `FAILED_SEARCHES` — recoverable geocoding, upstream, and schema failures
- `LIMITATIONS` — machine-readable MVP boundaries

### Costs and limits

`maxBusinessesToCheck` is a global safety cap. `maxQualifiedLeads` caps returned qualified leads and stops further website checks when reached. If the requested lead limit is higher than the business-check cap, the Actor automatically uses the smaller business-check cap. Google Maps acquisition is performed by `compass/crawler-google-places` and is billed separately according to that Actor's current pricing.

With pay-per-event monetization enabled, the Actor charges the `qualified-lead` event only when a qualified result is written to the default dataset. Filtered businesses, unqualified diagnostic rows, failed checks, duplicate suppression, and previously emitted Only New results are not charged. If the run's maximum charge is reached, the Actor stops before writing an unpaid qualified lead.

All other events, including the automatic `apify-default-dataset-item` and `apify-actor-start` events, must be removed or priced at `$0` in the monetization settings. This guarantees that zero-result runs and diagnostic rows produced with `includeUnqualified` are free. Google Maps acquisition by `compass/crawler-google-places` remains separately billed to the account running the Actor.

### Responsible use

The Actor processes public business information and does not send outreach. Users are responsible for their CRM, marketing, privacy, and outreach compliance, including applicable US state and federal rules. Opportunity scores describe deterministic data signals, not a promise that a business wants to buy a service.

# Actor input Schema

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

Add a keyword, a US location, and a search radius. Each entry is searched independently; duplicates are removed by Google Place ID.

## `mode` (type: `string`):

Verified mode checks listed websites and booking signals. Fast mode uses Maps fields and URL classification only.

## `opportunityTypes` (type: `array`):

Return businesses matching at least one selected opportunity. Website broken and missing booking require Verified mode.

## `maxBusinessesToCheck` (type: `integer`):

Global safety cap across all searches. Checked businesses can exceed returned leads because filters and verification run before qualification.

## `maxQualifiedLeads` (type: `integer`):

Stop website checks after this many qualified results have been returned. If this is higher than Maximum businesses to check, the smaller business-check limit is used automatically.

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

Businesses without a rating or below this value are skipped before website verification.

## `minReviewCount` (type: `integer`):

Require evidence of activity before treating a business as a lead.

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

Return only businesses with a phone number listed on Google Maps.

## `excludeClosed` (type: `boolean`):

Skip businesses marked temporarily or permanently closed.

## `excludeChains` (type: `boolean`):

Apply a conservative US chain name/domain registry. This does not claim exhaustive franchise detection.

## `bookingAudit` (type: `boolean`):

For English appointment-based categories, check Maps links and bounded website HTML for known booking providers and actions.

## `onlyNew` (type: `boolean`):

First run returns the current qualified baseline. Later runs with the same monitor ID suppress leads that were already returned.

## `monitorId` (type: `string`):

Required with Only New. Reuse the same ID with identical searches and filters; use a new ID when changing the monitor definition.

## `recheckAfterDays` (type: `integer`):

Reuse conclusive checks for known, not-yet-returned businesses until this many days pass. Changed URLs and inconclusive checks are retried sooner.

## `includeUnqualified` (type: `boolean`):

Also output checked businesses that fail filters or have no selected opportunity. Leave disabled for production lead workflows.

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

Optional Apify proxy used only for listed-business website checks. The upstream Maps Actor manages its own acquisition network.

## Actor input object example

```json
{
  "searches": [
    {
      "query": "hair salon",
      "location": "Austin, Texas, USA",
      "radiusKm": 10
    }
  ],
  "mode": "verified",
  "opportunityTypes": [
    "no_website_listed",
    "social_only",
    "directory_only",
    "website_broken",
    "missing_booking"
  ],
  "maxBusinessesToCheck": 100,
  "maxQualifiedLeads": 50,
  "minRating": 3.8,
  "minReviewCount": 10,
  "requirePhone": true,
  "excludeClosed": true,
  "excludeChains": true,
  "bookingAudit": true,
  "onlyNew": false,
  "recheckAfterDays": 7,
  "includeUnqualified": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Current-run results. With onlyNew enabled, this dataset contains only leads not previously emitted by the monitor.

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

Checked, qualified, emitted, suppressed, cached, charged, and charge-limit counts.

## `failedSearches` (type: `string`):

Geocoding, upstream run, and upstream schema failures that did not abort other searches.

## `limitations` (type: `string`):

Machine-readable explanation of market, language, evidence, delivery, and charging behavior.

# 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": [
        {
            "query": "hair salon",
            "location": "Austin, Texas, USA",
            "radiusKm": 10
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("i-scraper/google-maps-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 = { "searches": [{
            "query": "hair salon",
            "location": "Austin, Texas, USA",
            "radiusKm": 10,
        }] }

# Run the Actor and wait for it to finish
run = client.actor("i-scraper/google-maps-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 '{
  "searches": [
    {
      "query": "hair salon",
      "location": "Austin, Texas, USA",
      "radiusKm": 10
    }
  ]
}' |
apify call i-scraper/google-maps-no-website-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,i-scraper/google-maps-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/qyXhzdoP1Mufolbsp/builds/zAv1tcphoHUNra65E/openapi.json
