# Lead List Qualifier — Domain Hotness Scorer (`zinin/lead-list-qualifier`) Actor

Score a list of company domains for outbound-readiness. Combines tech stack, active hiring, funding mentions and contact reachability from our own live lead-gen Actors into one transparent hotness score per domain, so you know which leads on your list to call first.

- **URL**: https://apify.com/zinin/lead-list-qualifier.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Lead generation, Automation
- **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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Lead List Qualifier — Domain Hotness Scorer

Score a list of company domains for outbound-readiness. This Actor calls four of our
own live lead-gen Actors in parallel for every domain — tech stack, active hiring,
funding mentions and contact reachability — and combines what they find into one
transparent hotness score, so you know which leads on your list to call first.

### What you get

- One hotness score (0-96) per domain, with a full text breakdown of exactly which
  signals contributed and how many points each one added — never a black-box number.
- Signals combined: contact info found on the site, hiring momentum + role keyword
  matches, ecommerce/sales-tool detection, and SEC funding-filing mentions.
- Honest about uncertainty: a guessed hiring-board token is checked against the
  board's public owner signal when one is available. A confirmed mismatch is shown
  for diagnosis but contributes no score; unavailable evidence stays explicitly
  unverified rather than being silently promoted to a match.
- Domains with zero signal from all four sources come back free (not charged) — you
  only pay when we actually found something to report.
- Runs on Apify: call it from the API, export to JSON/CSV/Excel or push straight into
  your CRM/outreach pipeline.

### How to run it

1. Click **Try for free** — no card needed on the free plan.
2. Paste up to 25 domains into **Domains to qualify**.
3. Optionally set **Role keywords** (e.g. `sales`, `marketing`) to flag domains
   currently hiring for those roles.
4. Hit **Start** and pull the scored list from the dataset.

### Pricing

Pay-per-event: **$0.005 per run start + $0.01 per domain scored**.
A domain with zero signal from all four sources, or one we couldn't check at all
(all four sources unreachable), is returned but never charged. 10 domains scored cost about $0.11 (the one-time start fee plus 10 billed rows).

### Input

| Field | Required | What it does |
|---|---|---|
| `domains` | yes | Up to 25 company domains to score, e.g. `"stripe.com"`. |
| `role_keywords` | no | Words to match against open job titles (default: `["sales","marketing"]`). |
| `company_name_overrides` | no | `{"domain":"correct-slug"}` — override our guessed ATS token/company name for specific domains (see limitation below). |

```json
{
    "domains": ["stripe.com", "shopify.com"],
    "role_keywords": ["sales", "marketing"]
}
```

### ⚠️ Important limitation: guessed company identity for 2 of the 4 signals

Two of the four signals (contact info, tech stack) work directly off the domain you
give us — no ambiguity there. The other two (hiring activity, funding mentions) need a
company NAME or ATS token, not a domain, so by default we guess one from the domain
itself (`stripe.com` → `stripe`). **This guess can attach an unrelated company's data to
your domain.** Verified live: qualifying `example.com` (which has no real hiring-board
presence at all) returned "strong hiring, 21 open roles" — because some UNRELATED
company happens to sit under the token `example` on one of the three job-board
providers we check. Similarly, querying "stripe" against public funding filings
surfaces real SEC filings that merely contain the word "stripe" in an unrelated fund's
name (e.g. "Rockefeller Stripe LP"), not Stripe Inc. itself.

Every row tells you the input path via `matchBasis` (`"guessed-domain"` or
`"buyer-override"`) and the hiring ownership result via `attributionConfirmed`
(`true`, `false`, or `null`) plus `attributionEvidence`. A `false` hiring match is
excluded from scoring. `null` means the public board did not expose enough evidence,
not that ownership was confirmed. If you know the real ATS token or legal name
for a domain, pass it via `company_name_overrides` to remove the guesswork for that
domain — though even then, a name match on public filings is never proof of identity
(see `matchedFundingFilings` — always check it yourself before treating funding
mentions as fact).

