# GBP Audit Leads: Unclaimed & Incomplete Google Business Profile (`aiden_boudreau/google-business-profile-audit-leads`) Actor

GBP audit for lead generation: find local businesses whose Google Business Profile (GMB) is unclaimed or incomplete (no website, no hours, few photos, few reviews). Each lead gets an opportunity score, the exact gaps and a pitch line. For local SEO agencies.

- **URL**: https://apify.com/aiden_boudreau/google-business-profile-audit-leads.md
- **Developed by:** [Aiden Boudreau](https://apify.com/aiden_boudreau) (community)
- **Categories:** Lead generation, SEO tools
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 business profile 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

## GBP Audit Leads: Unclaimed & Incomplete Google Business Profile

A **GBP audit** built for lead generation: find local businesses whose **Google Business Profile** (GMB) needs work, ready for a local SEO agency to pitch. Give a
business type and a city; you get back the businesses whose Google profile is **unclaimed** or **incomplete**,
sorted by an opportunity score, with the exact gaps and a one-line pitch for each.

### What it checks (all from Google Maps data, no extra crawling)

| Gap | Points |
|---|---|
| Profile is unclaimed (the owner never verified it) | 35 |
| No website on the profile | 15 |
| Fewer than 10 reviews (10-29: 5) | 15 |
| No opening hours | 10 |
| Fewer than 5 photos (5-14: 5) | 10 |
| Rating under 4.0 (with 5+ reviews) | 10 |
| No phone number | 5 |

The score is capped at 100. Closed businesses are skipped. Use **Minimum opportunity score** (default 30) to keep
only real opportunities, or **Only unclaimed profiles** for the hottest pitch: "your business is on Google, but you
don't control the listing".

### Example output (real run, default input)

![Handymen in Boise, ID ranked by Google Business Profile gaps: real output](https://api.apify.com/v2/key-value-stores/VsOADrgiznRqRejDw/records/gbp-output.png)

Handymen in Boise, ID ranked by opportunity score, from a real run of the default input (phones masked in this image only).

### Output

One row per lead, highest score first:

```json
{
  "businessName": "Example Nails & Spa",
  "opportunityScore": 50,
  "gaps": ["Profile is unclaimed (owner never verified it)", "No website on the profile"],
  "pitch": "Example Nails & Spa's Google Business Profile has 2 fixable gaps: profile is unclaimed (owner never verified it); no website on the profile.",
  "claimed": false,
  "phone": "(602) 555-0100",
  "category": "Nail salon",
  "website": null,
  "address": "123 Main St, Phoenix, AZ 85016",
  "rating": 4.6,
  "reviewsCount": 468,
  "photosCount": 25,
  "hasOpeningHours": true,
  "googleMapsUrl": "https://www.google.com/maps/..."
}
```

A `SUMMARY` record in the key-value store gives businesses checked, leads and unclaimed count.

### Cost

- **$0.003 per lead returned** (a business at or above your minimum score). Businesses below the bar are free.
- Google Maps search runs through Apify's Google Maps Scraper and is billed to your account at its own price (about
  $4 per 1,000 places). No Maps filters are used, so you don't pay its per-filter extras. Set **Max Google Maps cost**
  to cap it.
- Already have a Google Maps Scraper dataset? Pass its ID in **Existing Google Maps dataset ID** and skip the search.

### FAQ

**Who is this for?** Local SEO and Google Business Profile agencies, web designers and reputation-management
freelancers looking for businesses with a clear, fixable problem.

**How much do 100 leads cost, all in?** It depends on the trade, because the share of businesses with a fixable
profile varies. In our test runs (Boise, 20 places each, minimum score 30): handymen gave 8-9 leads per 20 places,
plumbers 1 per 20. So 100 places cost about $0.40 of Google Maps plus $0.003 per lead: about $0.52 for ~40 handyman
leads, or about $0.42 for ~5 plumber leads. Trades with many small one-person businesses give the most leads.

**How accurate is "unclaimed"?** It's Google's own "Own this business?" flag as read by Google Maps Scraper.

**Related:** need businesses with no website at all? See
[Google Maps Businesses Without Website](https://apify.com/aiden_boudreau/google-maps-businesses-without-website).
Need existing websites audited? See [Web Design Leads](https://apify.com/aiden_boudreau/website-redesign-leads).

### Related Actors

Same author, built for local SEO and web design agencies:

- [Web Design Leads](https://apify.com/aiden_boudreau/website-redesign-leads): scores existing websites (mobile, HTTPS, age, speed) and finds businesses with dead or no sites.
- [Google Maps Businesses Without Website](https://apify.com/aiden_boudreau/google-maps-businesses-without-website): Google Maps businesses with no website, with phone and address.
- [Local SEO Keyword Finder](https://apify.com/aiden_boudreau/local-seo-keyword-finder): service + city keywords from Google search suggestions, tagged by intent.
- [Slow Website Leads: PageSpeed & Lighthouse Audit](https://apify.com/aiden_boudreau/slow-website-leads-pagespeed-audit): mobile Lighthouse score, load time, top 3 fixes and a pitch line per business website, no Google key needed.

# Actor input Schema

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

What to search on Google Maps, e.g. "plumber", "dentist", "nail salon". One search per term.

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

City, region or ZIP code to search, e.g. "Boise, ID" or "Austin, TX".

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

How many Google Maps places to check per term. Google Maps Scraper bills about $4 per 1,000 places to your account.

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

Only return businesses scoring at least this (0-100). Unclaimed profile = 35, no website = 15, few reviews = 15, no hours / few photos / low rating = 10 each. 0 returns every business.

## `onlyUnclaimed` (type: `boolean`):

Return only businesses whose Google profile was never claimed by the owner.

## `maxMapsCostUsd` (type: `integer`):

Optional cap on what the Google Maps Scraper step may charge your account.

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

Optional: score places from an earlier Google Maps Scraper run instead of (or in addition to) searching.

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

Google Maps language code.

## Actor input object example

```json
{
  "searchTerms": [
    "handyman"
  ],
  "location": "Boise, ID",
  "maxPlacesPerSearch": 20,
  "minScore": 30,
  "onlyUnclaimed": false,
  "language": "en"
}
```

# Actor output Schema

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

Businesses with profile gaps, highest score first.

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

Businesses checked, leads, unclaimed.

# 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": [
        "handyman"
    ],
    "location": "Boise, ID",
    "maxPlacesPerSearch": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("aiden_boudreau/google-business-profile-audit-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 = {
    "searchTerms": ["handyman"],
    "location": "Boise, ID",
    "maxPlacesPerSearch": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("aiden_boudreau/google-business-profile-audit-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 '{
  "searchTerms": [
    "handyman"
  ],
  "location": "Boise, ID",
  "maxPlacesPerSearch": 20
}' |
apify call aiden_boudreau/google-business-profile-audit-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,aiden_boudreau/google-business-profile-audit-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/mOEE449WGYYHuJvVc/builds/4GqeWP6o6r81u5Ks7/openapi.json
