# UK Business Leads Companies House Lookup, AI Scoring & Outreach (`automationnation/uk-business-leads`) Actor

Scrape UK businesses from Google Maps with AI lead scoring, Companies House director lookup, and personalised outreach templates. More data per lead than any other Google Maps scraper.

- **URL**: https://apify.com/automationnation/uk-business-leads.md
- **Developed by:** [Nathan Carter](https://apify.com/automationnation) (community)
- **Categories:** Lead generation, AI, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $100.00 / 1,000 business 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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## UK Business Leads — AI Lead Scoring, Director Lookup & Outreach

> Find newly opened UK businesses on Google Maps. Every result includes the **registered director's name from Companies House**, AI lead scoring, website quality analysis, and a personalised cold email written to that specific business — all built-in, no API keys needed.

### Free trial: 50 businesses, all features on

No credit card. No API keys. No configuration. Run it and see exactly what you get.

---

### Why this is different from every other UK scraper

#### 1. Director name from Companies House — nobody else does this

Every other Maps scraper gives you a business name. This gives you a person.

We cross-reference the UK government's Companies House register and return the registered director's first name for every business. Your cold email starts *"Hi James,"* — not *"Hi there,"*.

That one change doubles open rates. It's not a gimmick — it's the difference between looking like everyone else and looking like you've done your homework.

#### 2. HOT / WARM / COLD lead scoring

Every business is scored automatically based on how recently it opened:

- Incorporated in the last 3–12 months (Companies House)
- First Google Maps review within 2–8 weeks
- Very few reviews (still building reputation)
- Unclaimed Google listing
- No website or weak website

A restaurant with 3 reviews, incorporated 6 weeks ago, with no website = **HOT**. A chain with 1,400 reviews = **COLD**. Work the list top to bottom and only call the ones worth calling.

#### 3. Ready-to-send outreach — personalised, not templated

The AI writes three messages per business using the director's name, the actual review text, and the specific website issue spotted:

- **Email** — 90 words, addressed by first name, references something real about their business, direct CTA
- **LinkedIn message** — 300 chars, connection request style
- **SMS** — 160 chars, casual, name-first

These are not fill-in-the-blank templates. They reference specific things: *"noticed your site is missing a contact form"*, *"incorporated 8 weeks ago"*, *"your lamb rack got singled out in three reviews"*.

#### 4. Website quality score 0–10

We visit every website and score it, flagging: no SSL, no contact form, no booking link, no social links, no reviews/testimonials, no mobile viewport, no call-to-action. Instant pitch hook for any web or marketing agency.

#### 5. Search any business type — not just presets

Use the built-in categories or enter your own search terms: *"accountant"*, *"solicitor"*, *"mortgage broker"*, *"web design agency"*, *"fitness coach"* — anything Google Maps recognises.

---

### What you get per lead

| Field | Detail |
|---|---|
| **Name, address, phone** | Phone normalised to +44 format |
| **Email** | Scraped from their website across 14 contact page paths + obfuscation decoding |
| **Email type** | Personal (`james@bistro.co.uk`) or generic (`info@`) |
| **Website** | URL with UTM/tracking params stripped |
| **Social media** | Facebook, Instagram, TikTok, LinkedIn — clean profile URLs |
| **Director name** | From Companies House — most recently appointed active director |
| **Company number, type, age** | Private Limited, LLP, CIC, etc. |
| **Incorporation date** | Exact date the company was registered |
| **SIC codes** | Industry classification code(s) |
| **Lead score** | HOT / WARM / COLD with full reason breakdown |
| **Website score** | 0–10, with specific issues listed |
| **Google profile score** | 0–10, flags missing phone/photos/hours/description |
| **Reviews** | Up to 5 newest, with star ratings |
| **Review sentiment** | Positive / mixed / negative + one-sentence summary |
| **Target customer** | Who this business serves |
| **Price tier** | Budget / mid / premium |
| **Likely needs** | What marketing/digital services they visibly lack right now |
| **Email template** | 90-word personalised cold email, signed with your name |
| **LinkedIn message** | 300-char connection request |
| **SMS template** | 160-char text message |
| **Hours, price level, highlights** | Open/closed status, £ tier, amenity chips |
| **Booking URL** | If they use OpenTable, Treatwell, Booksy, Fresha, etc. |
| **Unclaimed listing** | YES if they haven't claimed their Google profile |
| **Estimated open date** | Derived from first review date |
| **Place ID, lat, lng** | For mapping, CRM imports, deduplication |

---

### Best way to use — by business type

#### Web & digital marketing agencies

Your window is the first 30–60 days after a business incorporates. After that, most have already been pitched by competitors or found someone themselves.

**Recommended settings:**
- Cities: your target region (start with one or two)
- Category: `restaurant`, `hair salon`, `gym`, `beauty salon` — or use Custom Search Terms for any type
- Max Reviews: `30` (filters to businesses still building their reputation)
- Add your name + service in the Outreach section

**What to do with the output:**
1. Sort by `leadScore` — work HOT first
2. Look at `websiteIssues` — this is your pitch hook (e.g. "no contact form, no mobile viewport")
3. The `emailTemplate` is already written — copy it, check the director name is right, send
4. For the ones with no email, use the `linkedinMessage` instead
5. Set up a Zapier webhook to push HOT leads straight into your CRM

**Pro tip:** Schedule this actor weekly with Incremental Mode on. Wake up every Monday to businesses that incorporated last week — none of which you've already emailed.

---

#### Accountants & bookkeepers

New companies need bookkeeping from day one. Most don't choose an accountant until month 2 or 3, when the first VAT question hits. Getting there in month 1 means you're already in the conversation.

**Recommended settings:**
- Custom Search Terms: `["restaurant", "hair salon", "gym", "retail", "trades"]` — any category that generates new limited companies
- Max Reviews: `50`
- Date Range Days: `90` (businesses whose first review appeared in the last 3 months)

**What to do with the output:**
1. Filter for `incorporationDate` within the last 6 months — these are the ones who haven't set up payroll or VAT yet
2. Look at `sicCodes` — certain SIC codes (56101 restaurant, 96020 hairdressing) indicate sole traders who become Ltd companies and need full bookkeeping immediately
3. The `emailTemplate` references their business type and how recently they incorporated — edit the sign-off, send

---

#### Recruiters & staffing agencies

A company incorporated last month needs staff. They haven't been to Reed or Indeed yet — they're still building out the basics.

**Recommended settings:**
- Custom Search Terms: `["restaurant", "construction company", "care home", "logistics"]`
- Max Reviews: `30`
- Cities: wherever you place candidates

**What to do with the output:**
1. Filter for `companyAge` under 6 months
2. Look at `sicCodes` to match industry to the roles you fill
3. The `directorName` means your first call or email uses their name — significantly better answer rate than "Dear Hiring Manager"

---

#### Equipment & supplies (POS, furniture, kitchen, fit-out)

A restaurant incorporated 8 weeks ago needs furniture, POS systems, kitchen equipment, signage, uniforms. You're the first supplier to call.

**Recommended settings:**
- Category: `restaurant`, `cafe`, `gym`, `beauty salon`
- Max Reviews: `15` (caught before they're fully equipped)
- Incremental Mode: on (weekly runs so you catch them at opening, not 6 months later)

---

#### PR & media

New openings are news. Most journalists find them after they've already been open 3 months.

**Recommended settings:**
- Date Range Days: `30`
- Max Reviews: `20`
- No other filters

The `openedText` and `lastReviewDate` fields tell you exactly how new they are. The `description` field (Google's editorial summary, where it exists) gives you the hook for a piece.

---

### Pricing

**Free: 50 businesses** — every feature included. No credit card, no expiry.

**Paid: $0.10 per business** — billed only when a lead is successfully scraped. No subscription. All features always included. Stop and start any time.

| Leads | Cost | What you get |
|---|---|---|
| 50 | Free | Full output — director name, AI email, website score, lead score |
| 100 | $10 | 100 leads with director names and personalised outreach |
| 500 | $50 | 500 leads — one month of a UK city's new businesses |
| 1,000 | $100 | 1,000 leads — serious outreach volume |
| 5,000 | $500 | 5,000 leads — agency-scale campaign |

**For comparison:** Hunter.io charges $0.13 per domain search — email address only, no AI, no director name, no lead scoring. This is $0.10 for the full package.

---

### Setup — 3 steps

**Step 1 — Where to search**
Set Cities (e.g. London, Manchester, Bristol) or Postcodes for precise radius targeting.

**Step 2 — What to search for**
Pick a Category — or use Custom Search Terms for any business type. Set Max Reviews to 30 to target new businesses.

**Step 3 — Personalise your outreach**
Add your name, business name, and what you offer in the Outreach section. The AI uses this to write emails signed by you.

That's it. Run it.

---

### Optional: boost performance

- **Hunter.io API key** — increases email discovery from ~35% to ~60%. Free tier available at hunter.io.
- **Your own Anthropic key** — if you run thousands of businesses per month and want dedicated API capacity. Not required — Claude Haiku is built in.
- **Your own Gemini key** — same as above, Gemini 2.5 Flash fallback built in.

---

### Delivery options

Connect results to your existing tools:

- **Google Sheets** — append every lead automatically. Share the sheet with your team.
- **Webhook / Zapier / Make** — one POST per lead. Connects to HubSpot, Salesforce, Pipedrive, Notion, Airtable, 1,000+ other tools.
- **HubSpot** — push contacts directly via private app token. No Zapier needed.
- **Slack** — post a digest of HOT leads and competitor alerts to your team channel.
- **Email** — receive results as a CSV attachment after each run.

---

### Scheduling (recommended)

Schedule this actor to run every Monday morning. Turn on **Incremental Mode** — it skips businesses from previous runs so you only get new ones. Wake up to a fresh inbox of businesses that incorporated or got their first review in the last 7 days, each with a ready-to-send email.

30 seconds to set up in the Apify scheduler.

---

### Data notes

- **Director name**: pulled from the UK Companies House public register. Returns the most recently appointed active director. Match confidence is high for limited companies; sole traders and partnerships may not be registered.
- **Email**: scraped from the business website across 14 page paths including contact, about, team, get-a-quote, book. Found for ~35–40% of businesses. Hunter.io key increases this to ~60%.
- **Opening date**: estimated from the date of the first Google Maps review. Google typically lags the real opening date by 1–4 weeks.
- **AI**: runs on Claude Haiku (Anthropic) by default — built in, no key needed. Falls back to Gemini 2.5 Flash if Claude is unavailable.
- **Lead scoring**: businesses are scored based on signals visible at scrape time. A business may be new but score COLD if it already has many reviews or a strong website — that's accurate scoring, not a bug.

---

### Questions or issues?

Leave a review on the actor page or contact through Apify. Response within 24 hours.

# Actor input Schema

## `cities` (type: `array`):

UK cities or regions to search. E.g. London, Manchester, Birmingham. Ignored if Postcodes are set.
## `postcodes` (type: `array`):

UK postcodes to search around. E.g. M1 1AA, SW1A 1AA. When set, overrides Cities and uses Radius Miles for geographic targeting.
## `radiusMiles` (type: `integer`):

Search radius around each postcode in miles. Only used when Postcodes are set. 1–20 recommended.
## `category` (type: `string`):

Type of business to find. Use 'all' to search across every category. Ignored if Custom Search Terms are set.
## `customSearchTerms` (type: `array`):

Search for any business type. E.g. ["accountant", "web design agency", "marketing agency", "solicitor", "mortgage broker"]. Overrides the Category setting above.
## `dateRangeDays` (type: `integer`):

Optional. Set to 30, 60 or 90 to filter for businesses whose first Google Maps review is within that window — a proxy for recently opened. Leave at 0 (default) to return all businesses.
## `minReviews` (type: `integer`):

Skip businesses with fewer than this many reviews. Use 0 to include brand-new listings.
## `maxReviews` (type: `integer`):

Skip businesses with more than this many reviews. Set to 10–30 to target brand-new businesses still building their reputation. Leave at 0 (default) for no cap.
## `requireWebsite` (type: `boolean`):

Only return businesses that have a website listed on Google Maps.
## `requireUnclaimed` (type: `boolean`):

Only return businesses that haven't claimed their Google Maps listing — easiest outreach targets.
## `scrapeEmails` (type: `boolean`):

Visit each business website and extract email addresses. Adds ~5 seconds per business.
## `maxResults` (type: `integer`):

Maximum number of businesses to return across all cities and queries.
## `incrementalMode` (type: `boolean`):

Skip businesses already seen in previous runs. Perfect for weekly scheduling — wake up to only new businesses each time.
## `anthropicApiKey` (type: `string`):

Claude Haiku is built-in — you do not need this. Only add your own key if you are running thousands of businesses per month and want dedicated API capacity. Get one at console.anthropic.com.
## `geminiApiKey` (type: `string`):

Gemini is the built-in fallback — you do not need this. Only add your own key if you hit rate limits on very large runs. Free at aistudio.google.com.
## `hunterApiKey` (type: `string`):

Boosts email discovery from ~30% to ~60%. Get a free key at hunter.io.
## `companiesHouseApiKey` (type: `string`):

Free UK government API. Returns director name, company number, incorporation date and SIC codes. Register at developer.companieshouse.gov.uk.
## `yourName` (type: `string`):

Your name — used to sign outreach templates.
## `yourBusiness` (type: `string`):

Your company name — used in outreach templates.
## `yourService` (type: `string`):

What you offer — e.g. 'digital marketing for new restaurants in London'.
## `yourEmail` (type: `string`):

Your contact email — included in outreach templates.
## `yourPhone` (type: `string`):

Your phone number — used in SMS templates.
## `competitors` (type: `array`):

List of competitors to monitor for rating changes and new reviews. Each entry: { "name": "Joe's Bistro", "mapsUrl": "https://maps.google.com/..." }
## `deliverEmail` (type: `boolean`):

Send results as a CSV file to your email after each run.
## `smtpHost` (type: `string`):

SMTP server hostname, e.g. smtp.gmail.com
## `smtpPort` (type: `integer`):

SMTP port, typically 587 (TLS) or 465 (SSL).
## `smtpUser` (type: `string`):

SMTP login username.
## `smtpPass` (type: `string`):

SMTP login password.
## `toEmail` (type: `string`):

Recipient email address for the CSV delivery.
## `fromEmail` (type: `string`):

Sender email address for the CSV delivery.
## `deliverSheets` (type: `boolean`):

Append results automatically to a Google Spreadsheet after each run.
## `serviceAccountJson` (type: `string`):

Paste the full service account credentials JSON from Google Cloud Console.
## `spreadsheetId` (type: `string`):

The ID from the Google Sheets URL: /spreadsheets/d/{ID}/edit
## `sheetName` (type: `string`):

Tab name to append data to. Created if it doesn't exist.
## `deliverWebhook` (type: `boolean`):

POST leads as JSON to a webhook URL — connect to HubSpot, Salesforce, Notion, or 1,000+ other tools via Zapier.
## `webhookUrl` (type: `string`):

Zapier catch hook, Make webhook, or any other HTTP endpoint.
## `webhookFormat` (type: `string`):

Send each lead as a JSON object or as a CSV row.
## `webhookPerRecord` (type: `boolean`):

Send one POST request per lead instead of all leads in one payload. Required for Zapier catch hooks and most CRM integrations.
## `deliverHubSpot` (type: `boolean`):

Create a contact in HubSpot for each lead found. Requires a HubSpot private app token.
## `hubspotToken` (type: `string`):

Create a private app in HubSpot → Settings → Integrations → Private Apps. Needs contacts write scope.
## `deliverSlack` (type: `boolean`):

Post a weekly summary of new businesses and competitor alerts to a Slack channel.
## `slackWebhookUrl` (type: `string`):

Create one at api.slack.com/messaging/webhooks
## `slackChannel` (type: `string`):

Override channel, e.g. #leads. Leave blank to use webhook default.

## Actor input object example

```json
{
  "cities": [
    "London"
  ],
  "postcodes": [],
  "radiusMiles": 5,
  "category": "restaurant",
  "customSearchTerms": [],
  "dateRangeDays": 0,
  "minReviews": 0,
  "maxReviews": 0,
  "requireWebsite": false,
  "requireUnclaimed": false,
  "scrapeEmails": true,
  "maxResults": 50,
  "incrementalMode": false,
  "yourName": "",
  "yourBusiness": "",
  "yourService": "",
  "yourEmail": "",
  "yourPhone": "",
  "competitors": [],
  "deliverEmail": false,
  "smtpHost": "",
  "smtpPort": 587,
  "toEmail": "",
  "fromEmail": "",
  "deliverSheets": false,
  "spreadsheetId": "",
  "sheetName": "Leads",
  "deliverWebhook": false,
  "webhookUrl": "",
  "webhookFormat": "json",
  "webhookPerRecord": false,
  "deliverHubSpot": false,
  "deliverSlack": false,
  "slackChannel": ""
}
````

# 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 = {
    "cities": [
        "London"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automationnation/uk-business-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 = { "cities": ["London"] }

# Run the Actor and wait for it to finish
run = client.actor("automationnation/uk-business-leads").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "cities": [
    "London"
  ]
}' |
apify call automationnation/uk-business-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automationnation/uk-business-leads",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "UK Business Leads Companies House Lookup, AI Scoring & Outreach",
        "description": "Scrape UK businesses from Google Maps with AI lead scoring, Companies House director lookup, and personalised outreach templates. More data per lead than any other Google Maps scraper.",
        "version": "1.0",
        "x-build-id": "5A24IPe72LyyrIt2C"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/automationnation~uk-business-leads/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-automationnation-uk-business-leads",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/automationnation~uk-business-leads/runs": {
            "post": {
                "operationId": "runs-sync-automationnation-uk-business-leads",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/automationnation~uk-business-leads/run-sync": {
            "post": {
                "operationId": "run-sync-automationnation-uk-business-leads",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "cities",
                    "category"
                ],
                "properties": {
                    "cities": {
                        "title": "Cities / Regions",
                        "type": "array",
                        "description": "UK cities or regions to search. E.g. London, Manchester, Birmingham. Ignored if Postcodes are set.",
                        "default": [
                            "London"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "postcodes": {
                        "title": "Postcodes (precise targeting)",
                        "type": "array",
                        "description": "UK postcodes to search around. E.g. M1 1AA, SW1A 1AA. When set, overrides Cities and uses Radius Miles for geographic targeting.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "radiusMiles": {
                        "title": "Search Radius (miles)",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Search radius around each postcode in miles. Only used when Postcodes are set. 1–20 recommended.",
                        "default": 5
                    },
                    "category": {
                        "title": "Business Category",
                        "enum": [
                            "all",
                            "restaurant",
                            "gym",
                            "hair salon",
                            "beauty salon",
                            "retail shop",
                            "cafe",
                            "bar",
                            "trades"
                        ],
                        "type": "string",
                        "description": "Type of business to find. Use 'all' to search across every category. Ignored if Custom Search Terms are set.",
                        "default": "restaurant"
                    },
                    "customSearchTerms": {
                        "title": "Custom Search Terms (override category)",
                        "type": "array",
                        "description": "Search for any business type. E.g. [\"accountant\", \"web design agency\", \"marketing agency\", \"solicitor\", \"mortgage broker\"]. Overrides the Category setting above.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "dateRangeDays": {
                        "title": "Filter: First Review Within (days)",
                        "minimum": 0,
                        "maximum": 365,
                        "type": "integer",
                        "description": "Optional. Set to 30, 60 or 90 to filter for businesses whose first Google Maps review is within that window — a proxy for recently opened. Leave at 0 (default) to return all businesses.",
                        "default": 0
                    },
                    "minReviews": {
                        "title": "Minimum Reviews",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Skip businesses with fewer than this many reviews. Use 0 to include brand-new listings.",
                        "default": 0
                    },
                    "maxReviews": {
                        "title": "Maximum Reviews (new businesses filter)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Skip businesses with more than this many reviews. Set to 10–30 to target brand-new businesses still building their reputation. Leave at 0 (default) for no cap.",
                        "default": 0
                    },
                    "requireWebsite": {
                        "title": "Must Have Website",
                        "type": "boolean",
                        "description": "Only return businesses that have a website listed on Google Maps.",
                        "default": false
                    },
                    "requireUnclaimed": {
                        "title": "Only Unclaimed Listings",
                        "type": "boolean",
                        "description": "Only return businesses that haven't claimed their Google Maps listing — easiest outreach targets.",
                        "default": false
                    },
                    "scrapeEmails": {
                        "title": "Scrape Emails from Websites",
                        "type": "boolean",
                        "description": "Visit each business website and extract email addresses. Adds ~5 seconds per business.",
                        "default": true
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of businesses to return across all cities and queries.",
                        "default": 50
                    },
                    "incrementalMode": {
                        "title": "Incremental Mode (new businesses only)",
                        "type": "boolean",
                        "description": "Skip businesses already seen in previous runs. Perfect for weekly scheduling — wake up to only new businesses each time.",
                        "default": false
                    },
                    "anthropicApiKey": {
                        "title": "Anthropic API Key (optional — Claude built-in)",
                        "type": "string",
                        "description": "Claude Haiku is built-in — you do not need this. Only add your own key if you are running thousands of businesses per month and want dedicated API capacity. Get one at console.anthropic.com."
                    },
                    "geminiApiKey": {
                        "title": "Gemini API Key (optional fallback override)",
                        "type": "string",
                        "description": "Gemini is the built-in fallback — you do not need this. Only add your own key if you hit rate limits on very large runs. Free at aistudio.google.com."
                    },
                    "hunterApiKey": {
                        "title": "Hunter.io API Key (optional)",
                        "type": "string",
                        "description": "Boosts email discovery from ~30% to ~60%. Get a free key at hunter.io."
                    },
                    "companiesHouseApiKey": {
                        "title": "Companies House API Key (UK — free)",
                        "type": "string",
                        "description": "Free UK government API. Returns director name, company number, incorporation date and SIC codes. Register at developer.companieshouse.gov.uk."
                    },
                    "yourName": {
                        "title": "Your Name",
                        "type": "string",
                        "description": "Your name — used to sign outreach templates.",
                        "default": ""
                    },
                    "yourBusiness": {
                        "title": "Your Business Name",
                        "type": "string",
                        "description": "Your company name — used in outreach templates.",
                        "default": ""
                    },
                    "yourService": {
                        "title": "Your Service / Pitch",
                        "type": "string",
                        "description": "What you offer — e.g. 'digital marketing for new restaurants in London'.",
                        "default": ""
                    },
                    "yourEmail": {
                        "title": "Your Email",
                        "type": "string",
                        "description": "Your contact email — included in outreach templates.",
                        "default": ""
                    },
                    "yourPhone": {
                        "title": "Your Phone",
                        "type": "string",
                        "description": "Your phone number — used in SMS templates.",
                        "default": ""
                    },
                    "competitors": {
                        "title": "Competitor Businesses to Monitor",
                        "type": "array",
                        "description": "List of competitors to monitor for rating changes and new reviews. Each entry: { \"name\": \"Joe's Bistro\", \"mapsUrl\": \"https://maps.google.com/...\" }",
                        "default": []
                    },
                    "deliverEmail": {
                        "title": "Deliver via Email (CSV attachment)",
                        "type": "boolean",
                        "description": "Send results as a CSV file to your email after each run.",
                        "default": false
                    },
                    "smtpHost": {
                        "title": "SMTP Host",
                        "type": "string",
                        "description": "SMTP server hostname, e.g. smtp.gmail.com",
                        "default": ""
                    },
                    "smtpPort": {
                        "title": "SMTP Port",
                        "type": "integer",
                        "description": "SMTP port, typically 587 (TLS) or 465 (SSL).",
                        "default": 587
                    },
                    "smtpUser": {
                        "title": "SMTP Username",
                        "type": "string",
                        "description": "SMTP login username."
                    },
                    "smtpPass": {
                        "title": "SMTP Password",
                        "type": "string",
                        "description": "SMTP login password."
                    },
                    "toEmail": {
                        "title": "Send CSV To",
                        "type": "string",
                        "description": "Recipient email address for the CSV delivery.",
                        "default": ""
                    },
                    "fromEmail": {
                        "title": "From Email",
                        "type": "string",
                        "description": "Sender email address for the CSV delivery.",
                        "default": ""
                    },
                    "deliverSheets": {
                        "title": "Deliver to Google Sheets",
                        "type": "boolean",
                        "description": "Append results automatically to a Google Spreadsheet after each run.",
                        "default": false
                    },
                    "serviceAccountJson": {
                        "title": "Google Service Account JSON",
                        "type": "string",
                        "description": "Paste the full service account credentials JSON from Google Cloud Console."
                    },
                    "spreadsheetId": {
                        "title": "Google Spreadsheet ID",
                        "type": "string",
                        "description": "The ID from the Google Sheets URL: /spreadsheets/d/{ID}/edit",
                        "default": ""
                    },
                    "sheetName": {
                        "title": "Sheet Name",
                        "type": "string",
                        "description": "Tab name to append data to. Created if it doesn't exist.",
                        "default": "Leads"
                    },
                    "deliverWebhook": {
                        "title": "Deliver via Webhook (Zapier / Make / CRM)",
                        "type": "boolean",
                        "description": "POST leads as JSON to a webhook URL — connect to HubSpot, Salesforce, Notion, or 1,000+ other tools via Zapier.",
                        "default": false
                    },
                    "webhookUrl": {
                        "title": "Webhook URL",
                        "type": "string",
                        "description": "Zapier catch hook, Make webhook, or any other HTTP endpoint.",
                        "default": ""
                    },
                    "webhookFormat": {
                        "title": "Webhook Payload Format",
                        "enum": [
                            "json",
                            "csv"
                        ],
                        "type": "string",
                        "description": "Send each lead as a JSON object or as a CSV row.",
                        "default": "json"
                    },
                    "webhookPerRecord": {
                        "title": "One Request Per Lead (Zapier mode)",
                        "type": "boolean",
                        "description": "Send one POST request per lead instead of all leads in one payload. Required for Zapier catch hooks and most CRM integrations.",
                        "default": false
                    },
                    "deliverHubSpot": {
                        "title": "Push Contacts to HubSpot",
                        "type": "boolean",
                        "description": "Create a contact in HubSpot for each lead found. Requires a HubSpot private app token.",
                        "default": false
                    },
                    "hubspotToken": {
                        "title": "HubSpot Private App Token",
                        "type": "string",
                        "description": "Create a private app in HubSpot → Settings → Integrations → Private Apps. Needs contacts write scope."
                    },
                    "deliverSlack": {
                        "title": "Deliver Summary to Slack",
                        "type": "boolean",
                        "description": "Post a weekly summary of new businesses and competitor alerts to a Slack channel.",
                        "default": false
                    },
                    "slackWebhookUrl": {
                        "title": "Slack Incoming Webhook URL",
                        "type": "string",
                        "description": "Create one at api.slack.com/messaging/webhooks"
                    },
                    "slackChannel": {
                        "title": "Slack Channel (optional)",
                        "type": "string",
                        "description": "Override channel, e.g. #leads. Leave blank to use webhook default.",
                        "default": ""
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