### Output

Full signal found (real output, live run 30.07.2026):

```json
{
    "domain": "stripe.com",
    "found": true,
    "hotnessScore": 78,
    "scoreBreakdown": [
        "contact info found on the site (+15)",
        "aggressive hiring (+38)",
        "113 open role(s) matching your keywords (+15)",
        "11 SEC filing(s) mention \"stripe\" — UNVERIFIED (+10)"
    ],
    "reachable": true,
    "emailsFound": 1,
    "phonesFound": 3,
    "hiringMomentum": "aggressive hiring",
    "openRolesCount": 540,
    "matchedRolesCount": 113,
    "techStackCount": 2,
    "ecommerce": null,
    "cms": null,
    "fundingMentionsCount": 11,
    "fundingConfidence": "low — name-substring match on public SEC filings against a guessed slug, NOT a verified link to this domain; see matchedFundingFilings",
    "matchedFundingFilings": [
        { "company": "Pantera Opportunities Fund LP Stripe", "filedAt": "2026-07-24", "url": "https://www.sec.gov/Archives/edgar/data/2147228/000090266426003236/0000902664-26-003236-index.htm" }
    ],
    "companySlugUsed": "stripe",
    "identityConfidence": "guessed",
    "matchBasis": "guessed-domain",
    "attributionConfirmed": true,
    "attributionEvidence": { "method": "greenhouse-board-name", "requestedDomain": "stripe.com", "signal": "Stripe", "detail": "greenhouse's board name matches stripe.com." },
    "techStackChecked": true,
    "contactsChecked": true,
    "hiringChecked": true,
    "fundingChecked": true,
    "partial": false,
    "partialReason": null,
    "error": "",
    "summary": "stripe.com — hotness 78: contact info found on the site (+15); aggressive hiring (+38); 113 open role(s) matching your keywords (+15); 11 SEC filing(s) mention \"stripe\" — UNVERIFIED (+10).",
    "checkedAt": "2026-07-30T10:36:08.928Z"
}
```

No signal found (real output, live run 30.07.2026 — free, not charged):

```json
{
    "domain": "zzqfakenonexistentdomain999999.example",
    "found": false,
    "hotnessScore": 0,
    "scoreBreakdown": [],
    "error": "",
    "summary": "zzqfakenonexistentdomain999999.example — no signal detected from any of the four sources (checked: techStack, contacts, hiring, funding).",
    "checkedAt": "2026-07-30T10:39:46.032Z"
}
```

| Field | Meaning |
|---|---|
| `found` | `true` only when `hotnessScore > 0` — the billable outcome. |
| `hotnessScore` | 0-96 heuristic index, sum of the components in `scoreBreakdown`. Not a percentage or a guarantee. |
| `reachable`, `emailsFound`, `phonesFound` | From website-contact-extractor. |
| `hiringMomentum`, `openRolesCount`, `matchedRolesCount` | From company-hiring-radar, keyed on `companySlugUsed`. |
| `techStackCount`, `ecommerce`, `cms` | From tech-stack-detector. |
| `fundingMentionsCount`, `fundingConfidence`, `matchedFundingFilings` | From funding-round-tracker — always check `matchedFundingFilings` yourself, see the limitation above. |
| `identityConfidence` | `"guessed"` or `"override"` — see the limitation above. |
| `matchBasis`, `attributionConfirmed`, `attributionEvidence` | How the ATS token was chosen and whether the board's public owner signal matched the requested domain. `null` is unknown, not confirmed. |
| `techStackChecked`/`contactsChecked`/`hiringChecked`/`fundingChecked` | Whether that source's own call succeeded this run (independent of whether it found anything). |
| `partial` / `partialReason` | `true` when some (not all) of the four sources failed to respond — the score is still computed from whatever did answer. |
| `error` | Empty string when the check completed (including "nothing found"); non-empty only when ALL FOUR sources failed to respond. |

