# Local Business Health Scorer: Google Maps lead finder (`fractionalhqforyou/local-business-health-scorer`) Actor

I search Google Maps and score every local business 0-100 for how much help it needs online. No website, a website that no longer answers, a listing with no photos, reviews nobody replied to. You get the reasons with their numbers, and the plainest as outreach lines you can paste.

- **URL**: https://apify.com/fractionalhqforyou/local-business-health-scorer.md
- **Developed by:** [Jessy Mariau](https://apify.com/fractionalhqforyou) (community)
- **Categories:** Lead generation, SEO tools, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 business scoreds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Local Business Health Scorer

I built this because I kept doing the same hour of work by hand. You search a trade and a town on Google Maps. Then you open ninety listings one at a time, hunting for the dozen with no website, a website that no longer loads, or thirty reviews nobody ever answered.

Now I run the search and score every listing in it, and you get a ranked list with a reason for each business that you can paste into an email.

### What I look at

Every business gets a score out of 100. Six things feed it, and they add up to exactly 100 so the total is always readable.

**Web presence, worth 35.** The listing has no website at all, or the website on it does not answer, or the link goes to a Facebook page rather than a site the business owns.

**Review engagement, worth 18.** The owner never replies to the recent reviews I read, or replies to almost none of them.

**Photos, worth 12.** The listing carries no photos, or barely any.

**Staleness, worth 12.** The newest review is months or years old. A listing with no reviews at all scores the full 12.

**Website quality, worth 10.** The site answers, but on plain http rather than https. Or it carries no mobile viewport tag. Or its footer copyright sits years behind.

**What the listing is missing, worth 13.** No opening hours, no phone number, no description. Under 4.2 stars with at least ten reviews adds the last 5 points.

Anything scoring 55 or more is marked HOT. From 30 to 54 is WARM, and the rest is COLD. Every row carries the reasons that fired with the numbers behind them, so you can see why a business scored what it did rather than taking the total on trust.

### Who I built it for

- Web designers and agencies who sell first websites and rebuilds to local trades
- Google Business Profile and local SEO consultants
- Photographers who sell listing photo shoots
- Anyone doing local outreach who wants a reason to write, rather than a name and a phone number

### How to run it

Put one or more search terms in, one per line, exactly as you would type them into Google Maps. Add a town or a city. Set how many businesses to score and how many recent reviews I should read for each of them. Run it, then open the Overview table and sort on the score column.

Leave the search term empty and you get two demo rows, scored by the same rubric I use on real ones, so you can see the shape of the output before you spend anything.

### What comes back

One row per business. It holds the contact details from the listing alongside every signal the score was built from. Underneath sit the rubric reasons in full, plus up to three pitch angles. A pitch angle is one sentence written from that row's own numbers:

> Not one of the last 5 reviews has a reply from the business.

> The Google listing has 1 photo on it, which is what a search result shows before anyone clicks.

> The website on the Google listing does not load, so the link customers click goes nowhere.

I also write a summary record with how many businesses landed in each band, how many had no website at all, and the ten highest scores with their first pitch angle.

### What it costs

You are charged once per business I score. The Google Maps search itself runs on the Google Maps Scraper and is billed to your own Apify account on top, exactly as it would be if you ran that Actor yourself. If you already scraped the places earlier, paste those records into the optional field and I score them without running a new search.

### Honest limits

- The owner-reply rate is measured on the recent reviews you asked for, not on every review the business ever had. Ask me for five and the number describes those five.
- A photo count of zero is read from the listing. Google sometimes attaches photos from other sources to a business that has uploaded none itself, which makes the count look healthier than the owner's own effort.
- The website check is one plain request rather than a browser. It tells you the link is dead or insecure. For a deeper look at how old a site is inside, run Website Redesign Lead Scorer over the sites I find.
- None of this is a judgement about the business. It describes what its public listing showed on the day I read it.

Built by **Fractional HQ** · https://fractionalhq.uk

# Actor input Schema

## `searchTerms` (type: `string`):

One search term per line, exactly as you would type it into Google Maps: plumber, dentist, wedding photographer. Leave empty to get a demo dataset that charges nothing.

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

A town, city or area, e.g. Manchester, UK. The narrower it is, the more useful the list.

## `maxPlaces` (type: `integer`):

A cap on how many listings are scored. Hard limit 500.

## `reviewsPerPlace` (type: `integer`):

The owner-reply check is measured on these. 5 is enough to see whether anyone answers; set 0 to skip reviews entirely and the check will not fire.

## `minScore` (type: `integer`):

Filters the saved rows, not the search. 55 and above is the HOT band. Every business searched is charged for whether or not it clears this.

## `checks` (type: `array`):

Leave all five on unless you are chasing one specific angle. Each check you turn off removes its points from the score, so scores are only comparable between runs with the same checks.

## `checkWebsites` (type: `boolean`):

On by default, and it is what separates a business with a real site from one whose link is dead. One plain request per website, no browser. Switch it off for a faster listing-only pass.

## `places` (type: `array`):

Paste Google Maps place records you scraped earlier and they are scored directly, with no new search and nothing billed for the search. Leave empty to search instead.

## Actor input object example

```json
{
  "searchTerms": "plumber",
  "location": "Manchester, UK",
  "maxPlaces": 50,
  "reviewsPerPlace": 5,
  "minScore": 0,
  "checks": [
    "presence",
    "engagement",
    "photos",
    "staleness",
    "completeness"
  ],
  "checkWebsites": true
}
```

# Actor output Schema

## `businesses` (type: `string`):

One row per business: the opportunity score and band, the contact details from the listing, every signal behind the score, the triggered rubric reasons and the pitch angles written as sentences.

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

The OUTPUT record: businesses scored, how many landed HOT, WARM and COLD, how many had no website, how many events were charged, and the top 10 by score with their first pitch angle.

# 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": "plumber",
    "location": "Manchester, UK"
};

// Run the Actor and wait for it to finish
const run = await client.actor("fractionalhqforyou/local-business-health-scorer").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": "plumber",
    "location": "Manchester, UK",
}

# Run the Actor and wait for it to finish
run = client.actor("fractionalhqforyou/local-business-health-scorer").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": "plumber",
  "location": "Manchester, UK"
}' |
apify call fractionalhqforyou/local-business-health-scorer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fractionalhqforyou/local-business-health-scorer"
        }
    }
}

```

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/gXh09bnACPR236laV/builds/yA8y4EY5Nh63zuxLR/openapi.json
