# SiteVerdict — Agency Lead Finder: score local business websites (`siteverdict/siteverdict-agency-lead-finder`) Actor

Find which local businesses to pitch. Feed a Google Maps Scraper dataset, CSV or URL list; each website gets a 0-100 lead score, flags for web design, SEO, speed, tracking, compliance, email and accessibility, plus 3 plain-English pitch points. No-website leads too.

- **URL**: https://apify.com/siteverdict/siteverdict-agency-lead-finder.md
- **Developed by:** [Aman Thakran](https://apify.com/siteverdict) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

## SiteVerdict — Agency Lead Finder: score local business websites

**Turn a Google Maps list into a ranked call sheet: who to pitch, what to sell them, and the exact sentence to open with.** Every claim comes with evidence you can show the business owner.

You give it a list of businesses. Each website gets:

- a **0-100 lead score**;
- the **services the business needs**: web design, SEO, speed, tracking/ads, compliance, email deliverability or accessibility;
- **three plain-English pitch points** you can paste into an email or say on a call.

It also finds:

- businesses with **no website**, a Facebook-only page or a **broken site**;
- the business's **UK company number** (with Companies House data if you add your free key);
- an optional one-line **AI pitch** (your own key).

Leads export to `LEADS.csv` and to a **HubSpot import file**.

In our own check on 11 Oct 2026 (20 Plymouth businesses, 200 facts compared with `curl`/`dig`/`openssl` run separately), every checked fact matched and there were no false findings. That is a small test of 10 technical facts per site, not a guarantee for every site; see [Benchmark](#benchmark) for what was and was not checked.

### Three ways agencies use it

1. **Web-design and SEO agencies.** Scrape "plumbers in Leeds" with Google Maps Scraper, then run this Actor on the results. You get the 30 best leads first, for example:

   - *"Your site has no HTTPS, so Chrome labels it Not secure."*
   - *"On a 4G phone your homepage takes 5.3 s to load."*

   No-website and broken-site businesses come out as separate, cheap leads.
2. **Specialists.** Set `targetService` (e.g. `seo`, `speed` or `compliance`) to re-rank by *your* service and see why each lead fits. Example: *"SEO opportunity (14 pts): No XML sitemap; Missing meta description."* Turn on `onlyTargetService` to pay only for leads you can sell to.
3. **Agencies with a CRM.** Import `HUBSPOT_COMPANIES.csv` straight into HubSpot. For UK leads, add the Companies House record so you can skip dissolved companies and see the company's age, SIC codes and accounts size.

### Before → after

**Before:** a Google Maps export.

```
Smith Plumbing, smithplumbing.co.uk, 4.8★, 52 reviews
```

**After** (trimmed):

```json
{ "leadScore": 74, "tier": "A", "tierLabel": "Hot lead", "status": "scored", "name": "Smith Plumbing",
  "servicesToPitch": "Web design, Speed, SEO",
  "pitch1": "Your site has no secure padlock (HTTPS). Chrome labels it \"Not secure\", which puts off customers and hurts Google rankings.",
  "pitch2": "On a typical 4G phone your homepage takes 5.3 s to show its main content...",
  "aiPitch": "Smith Plumbing's 52 five-star reviews are being undercut by a site Chrome flags as Not secure and that takes 5 seconds to load on phones, both fixable in a week.",
  "targetService": { "service": "SEO", "points": 11, "flagged": true, "why": "SEO opportunity (11 pts): No XML sitemap; Missing meta description" },
  "company": { "onSite": { "ukCompanyNumber": "12345678", "vatNumber": "GB987654321", "socialProfiles": { "facebook": "https://www.facebook.com/smithplumbing" } },
               "companiesHouse": { "companyName": "SMITH PLUMBING LTD", "status": "active", "incorporatedOn": "2015-06-01", "sicCodes": [{ "code": "43220", "description": "Plumbing, heat and air-conditioning installation" }] } },
  "phone": null, "hasPhone": true }
```

### Benchmark

We took 20 independent businesses in Plymouth, UK, from OpenStreetMap open data (ODbL). We checked the Actor against `curl`, `dig` and `openssl` run separately. Full method and caveats are in `BENCHMARK.md`.

| | Facts correct (200) | False findings | Time per site | 100 sites cost |
|---|---|---|---|---|
| Quick mode | 200/200 | 0 | ~2 s | $0.50 |
| Full mode (real mobile Chrome) | 200/200 | 0 | ~11 s | $1.50 |

Limits of this test: one town, 20 small-business sites, one day (11 Oct 2026), and only the 10 facts listed below. Sites behind bot protection, unusual DNS set-ups or pages that change between checks can give different results, and the lead scores and sales notes are judgement calls that this test does not measure.

The checked facts:

- the up/down verdict;
- the HTTP→HTTPS redirect;
- TLS days left;
- SPF and DMARC;
- the sitemap;
- the viewport tag;
- the title;
- the WordPress version;
- GA4 and GTM IDs.

**Compared with the most-used alternatives**, from their public docs (we did not run them):

| Actor | Price per 100 | Personal data |
|---|---|---|
| Local Lead Generation Agent | $3 | Collects emails and phones |
| Google Maps Leads + Website Audit | $1-15 | Collects emails and phones |
| Website Audit Lead Finder | $2, +$1.20 with AI | Extracts emails |
| **This Actor** | **$0.50 quick / $1.50 full** | **Off by default** |

Only this Actor measures real mobile Core Web Vitals and cookies set before consent, and only it detects hosting error pages, adds Companies House data and exports for HubSpot.

### Pair it with Google Maps Scraper (the 2-minute workflow)

1. Run [Google Maps Scraper](https://apify.com/compass/crawler-google-places) for something like `plumbers in Plymouth` or `dentists in Leeds`.
2. Copy the **dataset ID** (or **run ID**) from that run's Storage tab.
3. Paste it into **Google Maps Scraper dataset ID** here and click **Start**.
4. Open the **Leads** table (sort by Lead score), download `LEADS.csv` (already ranked best-first), or open the HTML **REPORT** to share with your team.

Field names such as `title`, `website`, `phone`, `categoryName`, `city`, `address`, `totalScore`, `reviewsCount`, `permanentlyClosed` are mapped automatically, and every original field is passed through in `original`.

**Automate it:** add this Actor as an *integration* on your Google Maps Scraper task (Integrations → "Run Actor"), passing the run ID. Every scrape is then scored automatically.

You can also use:

- **A CSV or JSON file URL** (Google Sheets → File → Share → Publish to web → CSV). Columns like *Business Name, Website, Phone, Town, Category, Reviews, Rating* are recognised.
- **A JSON list of businesses**: `[{"name": "Smith Plumbing", "website": "smithplumbing.co.uk", "phone": "...", "city": "Plymouth", "reviewsCount": 48}]`
- **Plain website URLs** (no business data, so the activity part of the score is neutral).

### What it checks on every website

| Service you can sell | What we look for |
|---|---|
| **Web design** | No website / Facebook-only / directory-only / free builder subdomain (e.g. `*.wixsite.com`), site down, parked or "coming soon" page, not mobile-friendly (no viewport, sideways scrolling), no HTTPS, expired / invalid / expiring SSL, HTTP not redirected to HTTPS, broken contact page or homepage links, buttons that do nothing (dead clicks), no click-to-call link, outdated WordPress / jQuery / PHP, footer copyright years out of date |
| **Speed** | Real mobile load (390 px, Fast 4G + 2x CPU): Largest Contentful Paint, layout shift (CLS) with the elements that move, Total Blocking Time, page weight, oversized images. Quick mode: server response time and render-blocking scripts |
| **SEO** | Homepage hidden by `noindex` or robots.txt, missing / poor title, missing meta description, no H1, no LocalBusiness structured data, no XML sitemap, no social sharing preview, **AI search engines blocked** (OAI-SearchBot, PerplexityBot, Claude-SearchBot...), Bing blocked |
| **Tracking / Ads** | No analytics, only the retired Universal Analytics, GA4 configured but not recording, Meta Pixel installed but not firing, tracking scripts that fail to load, no ad / retargeting pixels |
| **Compliance** (UK/EU) | Analytics / advertising / session-replay tools and their cookies running **before any consent** with no cookie banner (high) or despite a banner (medium); no privacy policy link. A risk indicator, not legal advice |
| **Email deliverability** | No SPF, multiple SPF records, SPF that lets anyone send (`+all` / `?all`), no DMARC, DMARC monitor-only (`p=none`). Public DNS only; no emails are collected or sent |
| **Accessibility** | Pinch-zoom disabled, images without alt text, form fields without labels, icon-only buttons/links without names, page language missing, tap targets too small (WCAG 2.2 SC 2.5.8) |

Every finding has the **evidence** we measured (numbers, IDs, file names) and a **confidence** flag: `measured` (seen in a real browser, DNS or TLS) or `estimated` (inferred from the HTML in Quick mode).

### How the lead score works

- **Opportunity (0-70):** each problem adds points by severity (for example no website 70, site down 60, very slow mobile 18, tracking without consent 14, missing meta description 6). Points go through a diminishing-returns curve, so one huge problem or many small ones both rank well.
- **Activity (0-30):** Google reviews (log scale, up to 20), rating (up to 5) and a phone number (3). If your input has no review data, a neutral 12 is used.
- **Tiers:** A ≥ 70 *Hot lead*, B ≥ 55 *Warm*, C ≥ 40 *Possible*, D below 40.

A brilliant website owned by a busy business scores low on purpose: there's nothing to sell them.

### Example output (one business, trimmed)

```json
{
  "leadScore": 77,
  "tier": "A",
  "tierLabel": "Hot lead",
  "status": "scored",
  "name": "Example Boat Tours",
  "website": "https://example-boattours.co.uk/",
  "phone": null,
  "hasPhone": true,
  "category": "Boat tour agency",
  "city": "Plymouth",
  "rating": 4.6,
  "reviewsCount": 900,
  "servicesToPitch": "Speed, Compliance, SEO, Web design",
  "pitch1": "On a typical 4G phone your homepage takes 5.3 s to show its main content. Google's \"good\" mark is 2.5 s, and slow pages lose visitors before they ever see you.",
  "pitch2": "Your site runs tracking (Google Analytics 4) with no cookie banner. Under UK/EU cookie rules (PECR / ePrivacy) that needs consent first, a risk indicator worth fixing.",
  "pitch3": "Your homepage has no meta description, so Google picks random text for your search snippet instead of a sales message.",
  "opportunities": {
    "webDesign": { "flag": true, "points": 9, "issues": ["no-click-to-call", "outdated-jquery"] },
    "seo": { "flag": true, "points": 10, "issues": ["missing-meta-description", "no-local-schema"] },
    "speed": { "flag": true, "points": 24, "issues": ["slow-lcp", "heavy-page"] },
    "trackingAds": { "flag": false, "points": 3, "issues": ["no-ad-pixels"] },
    "compliance": { "flag": true, "points": 14, "issues": ["trackers-no-consent"] },
    "emailDeliverability": { "flag": false, "points": 3, "issues": ["dmarc-none"] },
    "accessibility": { "flag": false, "points": 3, "issues": ["unnamed-controls"] }
  },
  "issues": [
    {
      "id": "slow-lcp", "service": "speed", "severity": "high", "points": 18,
      "title": "Very slow on mobile (LCP)",
      "evidence": "Mobile LCP 5.3 s (Mobile 390x844, Fast 4G ... + 2x CPU slowdown)",
      "confidence": "measured"
    },
    {
      "id": "trackers-no-consent", "service": "compliance", "severity": "high", "points": 14,
      "title": "Tracking without a cookie banner",
      "evidence": "Before any consent: Google Analytics 4, cookie _ga_XXXXXXX, cookie _ga",
      "confidence": "measured"
    }
  ],
  "scoreBreakdown": { "opportunityScore": 48.9, "activityScore": 28, "activityKnown": true },
  "tech": {
    "mobileLcpMs": 5348, "mobileCls": 0.0026, "pageWeightKb": 5973, "https": true, "sslDaysLeft": 163,
    "builder": "WordPress", "trackingTools": ["Google tag (gtag.js)", "Google Analytics 4"],
    "consentTool": null, "spf": "strict (-all)", "dmarc": "none"
  },
  "scanMode": "full",
  "scanMs": 12710,
  "original": { "...": "every field from your input row" }
}
```

A business with no website looks like this:

```json
{ "leadScore": 77, "tier": "A", "status": "no-website", "name": "Example Corner Cafe", "reviewsCount": 210, "rating": 4.7,
  "servicesToPitch": "Web design, SEO",
  "pitch1": "Your Google listing has no website, so people who find you on Maps cannot see your services, prices or reviews in one place and often pick a competitor who has one." }
```

### Sales options (new in 1.1)

| Option | What it does | Cost |
|---|---|---|
| `targetService` | Re-ranks leads by the opportunity for the one service you sell, with a reason, e.g. *"Speed opportunity (24 pts): Very slow on mobile (LCP); Heavy page"* | included |
| `onlyTargetService` | Only outputs leads with an opportunity for that service. The rest are not output and **not charged** | included |
| `companyEnrichment` | Reads the UK company number, VAT number, schema.org organisation data and company social pages that the business publishes on its own site | included |
| `companiesHouseApiKey` | Your free Companies House key. Adds status, incorporation date, SIC codes, accounts type and registered office. Matching uses the number on the site, or an exact name match. No officers or personal data are fetched | `company-enriched`, only when a record is attached |
| `aiProvider` + `aiApiKey` | One factual opening line per good lead, built from its measured issues, using your own Anthropic or OpenAI key (default model `claude-sonnet-5-5`). Nothing is sent to the business | `ai-pitch`, only when a line is written |
| `exportHubspot` | `HUBSPOT_COMPANIES.csv` for HubSpot → Import → Companies. Company Domain Name de-duplicates; the "SiteVerdict …" columns become custom properties | included |
| `includeBusinessPhone` | Adds the listing's phone number. **Off by default** | included |

### Outputs

- **Dataset** with four views: *Leads (CSV-friendly)*, *Opportunity flags by service*, *All issues with evidence* (one row per issue) and *Technical summary*.
- **`HUBSPOT_COMPANIES.csv`**: the HubSpot Companies import file (phone column empty unless you opt in).
- **`LEADS.csv`** in the key-value store: every business ranked best-first, Excel/Sheets-ready (UTF-8 with BOM, formula-injection safe).
- **`REPORT`**: an HTML report ranking the best prospects with their pitch points (works on phones; light and dark mode).
- **`SUMMARY`**: JSON with counts, tiers, what was filtered out and the top 10.
- Optional **mobile screenshot** per site (`saveScreenshots`), handy for "here's how your site looks on a phone" emails.

`status` tells you what happened to each row: `scored`, `no-website`, `social-only` (Facebook / Instagram / Linktree / directory listing), `website-down`, `duplicate` (same website as an earlier row: scanned once, reused, free), `scan-blocked` (bot protection; not charged) or `scan-failed` (not charged).

### Scan modes

| | Full (default) | Quick |
|---|---|---|
| How | One real mobile Chrome load per site + HTTP, TLS and DNS checks | HTTP, TLS and DNS only, no browser |
| Typical time per site | 10-17 s (6 in parallel) | 2-5 s (16 in parallel) |
| Speed findings | Measured Core Web Vitals | Estimated from server response and HTML |
| Tracking / consent | Real network hits and cookies set before consent | Tags and consent tools found in the HTML |
| Best for | Lists up to a few thousand, when you'll actually pitch | Very large lists, first-pass filtering |

### Filters

Category words, cities/towns, minimum reviews, minimum rating, *with website / without website* (the "without website" option skips all scanning and is the cheapest way to find web-design leads), and skip permanently/temporarily closed businesses (on by default).

### Pricing

Pay per result, no subscription. You're charged only for businesses that produce a result:

| Event | When |
|---|---|
| `business-scored` | A website was fully scored in a real browser |
| `business-quick-scored` | A website was scored in Quick mode (HTTP only), or in Full mode when the browser couldn't load it but the HTML could still be scored |
| `no-website-lead` | A business with no website, a social-only page, a site that is down or a site showing a hosting error page |
| `company-enriched` | A Companies House record was attached (needs your free key) |
| `ai-pitch` | An AI pitch line was written with your own LLM key |

**Example costs at the proposed prices:**

| Job | Approximate cost |
|---|---|
| 100 websites, quick mode | $0.50 |
| 100 websites, full mode | $1.50 |
| 500 Google Maps places (420 with a website, 80 without), full mode | ≈ $6.46 |
| + Companies House for 60 UK companies | ≈ $0.24 more |
| + AI lines for the 50 best leads | ≈ $0.25 more |

Never charged: duplicates of a website already scanned in the run, sites behind bot protection, scans that fail or time out, and rows removed by your filters. Your **maximum total charge per run** is respected: once it's reached, the remaining businesses are skipped (not scanned, not charged) and the run finishes with the report of everything done so far. See the Pricing tab for current prices.

### Privacy and responsible outreach (UK / EU)

- **Personal data is OFF by default.** Phone numbers from your input are removed from the output and from `original` unless you turn on `includeBusinessPhone`. A sole trader's phone number is personal data under UK GDPR. We keep only a `hasPhone` flag for scoring.

  Email addresses are **never** collected, and neither are reviewer names, staff names or personal social profiles. Company social pages, e.g. `linkedin.com/company/…`, are kept; `/in/` profiles are not. We don't follow links to Facebook or Instagram pages: those businesses are reported as "social-only" without the page being opened.

- **What we process:** the business data you provide, plus technical checks of the business's public website and public DNS records. Optionally we also use Companies House public data, with your key. *Contains public sector information licensed under the Open Government Licence v3.0.* No officers or PSCs are fetched.

- **Honest crawling:** one homepage load per site plus a handful of light requests (robots.txt, sitemap, up to 5 links, TLS and DNS). Requests identify themselves as `SiteVerdictLeadFinder/1.1 (+https://apify.com/siteverdict/siteverdict-agency-lead-finder)`. Sites with bot protection are skipped, not bypassed.

- **Your outreach is your responsibility.** In the UK, emailing or calling businesses is governed by **UK GDPR** and **PECR**. Generally, B2B emails to *corporate* subscribers (limited companies, LLPs) don't need prior consent under PECR, but **sole traders and some partnerships are treated like individuals** and do. If you use personal data (for example a named contact's email), you need a lawful basis, typically **legitimate interests** backed by a documented **Legitimate Interests Assessment (LIA)**, plus a clear privacy notice and an easy opt-out in every message. Screen phone numbers against the **TPS / CTPS** before cold calling. EU countries have similar but different rules.

- The **Compliance** findings are **risk indicators** based on what the homepage does before a visitor makes a choice. They are not legal advice and not a full cookie audit. Please don't present them to prospects as legal conclusions.

- **Where results are stored:** the default dataset and key-value store of the run (scored rows, reports and exports), inside your own Apify account. When you point it at another dataset (for example a Google Maps Scraper run), that dataset is only read, never changed. Default storages are unnamed; how long Apify keeps them is set by Apify and your plan, not by SiteVerdict ([Apify data retention](https://docs.apify.com/platform/storage/usage#data-retention)). You can delete them sooner in Apify Console.

- **Third parties you choose:** Companies House enrichment uses your own key. The optional AI pitch sends your offer description and the prospect facts the Actor found (public website, DNS and register data; no personal contact details) to Anthropic or OpenAI under your own key and their terms.

- **What SiteVerdict keeps:** nothing. The Actor runs in your Apify account and sends no data to SiteVerdict; our contact address appears only in the User-Agent sent to the sites it checks.

This section is general information, not legal advice. See the ICO's guidance on [direct marketing](https://ico.org.uk/for-organisations/direct-marketing-and-privacy-and-electronic-communications/) and [legitimate interests](https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/lawful-basis/legitimate-interests/).

### FAQ

**Which Google Maps Scraper fields do I need?** Just `title` and `website`. `reviewsCount`, `totalScore` and `phone` improve the score. The Google Maps `url` is never mistaken for the business website.

**Can I run it on another account's dataset?** You can read any dataset your Apify token can access (your own, or one shared with you).

**Why did a site I know is fine get a speed issue?** Speed is measured on a simulated mid-range phone on 4G from a data centre, once. Lab numbers vary from run to run (often ±20-30%) and differ from Google's real-user (CrUX) data. Treat speed findings as a conversation starter and re-test before quoting numbers.

**The compliance finding says there's no cookie banner, but there is one.** Some banners only appear to visitors in the UK/EU. If you mainly prospect UK/EU businesses, set the proxy to a UK datacenter proxy (`apifyProxyCountry: GB`) for the most accurate consent results. When consent-tool code is present in the page we never claim "no banner".

**Do you send any emails or test contact forms?** No. We never submit forms or send emails. "Broken contact page" means the contact link returns 404/410/5xx.

**What about sites behind Cloudflare / bot protection?** Full mode tries once with a real browser; if a challenge page still answers, the row is `scan-blocked` and not charged. We don't attempt to bypass protection.

**How do duplicates work?** Chains and multi-location businesses often share one website. It's scanned once; the other rows reuse the result (marked `duplicate`, not charged) but keep their own reviews/rating in the score.

### Limits

- Homepage only (plus a light check of up to 5 linked pages). Deep page-by-page audits are out of scope; use SiteVerdict's dedicated speed, tracking, accessibility and domain-health Actors for that.
- One lab measurement per site; numbers vary between runs.
- Consent detection checks behaviour before any click (we never click banners). It does not verify what happens after "Reject".
- Accessibility checks are a quick heuristic, not a WCAG audit.
- Email checks cover SPF / DMARC / MX only (no DKIM selector guessing, no mailbox tests).
- Quick mode can't measure Core Web Vitals or real tracking hits, and some hosts refuse plain HTTP clients (marked `scan-blocked`, not charged).
- Max 50,000 businesses per run.

### Support

Found a wrong finding or want a check added? Open an issue on the Actor's Issues tab with the website and what you expected. We read every report.

*SiteVerdict is built by BharatFare Travel and Technologies Ltd (UK).*

# Changelog

This Actor's version history is a separate document: https://apify.com/siteverdict/siteverdict-agency-lead-finder/changelog.md

# Actor input Schema

## `datasetId` (type: `string`):

Paste the dataset ID (or dataset URL) from a Google Maps Scraper run, e.g. compass/crawler-google-places. Fields like title, website, phone, categoryName, city, totalScore and reviewsCount are mapped automatically.

## `runId` (type: `string`):

A run ID (or run URL). The run's default dataset is read. Handy for Actor-to-Actor integrations and webhooks.

## `fileUrl` (type: `string`):

Public URL of a CSV, JSON array, JSON Lines file or a plain list of URLs (one per line). Google Sheets: File > Share > Publish to web > CSV. Columns such as name, website, phone, address, city, category, rating and reviews are recognised automatically.

## `businesses` (type: `array`):

A list of objects, e.g. \[{"name": "Smith Plumbing", "website": "smithplumbing.co.uk", "phone": "+44...", "city": "Plymouth", "category": "Plumber", "reviewsCount": 48}]. Businesses without a website are returned as no-website leads.

## `websites` (type: `array`):

Plain list of websites to score (no business data, so the activity part of the score uses a neutral value).

## `scanMode` (type: `string`):

Full = one real mobile browser load per site (Core Web Vitals, layout shift, real tracking hits, cookies set before consent, dead clicks) + HTTP/DNS checks. Quick = HTTP and DNS only, no browser: about 5x faster and cheaper, for very large lists; speed and tracking findings are estimated from the HTML.

## `maxBusinesses` (type: `integer`):

Stop after this many businesses (after filters). Your max total charge per run is respected as well.

## `complianceRegion` (type: `string`):

UK/EU turns on the cookie-consent risk indicator (UK GDPR + PECR / EU ePrivacy): tracking or advertising cookies set before any consent. Choose 'Other' for markets without prior-consent cookie rules.

## `checkEmailDns` (type: `boolean`):

Public DNS lookups of SPF, DMARC and MX for the website's domain. No emails are collected or sent.

## `checkLinks` (type: `boolean`):

Light HEAD requests to the contact page and up to 4 other homepage links to catch broken pages.

## `categories` (type: `array`):

Keep businesses whose category contains any of these words (case-insensitive), e.g. dentist, plumber, restaurant. Empty = all.

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

Keep businesses whose city or address contains any of these (case-insensitive). Empty = all.

## `minReviews` (type: `integer`):

Skip businesses with fewer Google reviews (a proxy for an active business that can pay). 0 = no minimum.

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

Skip businesses rated below this (0-5). 0 = no minimum.

## `websiteFilter` (type: `string`):

All = score websites and return businesses without a website as no-website leads. With website = only scan businesses that have a site. Without website = only return no-website / social-only leads (no scanning, cheapest).

## `skipClosed` (type: `boolean`):

Skip rows marked permanently or temporarily closed (Google Maps Scraper fields).

## `maxConcurrency` (type: `integer`):

Sites scanned in parallel. 0 = automatic (6 in full mode, 16 in quick mode). In full mode allow roughly 500 MB of memory per parallel site.

## `navigationTimeoutSecs` (type: `integer`):

How long to wait for a homepage. Sites slower than this are still scored from whatever loaded.

## `mobileThrottling` (type: `string`):

Fast 4G + 2x CPU approximates a mid-range phone on 4G. 'None' measures raw speed from the data centre (numbers look better).

## `saveScreenshots` (type: `boolean`):

Saves a 390px-wide screenshot of each homepage to the key-value store, handy for outreach emails.

## `includeOriginalFields` (type: `boolean`):

Copy every field of the input row into 'original' on each result (e.g. all Google Maps Scraper fields).

## `targetService` (type: `string`):

Re-ranks leads by the opportunity for the service you sell and explains it (e.g. "SEO opportunity (14 pts): No sitemap; Missing meta description").

## `onlyTargetService` (type: `boolean`):

Leads without one are not output and not charged.

## `includeBusinessPhone` (type: `boolean`):

Off by default (UK GDPR: a sole trader's phone is personal data). When off, phone numbers are removed from the output and from original fields, and only hasPhone is kept. Emails are never collected.

## `companyEnrichment` (type: `boolean`):

Free: UK company number, VAT number, schema.org organisation data and company social pages that the business itself publishes.

## `companiesHouseApiKey` (type: `string`):

Your free key from developer.company-information.service.gov.uk. Adds status, incorporation date, SIC codes and accounts type. Charged (company-enriched) only when a record is attached. Officers are never fetched.

## `companyNameSearch` (type: `boolean`):

UK only, exact normalised name match (one active company) so it never guesses.

## `aiProvider` (type: `string`):

Writes one factual, specific opening line per good lead from its measured issues. Nothing is sent to the business.

## `aiApiKey` (type: `string`):

Your Anthropic or OpenAI key; billed by your provider, never logged or stored.

## `aiModel` (type: `string`):

Default: claude-sonnet-5-5 (Anthropic) or gpt-4o-mini (OpenAI).

## `aiOfferDescription` (type: `string`):

e.g. "Fast WordPress rebuilds and local SEO for trades in Devon".

## `aiMinLeadScore` (type: `integer`):

Keeps your LLM spend on the best leads.

## `aiMaxLeads` (type: `integer`):

Hard cap on generated lines (and on the ai-pitch event).

## `exportHubspot` (type: `boolean`):

Ready for HubSpot > Import > Companies (Company Domain Name de-duplicates).

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

Optional. Most small-business sites don't need a proxy. Datacenter proxy is enough when a host rate-limits.

## Actor input object example

```json
{
  "websites": [
    "https://www.example.com"
  ],
  "scanMode": "full",
  "maxBusinesses": 100,
  "complianceRegion": "uk-eu",
  "checkEmailDns": true,
  "checkLinks": true,
  "minReviews": 0,
  "minRating": 0,
  "websiteFilter": "all",
  "skipClosed": true,
  "maxConcurrency": 0,
  "navigationTimeoutSecs": 20,
  "mobileThrottling": "fast-4g",
  "saveScreenshots": false,
  "includeOriginalFields": true,
  "targetService": "none",
  "onlyTargetService": false,
  "includeBusinessPhone": false,
  "companyEnrichment": true,
  "companyNameSearch": false,
  "aiProvider": "none",
  "aiMinLeadScore": 55,
  "aiMaxLeads": 100,
  "exportHubspot": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `report` (type: `string`):

No description

## `csv` (type: `string`):

No description

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

No description

## `leads` (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 = {
    "websites": [
        "https://www.example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("siteverdict/siteverdict-agency-lead-finder").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 = { "websites": ["https://www.example.com"] }

# Run the Actor and wait for it to finish
run = client.actor("siteverdict/siteverdict-agency-lead-finder").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 '{
  "websites": [
    "https://www.example.com"
  ]
}' |
apify call siteverdict/siteverdict-agency-lead-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,siteverdict/siteverdict-agency-lead-finder"
        }
    }
}
```

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/EEnXbiJWFY0gCts2v/builds/LOXRa79BpZO99TLAf/openapi.json