### Other tools we built

#### Related tools

Related tools for adjacent workflows in B2B lead generation and data enrichment.

| Actor | What it does |
|---|---|
| [B2B Lead Enricher](https://apify.com/zinin/b2b-lead-enricher) | Pair it in the B2B lead generation and data enrichment workflow: Turn a list of company websites into sales-qualified lead cards: detected tech stack, a rough revenue... |
| [Company Profile Lookup](https://apify.com/zinin/company-lookup) | Pair it in the B2B lead generation and data enrichment workflow: Turn a domain or company name into one unified company card: website tech stack (CMS, ecommerce, key tech)... |
| [Intent Signal Aggregator](https://apify.com/zinin/intent-signal-aggregator) | Pair it in the B2B lead generation and data enrichment workflow: Is this company in-market right now? Combines public hiring activity (Greenhouse, Lever, Ashby) and recent... |
| [Counterparty Risk Rollup — Sanctions, Courts, Registry, Hiring](https://apify.com/zinin/counterparty-risk-rollup) | Pair it in the B2B lead generation and data enrichment workflow: One call, one row per counterparty: sanctions screening (OFAC + EU), legal-entity registry (GLEIF),... |
| [Company Hiring Radar](https://apify.com/zinin/company-hiring-radar) | Pair it in the B2B lead generation and data enrichment workflow: Pull every open role a company is hiring for from its public job board (Greenhouse, Lever, Ashby) and turn... |

### FAQ / Limitations

**Why is my score lower than I expected?** Check `partial` first — if some sources
didn't respond this run, the score only reflects what did. Then check
`identityConfidence` — a `"guessed"` slug for a distinctive company name usually still
works; a common word as a domain label (like "example") is where guesses go wrong.

**What this is NOT.** This is not a verified company database and does not confirm
that a domain and a matched hiring board or funding filing are the same legal entity —
see the limitation section above. It is a prioritization heuristic, not proof.

Found a bug or need a custom scoring weight? Issues on the Actor's page.

# Actor input Schema

## `domains` (type: `array`):

Company domains to score (e.g. "stripe.com"). Each domain fires 4 parallel checks (tech stack, hiring, funding mentions, contact info), so this is capped at 25 per run.

## `role_keywords` (type: `array`):

Highlight domains currently hiring for roles matching these words (passed to our company-hiring-radar Actor, e.g. "sales", "marketing"). Leave empty to skip role matching.

## `company_name_overrides` (type: `object`):

By default this Actor guesses each domain's ATS token / company name from the domain itself (e.g. "stripe.com" -> "stripe") for the hiring and funding checks — this is a best-effort heuristic, not a verified identity, and can be wrong. Use this field to override the guess for specific domains: {"my-startup.io": "mystartupinc"}.

## Actor input object example

```json
{
  "domains": [
    "stripe.com",
    "shopify.com"
  ],
  "role_keywords": [
    "sales",
    "marketing"
  ],
  "company_name_overrides": {}
}
```

# 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 = {
    "domains": [
        "stripe.com",
        "shopify.com"
    ],
    "role_keywords": [
        "sales",
        "marketing"
    ],
    "company_name_overrides": {}
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/lead-list-qualifier").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 = {
    "domains": [
        "stripe.com",
        "shopify.com",
    ],
    "role_keywords": [
        "sales",
        "marketing",
    ],
    "company_name_overrides": {},
}

# Run the Actor and wait for it to finish
run = client.actor("zinin/lead-list-qualifier").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 '{
  "domains": [
    "stripe.com",
    "shopify.com"
  ],
  "role_keywords": [
    "sales",
    "marketing"
  ],
  "company_name_overrides": {}
}' |
apify call zinin/lead-list-qualifier --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=zinin/lead-list-qualifier",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/uVuqSlqflIUUfKRKA/builds/TmAlxYZFTzentPuKc/openapi.json
