# Local Business Leads with Website Audit (`mambo_melon/local-leads-website-audit`) Actor

Type a niche and a city, get local businesses from Google Maps ranked as agency leads: each website audited for mobile, SSL, speed, outdated footer, booking, chat and analytics, plus businesses with no website at all. Lead score, problems, a first outreach line and contacts.

- **URL**: https://apify.com/mambo\_melon/local-leads-website-audit.md
- **Developed by:** [Joran Morgan](https://apify.com/mambo_melon) (community)
- **Categories:** Lead generation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $15.00 / 1,000 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?

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

## Local Business Leads with Website Audit

Type a business type and a city, and get back a list of local businesses from Google Maps, each one checked the way a web or marketing agency would check it before reaching out: is the site mobile-friendly, is HTTPS working, how slow is it, does the footer still say © 2019, can you book online, is there a chat, analytics, a contact form. Every business gets a lead score from 0 to 100, the problems in plain English, a first line for your cold email, and the phone, email and address.

Businesses with no website at all, or with a website on their Google listing that no longer loads, come back as the hottest leads.

I made this because prospecting for local clients always went the same way for me: pull a list from Google Maps, open fifty websites, take notes, write fifty openers. This does the whole thing in one run and sorts the list by who needs help most.

### How it works

1. It searches Google Maps with Apify's own [Google Maps Scraper](https://apify.com/compass/crawler-google-places) for each business type in your location.
2. Every website found is audited (the same checks as my [Website Audit & Lead Scorer](https://apify.com/mambo_melon/website-audit-lead-scorer)). Chain locations that share one website are audited and listed once.
3. Results are merged into one row per business.

**About cost:** the Google Maps step runs the Google Maps Scraper in your account, and that Actor bills its own results (roughly $1.50 to $4 per 1,000 places depending on your plan). This Actor then charges per lead it returns. Sites that still refuse automated visits after a retry come back with an error and aren't charged, and neither are businesses you filter out with `minLeadScore`.

### Example

Input:

```json
{ "searchQueries": ["dentist", "plumber"], "location": "Denver, Colorado", "maxPlacesPerSearch": 25 }
```

That run returned 49 businesses in about a minute and a half. The top website lead (real output, business name and website changed):

```json
{
  "businessName": "Example Dental at Midtown",
  "category": "Dentist",
  "city": "Denver",
  "phone": "(303) 555-0142",
  "website": "http://www.example-dental.com/",
  "rating": 3.9,
  "reviewsCount": 262,
  "leadScore": 63,
  "priority": "hot",
  "pitchHook": "Hi, I was looking at example-dental.com and noticed browsers mark your site as \"Not secure\", and the site doesn't adapt to phone screens. I help local businesses fix exactly this. Happy to show you what it would look like.",
  "issueCodes": ["no_https", "not_mobile_friendly", "no_live_chat", "no_analytics", "no_contact_form", "no_social_links"],
  "hasWebsite": true,
  "mobileFriendly": false,
  "sslValid": false,
  "loadTimeMs": 2208,
  "hasOnlineBooking": true,
  "hasLiveChat": false,
  "hasAnalytics": false,
  "cms": "WordPress",
  "emails": ["appointments@example-dental.com"],
  "error": null
}
```

And a business with no website, from the same run:

```json
{
  "businessName": "Example Plumbing",
  "phone": "(720) 555-0198",
  "rating": 4.7,
  "hasWebsite": false,
  "leadScore": 70,
  "priority": "hot",
  "issueCodes": ["no_website"],
  "pitchHook": "Hi, I found Example Plumbing on Google Maps and noticed you don't have a website listed on Google. I build simple websites for local businesses. Happy to show you an example."
}
```

Every row has the same fields; missing values are `null`. The **Leads** view shows name, score, pitch line and contacts; **Website checks** shows every check as a column.

### Scoring

| Problem | Points |
|---|---|
| No website on Google Maps | 70 |
| Website on the listing doesn't load (dead domain, server errors) | 65 |
| Listing points to a Facebook/Instagram page instead of a website | 60 |
| No HTTPS or broken SSL certificate | 20 |
| Not mobile-friendly | 20 |
| Homepage slower than 5 s (3 s: 5 points) | 10 |
| Footer copyright 2+ years old | 10 |
| No online booking | 10 |
| No analytics | 10 |
| No live chat, no contact form, outdated CMS, site builder, missing SEO basics | 3 to 5 each |

Score is capped at 100. 50+ is `hot`, 25 to 49 `warm`, below that `cold`.

### Input

| Field | What it does | Default |
|---|---|---|
| `searchQueries` | Business types to search, e.g. `dentist`, `roofer`, `hair salon` | required |
| `location` | City or area, e.g. `Austin, Texas`, `Leeds, UK` | required |
| `maxPlacesPerSearch` | Google Maps results per business type | 50 |
| `minLeadScore` | Only return businesses scoring at least this (others aren't charged) | 0 |
| `includeBusinessesWithoutWebsite` | Include businesses with no website | on |
| `language` | Google Maps language | `en` |

### FAQ

**Why do some rows have an error like HTTP 403?**
Some sites block automated visits. Those get one more try through a residential connection, which gets most of them through. If a site still refuses, the business is listed with its Google Maps data and an `error`, and isn't charged.

**Where do the emails come from?**
Only from the business's own website (mailto links and visible text). Phones and addresses come from Google Maps.

**Can I use my own list instead of Google Maps?**
Yes, use [Website Audit & Lead Scorer](https://apify.com/mambo_melon/website-audit-lead-scorer) and paste your websites.

### Notes

Only public information is used. Technology detection relies on the open-source [webappanalyzer](https://github.com/enthec/webappanalyzer) rules (GPL-3.0). Questions or a site scored wrong? Open an issue.

# Actor input Schema

## `searchQueries` (type: `array`):

What to search on Google Maps, e.g. 'dentist', 'plumber', 'hair salon'. One lead list per query.

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

City or area, e.g. 'Austin, Texas' or 'Leeds, UK'.

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

How many Google Maps results to take for each business type.

## `minLeadScore` (type: `integer`):

Skip businesses whose website is in good shape. Skipped businesses are not charged.

## `includeBusinessesWithoutWebsite` (type: `boolean`):

Businesses without a website on Google Maps are usually the best leads for a web agency.

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

Language code for Google Maps results.

## Actor input object example

```json
{
  "searchQueries": [
    "dentist",
    "plumber"
  ],
  "location": "Austin, Texas",
  "maxPlacesPerSearch": 50,
  "minLeadScore": 0,
  "includeBusinessesWithoutWebsite": true,
  "language": "en"
}
```

# Actor output Schema

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

No description

## `checks` (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 = {
    "searchQueries": [
        "dentist",
        "plumber"
    ],
    "location": "Austin, Texas"
};

// Run the Actor and wait for it to finish
const run = await client.actor("mambo_melon/local-leads-website-audit").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 = {
    "searchQueries": [
        "dentist",
        "plumber",
    ],
    "location": "Austin, Texas",
}

# Run the Actor and wait for it to finish
run = client.actor("mambo_melon/local-leads-website-audit").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 '{
  "searchQueries": [
    "dentist",
    "plumber"
  ],
  "location": "Austin, Texas"
}' |
apify call mambo_melon/local-leads-website-audit --silent --output-dataset

```

## MCP server setup

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

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/0N0g76L1mC91hBXHR/builds/wxvR7xRTKPen6GH5u/openapi.json
