# Security & Website Pain Prospect Finder for MSPs (`probelane/security-prospect-finder`) Actor

Turn a list of company websites into a scored, pitch-ready prospect list. Finds spoofable email domains (DMARC/SPF/DKIM), expired SSL, sites down, outdated WordPress/PHP, no HTTPS and expiring domains — with evidence, a 0-100 opportunity score and a cold-open line.

- **URL**: https://apify.com/probelane/security-prospect-finder.md
- **Developed by:** [Probelane](https://apify.com/probelane) (community)
- **Categories:** Lead generation, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$15.00 / 1,000 company scoreds

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

## Security & Website Pain Prospect Finder

**Paste a list of company websites. Get back a ranked prospect list your sales team can work today: each company's biggest security or website problem, the exact proof, why it costs them money, an opportunity score from 0 to 100, and a one-line cold opener.**

Built for **MSPs, cybersecurity firms, web agencies, IT consultants and email-deliverability specialists** who sell to small and mid-sized businesses. A plain lead list tells you who exists. This tells you who has a problem you can fix, and gives you the opener.

- 🎯 **One sales-ready row per company**, sorted best prospect first
- 🔎 **Evidence you can quote**: the actual DMARC/SPF record, certificate dates, HTTP status, software version or missing header
- 💬 **Plain-English "why it matters"** (for example *"anyone can send email as @acme.com → invoice-fraud risk"*) plus a suggested offer and a cold-open line
- 📊 **Opportunity score 0–100** to prioritise call lists and sequences
- 💸 **Pay only for companies you receive**. Invalid inputs, non-existent domains and companies below your minimum score are free.
- 🛡️ **Passive and public only**: DNS lookups, one homepage visit, a TLS handshake and a registry lookup. No port scanning, no logins, no exploitation.

***

### What it finds

| Signal | Example evidence | Why buyers care |
|---|---|---|
| **Spoofable email domain**: no DMARC, or DMARC `p=none` | `No DMARC TXT record at _dmarc.acme.com. SPF: "v=spf1 include:spf.protection.outlook.com ~all"` | Anyone can send email as @acme.com, the setup behind fake-invoice and "our bank details changed" scams. Gmail, Yahoo and Microsoft now require DMARC for bulk senders. |
| **Broken SPF**: missing, `+all`, two records, more than 10 lookups | `SPF: "v=spf1 a mx include:… +all"` | Their own invoices and quotes land in spam, and forged mail gets through |
| **No DKIM** | `No DKIM key on 59 common selectors` | Weaker deliverability, and fails the Gmail/Yahoo sender rules |
| **SSL expired, invalid or expiring** | `Certificate … valid to 2026-07-23, error: certificate has expired` | Browsers show a full-page warning and visitors leave |
| **No HTTPS / no HTTP→HTTPS redirect** | `TLS on acme.com:443 failed; site served at http://www.acme.com/` | Chrome marks the site "Not secure", so contact-form leads drop |
| **Website down, 5xx, suspended or placeholder** | `GET https://acme.com/ → HTTP 503` / `page title "Domain Registered"` | Lost enquiries. This is a strong web-agency lead. |
| **Slow website** | `GET https://www.acme.com/: 9,500 ms` | Visitors bounce and Google ranks the site lower |
| **Outdated or end-of-life software**: WordPress, PHP, Drupal, Joomla, Magento 1, jQuery below 3.5 | `WordPress 6.0.16 (current 7.1)` / `X-Powered-By: PHP/7.4.33` | Prime target for automated hacking bots. A natural lead for a maintenance retainer. |
| **Domain expired or expiring within 30 days** | `Registry expiry date: 2026-10-26` | If auto-renew is off, the website and every mailbox go dark |
| **Missing security headers / version leaks** | `Missing: HSTS, Content-Security-Policy, X-Frame-Options` | Fails client security questionnaires |

Every row also includes the **detected stack** (CMS and version, PHP, hosting/CDN, certificate issuer) and the **mail provider** (Microsoft 365, Google Workspace, Proofpoint, or "hosting-provider mail", which is often a migration opportunity).

### Example output

Real run on 51 small accountants, law firms and dental practices in South Africa and the USA (company names anonymised):

| # | Company | Score | Severity | Top problem | Evidence | Cold-open line |
|---|---|---|---|---|---|---|
| 1 | Example Tax & Accounting | 81 | critical | Domain can be spoofed: no DMARC record | `No DMARC TXT record at _dmarc.example-tax.com. SPF: none.` | "Quick heads-up: anyone can currently send email that looks like it's from @example-tax.com because there's no DMARC record. I can send you the exact DNS fix; it takes about 15 minutes." |
| 2 | Example Attorneys Inc. | 81 | critical | Domain can be spoofed: no DMARC record (+ outdated WordPress 6.0) | `No DMARC TXT record … SPF: "v=spf1 +a +mx … ~all"` | "Quick heads-up: anyone can currently send email that looks like it's from @example-attorneys.co.za…" |
| 4 | Example Accounting & Tax | 76 | critical | SSL certificate expired | `Certificate for example.co.za: issuer Sectigo Limited, valid to 2026-07-23T23:59:59Z` | "Visitors to example.co.za currently get a browser security warning (certificate expired). It's usually a same-day fix." |
| 18 | Example Labour Law | 68 | high | Domain can be spoofed: DMARC is monitor-only (+ host placeholder page instead of a website) | `_dmarc.example.co.za: "v=DMARC1; p=none;"` | "Your DMARC record for @example.co.za is still on p=none, which means spoofed emails using your domain still get delivered…" |
| 22 | Example CPA | 52 | high | No HTTPS: site only works over plain HTTP | `TLS on example.com:443 failed; site served at http://www.example.com/` | "Chrome shows example.com as 'Not secure' because it has no HTTPS…" |

From that run: **30 of 51** firms with mailboxes on their domain could be spoofed (no DMARC or `p=none`), **1** had an expired certificate, **2** had no HTTPS at all, **1** showed a host "coming soon" page instead of a website, **3** had a domain expiring within 30 days, and **10** were running vulnerable jQuery, outdated WordPress or end-of-life PHP.

Full row (JSON, abridged):

```json
{
  "rank": 1,
  "company": "Example Tax & Accounting",
  "domain": "example-tax.com",
  "website": "https://www.example-tax.com/",
  "opportunityScore": 81,
  "severity": "critical",
  "topProblem": "Domain can be spoofed: no DMARC record",
  "evidence": "No DMARC TXT record at _dmarc.example-tax.com. SPF: none.",
  "whyItMattersCommercially": "Anyone can send email that appears to come from @example-tax.com and receivers have no instruction to block it — the setup behind invoice-fraud and 'our bank details changed' scams…",
  "suggestedPitch": "Email-authentication hardening: publish DMARC (p=none + reporting), fix SPF/DKIM, move to p=reject in 4–6 weeks, then monthly DMARC monitoring.",
  "coldOpenLine": "Quick heads-up: anyone can currently send email that looks like it's from @example-tax.com because there's no DMARC record — I can send you the exact DNS fix, it takes about 15 minutes.",
  "otherSignals": "[high] No SPF record | [medium] No DKIM signing key found | [low] Missing security headers (grade F)",
  "signalCount": 4,
  "detectedStack": "ProSites · SSL: ZeroSSL GmbH",
  "mailProvider": "Google Workspace",
  "niche": "CPA",
  "location": "Boise ID US",
  "source": "input",
  "checkedAt": "2026-10-07T03:47:12Z",
  "signals": [ { "code": "no_dmarc", "severity": "critical", "problem": "…", "evidence": "…" } ]
}
```

### How to use it

1. **Add companies.** Use any of these:
   - **Company websites**: one per line, as a domain, URL or email. You can add labels separated by commas: `acme.co.za, Acme Attorneys, law firm, Durban`.
   - **CSV / Google Sheet URL**: a public CSV link. Columns are detected by name (`domain`/`website`/`url`, `company`/`name`, `niche`/`industry`, `location`/`city`).
   - **Discovery pages** (optional): a public directory or member-list page you are allowed to use. The Actor collects the company websites it links to.
2. Optionally set a **niche/location label** and a **minimum opportunity score**.
3. Click **Start**. Results are sorted by opportunity score. Open the **Prospects** view, or download **CSV / Excel / JSON**.

**Output views:** *Prospects* (overview), *CSV / CRM export* (all flat columns), *Outreach sheet* (company, website, problem, opener, pitch) and *Technical evidence* (raw DMARC/SPF records, SSL dates, HTTP status, domain expiry). A sorted `prospects.csv` is also saved in the run's key-value store.

### Use cases

- **MSPs and IT providers**: find local firms on hosting-provider mail with no DMARC, then lead with a free "email spoofing check" and convert to Microsoft 365 / Google Workspace security and monitoring.
- **Cybersecurity consultants and vCISOs**: build a target list of accountants, law firms and clinics (which handle payments and sensitive data) that are exposed to invoice fraud, and open with evidence instead of fear.
- **Web agencies**: find businesses with expired SSL, no HTTPS, placeholder or suspended sites, slow pages or WordPress versions years out of date. These are ready-made redesign and maintenance-plan leads.
- **Email deliverability and DMARC vendors**: segment by `dmarcPolicy` (none vs missing) and mail provider.
- **Account managers**: run the list against your **existing clients** to find upsell work and fix gaps before a competitor points them out.

### Pricing

**Pay per event: $0.015 per company scored.** That is **$1.50 per 100 companies** or **$15 per 1,000**, and there is no subscription.

- You are charged only for companies **delivered in your results**.
- **Free:** invalid inputs, domains that don't exist, duplicates, and companies hidden by your *minimum opportunity score*.
- The Actor respects your **maximum cost per run**. It stops cleanly once the limit is reached and still returns a sorted list.
- Platform usage is included in the price (no separate compute bill).
- Apify's minimum *maximum cost per run* for this Actor is $0.50 (about 33 companies). Smaller lists simply cost less.

One closed deal from a 1,000-company scan typically pays for the scan many times over.

### Feed it into your CRM, Sheets, Make or Zapier

- **Google Sheets:** use the *Export to Google Sheets* integration in the run's Integrations tab, or `=IMPORTDATA("https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=csv&view=flat&clean=1")` (a public dataset or a token-authenticated URL).
- **Make / Zapier / n8n:** use the official Apify app, trigger *"Actor run finished"*, then *"Get dataset items"* (`view=outreach`), and map `company`, `website`, `topProblem` and `coldOpenLine` into HubSpot, Pipedrive, Close, Instantly, lemlist or Apollo custom fields.
- **API:** `GET https://api.apify.com/v2/datasets/<DATASET_ID>/items?view=flat&format=csv`, or call the Actor synchronously with `run-sync-get-dataset-items`.
- **Schedules:** re-scan your prospect or client list monthly and alert on new critical findings (for example an SSL certificate about to expire).

Tip: put `{{coldOpenLine}}` as the first line of a cold email and `{{evidence}}` in a follow-up. Specific, verifiable observations get far more replies than generic "we do IT security" pitches.

### FAQ

**Is this legal and ethical?** The Actor uses only public, passive information that any browser or mail server sees: DNS records, one normal homepage request, the TLS certificate and public registry (RDAP/WHOIS) data. It does no port scanning, vulnerability probing, login attempts or exploitation. Use the results responsibly: present findings helpfully, follow anti-spam and privacy laws in your region (for example CAN-SPAM, GDPR, POPIA), and honour opt-outs.

**How accurate is "no DKIM"?** DKIM keys sit under selector names that can't be listed. The Actor checks 59 common selectors (Microsoft 365, Google, major ESPs). A provider with a custom selector can show as "not found", so this signal is scored *medium* and worded carefully.

**Why is a site marked slow?** The time is measured for the successful homepage request (including redirects) from Apify's cloud. It is flagged above 6 seconds, which is a real-world problem, not a lab metric.

**How is the opportunity score calculated?** Each signal has a severity weight (critical > high > medium > low), and the weights combine with diminishing returns into a 0–100 score. Parked domains are capped near 0, and domains with no mail and no working website are capped at 35 because they are probably inactive businesses.

**Does it find email addresses or phone numbers?** No. It scores companies you already have, or that you discover from a public list page. Pair it with your existing enrichment tool.

**How fast is it?** Roughly 1–2 seconds per company at 10 in parallel. 1,000 companies take a few minutes to tens of minutes, depending on how slow the sites are.

**Can I scan my own clients?** Yes. Many MSPs run it monthly against their client list as a lightweight external health check.

### Related Probelane Actors

- [Bulk DMARC, SPF & DKIM Checker](https://apify.com/probelane/email-domain-security-auditor): full email-authentication audit with an A–F grade and exact fixes
- [Bulk Website Tech Stack, SSL Expiry & Security Headers Checker](https://apify.com/probelane/website-tech-stack-health): 7,600+ technologies, uptime, SSL and headers
- [Bulk WHOIS & RDAP Domain Lookup](https://apify.com/probelane/bulk-domain-whois-rdap): registrar, creation and expiry dates, nameservers and availability

Questions or feature requests? Open an issue on the Actor's **Issues** tab. We usually reply within a day.

# Actor input Schema

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

One company per line: a domain, URL or email (acme.com, https://www.acme.com/contact, jane@acme.com). Optionally add labels separated by commas: domain, company name, niche, location — e.g. 'acme.co.za, Acme Attorneys, law firm, Durban'. Duplicates are removed automatically.

## `websitesText` (type: `string`):

Paste a long list, one company per line (same format as above), or a space-separated list of domains.

## `csvUrl` (type: `string`):

Public CSV link, e.g. a Google Sheet published as CSV (File → Share → Publish to web → CSV). Columns are detected by name: domain/website/url, company/name, niche/industry, location/city. Without a header the first column is used as the domain.

## `discoveryPageUrls` (type: `array`):

Public directory or 'members' pages you are allowed to use (association member lists, chamber of commerce pages, 'top 20 firms in X' articles). The Actor reads the page once and takes every outbound company website it links to (social networks, government/education and big platforms are skipped). Review the page's terms before using it.

## `maxDiscoveredPerPage` (type: `integer`):

Cap on websites taken from each discovery page.

## `niche` (type: `string`):

Added to every row that has no niche of its own (e.g. 'dental clinics'). Useful for CRM segmentation.

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

Added to every row that has no location of its own (e.g. 'Cape Town, ZA').

## `minOpportunityScore` (type: `integer`):

Hide weaker prospects. Hidden companies are NOT charged — you only pay for rows you receive.

## `checkDomainExpiry` (type: `boolean`):

Flags domains that are expired, in redemption or expire within 30 days.

## `detectTechnologies` (type: `boolean`):

Detects CMS, hosting, CDN and versions (WordPress, PHP, Drupal, Joomla, Magento, jQuery) using open-source fingerprints, and flags end-of-life versions.

## `maxItems` (type: `integer`):

Optional cap on companies processed (after de-duplication). Leave empty for all.

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

Companies checked in parallel.

## `timeoutSecs` (type: `integer`):

Per-request timeout for the homepage check.

## Actor input object example

```json
{
  "websites": [
    "bhadurban.co.za, BHA Chartered Accountants, accountants, Durban",
    "langacpa.com, Langa & Company CPAs, CPA, Boise ID",
    "khanattorneys.co.za, Khan Attorneys, law firm, Johannesburg",
    "dnsc.co.za, Durban North Smile Center, dental clinic, Durban",
    "strattoncpa.com, Stratton & Associates, CPA, Boise ID"
  ],
  "maxDiscoveredPerPage": 200,
  "minOpportunityScore": 0,
  "checkDomainExpiry": true,
  "detectTechnologies": true,
  "maxConcurrency": 10,
  "timeoutSecs": 15
}
```

# Actor output Schema

## `prospects` (type: `string`):

No description

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

No description

## `summary` (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": [
        "bhadurban.co.za, BHA Chartered Accountants, accountants, Durban",
        "langacpa.com, Langa & Company CPAs, CPA, Boise ID",
        "khanattorneys.co.za, Khan Attorneys, law firm, Johannesburg",
        "dnsc.co.za, Durban North Smile Center, dental clinic, Durban",
        "strattoncpa.com, Stratton & Associates, CPA, Boise ID"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("probelane/security-prospect-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": [
        "bhadurban.co.za, BHA Chartered Accountants, accountants, Durban",
        "langacpa.com, Langa & Company CPAs, CPA, Boise ID",
        "khanattorneys.co.za, Khan Attorneys, law firm, Johannesburg",
        "dnsc.co.za, Durban North Smile Center, dental clinic, Durban",
        "strattoncpa.com, Stratton & Associates, CPA, Boise ID",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("probelane/security-prospect-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": [
    "bhadurban.co.za, BHA Chartered Accountants, accountants, Durban",
    "langacpa.com, Langa & Company CPAs, CPA, Boise ID",
    "khanattorneys.co.za, Khan Attorneys, law firm, Johannesburg",
    "dnsc.co.za, Durban North Smile Center, dental clinic, Durban",
    "strattoncpa.com, Stratton & Associates, CPA, Boise ID"
  ]
}' |
apify call probelane/security-prospect-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,probelane/security-prospect-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/M1K5pUF253O7VF39K/builds/makAjqL6vRHJOgfs4/openapi.json
