# BE-Lead-Hunter (`wooden_turbojet/be-lead-hunter`) Actor

Experimental business-contact research: supplied-page extraction, reviewed dataset reuse, gated website collection and evidence-only qualification. No new discovery Actor starts, mailbox verification, AI calls or outreach.

- **URL**: https://apify.com/wooden_turbojet/be-lead-hunter.md
- **Developed by:** [Niks Api](https://apify.com/wooden_turbojet) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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

## BE-Lead-Hunter

An experimental business-contact research and evidence-review Actor. It helps
organize supplied business listings, extract contacts from saved website HTML,
and distinguish supported observations from checks that have not been performed.

This is a developing research tool, not an automated sales or outreach platform.
It does not start discovery Actors, verify mailboxes, assess buying intent, or
send messages. An extracted public email is not permission to contact someone.

### What it can do

| Run mode | Purpose and limits |
|---|---|
| `snapshots` | Review supplied listings and saved HTML without fetching websites. |
| `discovery_plan` | Produce an offline discovery plan; does not execute it. |
| `reuse_discovery` | Read a compatible completed Google Maps Scraper run when explicitly enabled and permitted; starts no new source run. |
| `crawl_simulation` | Exercise collection using supplied synthetic HTTP/DNS fixtures. |
| `crawl_websites` | Bounded public-website collection; requires both input opt-in and server authorization. Robots-policy limitations can cause collection holds. |
| `collect_discovery` | Website collection for a developer-reviewed source/profile, not arbitrary unreviewed source batches. |
| `qualify_saved_collection` | Checksum-pinned replay of a developer-reviewed saved collection. Not available for arbitrary new batches. |
| `save_reviews` | Separately authorized append-only review persistence. Not a generally configured hosted database service. |

For a first test, use `snapshots` with fictional supplied data. Leave all live,
source-read and persistence opt-ins off. Never put credentials in Actor input.

### Minimal fictional example

```json
{
  "runMode": "snapshots",
  "country": "United States",
  "state": "Texas",
  "city": "Demo City",
  "category": "real estate",
  "enableLiveRequests": false,
  "allowReadOnlyApify": false,
  "enableReviewPersistence": false,
  "discoveryItems": [
    {
      "placeId": "fictional-cedar-realty",
      "title": "Fictional Cedar Realty",
      "address": "100 Sample Street, Demo City, TX",
      "website": "https://cedar-realty.example/"
    }
  ],
  "websitePages": [
    {
      "url": "https://cedar-realty.example/",
      "statusCode": 200,
      "observedAt": "2026-10-20T00:00:00Z",
      "html": "<html><head><title>Fictional Cedar Realty</title></head><body><h1>Fictional sample</h1><p>This fictional business demonstrates saved-page extraction and research review. It is not a real contact or live website audit.</p><a href=\"mailto:hello@cedar-realty.example\">Contact</a></body></html>"
    }
  ]
}
```

The example supplies HTML as data; no request is made to the `.example` domain.

### Output

The dataset contains review records with identity, location, contact provenance,
evidence limitations and disabled sending. Some modes also separate deferred or
rejected records in key-value-store reports. Saved-collection qualification retains
all source records in its dataset, including holds and rejects.

`RUN_SUMMARY` describes the executed mode and counts. Saved-collection qualification
also writes `QUALIFICATION_REPORT`, including its input-integrity checks. Records
require human review; an evidence-readiness score is not lead quality, mailbox
deliverability, service need or purchase intent.

Fourteen service categories are represented in saved-collection qualification,
but most checks are not implemented. Current evidence checks are limited to
basic page title/description/heading and viewport signals. Missing evidence is
unknown, not proof that a business needs a service. This is not a comprehensive
SEO, accessibility, performance, advertising or social-media audit.

### Costs, access and responsible use

Apify compute, storage and transfer can incur usage charges, including on runs
that perform no new website scraping. Input budget declarations are not billing
caps; set a small Console/API run limit and inspect usage. Optional source tools
have their own pricing and terms; this Actor does not start them for you.

Use only data and websites you are authorized to process. Keep private inputs,
credentials and real customer/lead exports out of public examples and share links.
Sending, mailbox verification, AI analysis, n8n activation and production database
connectivity are not part of the validated saved-evidence qualification workflow.

### Validation status

The saved-evidence integration passed 488 cloud tests and reproduced the reviewed
ten-record pilot exactly in exported report, summary and dataset comparisons.
That pilot has partial website coverage and no outreach-qualified records.
Broader markets, new source profiles and production reliability require separate
validation. The tool remains experimental.

# Actor input Schema

## `runMode` (type: `string`):

Snapshot processing, offline plan/simulation, completed-run reuse, reviewed-source collection, pinned saved-evidence qualification or save-only review storage. No mode starts source Actors or sends email.

## `qualificationProfile` (type: `string`):

qualify_saved_collection only: pins the exact reviewed collection receipt and eight artifact checksums. No new source or website requests.

## `qualificationBundle` (type: `object`):

qualify_saved_collection only: receipt and eight original UTF-8 artifact texts, prepared by the local input builder. Never include credentials. Exact pinned hashes and 250 KB total bound are enforced in code.

## `collectionProfile` (type: `string`):

collect_discovery only: selects the three manually reviewed named-agent identities and confirmed HTTPS starting sites. Other records remain deferred; this is not automatic agent qualification.

## `enableReviewPersistence` (type: `boolean`):

Explicitly opt into save_reviews mode. Trusted server authorization and deployment secrets are also required; disabled by default.

## `reviewJob` (type: `object`):

save_reviews only: campaign, leads (1–10), sourceDigest, processorRevision, recordKind. Configure credentials only in trusted deployment secrets.

## `country` (type: `string`):

Target country for the supplied research records or discovery plan.

## `state` (type: `string`):

The current pilot is Nashville, Tennessee. Historical Texas fixtures remain supported; supply the state explicitly.

## `city` (type: `string`):

The selected real-data pilot city is Nashville, Tennessee, not Texas.

## `category` (type: `string`):

Business category used to filter supplied records and prepare discovery plans.

## `marketScope` (type: `string`):

Choose a specific city or an explicitly labeled state sample; this setting does not launch discovery.

## `businessSegment` (type: `string`):

The selected pilot targets individual agents. Search results still require review to distinguish agents from brokerages and teams.

## `discoveryLimit` (type: `integer`):

Maximum listings selected for the small discovery sample, up to ten.

## `sourceRunId` (type: `string`):

Existing completed Google Maps Actor run to inspect in reuse mode; this never starts a new source run.

## `sourceDatasetId` (type: `string`):

reuse_discovery or collect_discovery: read the dataset for a reviewed source manifest and verify its content hash. Grants READ only. Run status is Console-attested, not re-read through the API. collect_discovery requires this field.

## `allowReadOnlyApify` (type: `boolean`):

Opt into reading an existing completed run with trusted SDK credentials; disabled by default.

## `enableLiveRequests` (type: `boolean`):

Opt into bounded website collection only when the server separately permits it; disabled by default.

## `maxWebsites` (type: `integer`):

Upper bound on supplied websites attempted during authorized website collection.

## `maxHttpRequests` (type: `integer`):

Total HTTP attempt limit, including robots.txt checks and redirects.

## `maxResponseBytes` (type: `integer`):

Maximum response-body bytes accepted for one page.

## `maxTotalResponseBytes` (type: `integer`):

Combined response-body byte budget across collected pages.

## `minRequestIntervalSecs` (type: `number`):

Minimum delay in seconds between requests to the same origin.

## `maxCollectionElapsedSecs` (type: `number`):

Elapsed-time check threshold for collection, not a hard deadline for DNS or platform execution.

## `simulationObservedAt` (type: `string`):

Explicit observation timestamp for fixture-only simulated responses.

## `httpFixtures` (type: `array`):

Fictional response fixtures for offline crawl simulation; not evidence of live HTTP collection.

## `dnsRecords` (type: `object`):

Fictional DNS answers for offline simulation; never trusted as live DNS evidence.

## `pilotBudgetUsd` (type: `number`):

Declared total pilot budget in USD, at most five dollars; this does not enforce Apify billing.

## `pilotSpentUsd` (type: `number`):

User-declared prior pilot costs in USD, not verified against provider billing.

## `pendingCommitmentsUsd` (type: `number`):

Declared outstanding pilot commitments in USD for budget planning.

## `parentReserveUsd` (type: `number`):

Estimated USD reserve for this Actor and platform costs, not a provider-enforced spending limit.

## `discoveryBudgetUsd` (type: `number`):

Proposed USD allocation for a later approved discovery run; no discovery is launched by this field.

## `maxLeads` (type: `integer`):

Upper bound on selected business records processed into review output.

## `maxPagesPerWebsite` (type: `integer`):

Maximum supplied HTML snapshots processed for one business.

## `strictCityMatch` (type: `boolean`):

Reject records with known addresses outside the explicitly selected city.

## `requireWebsite` (type: `boolean`):

Exclude records without a reported website when enabled; disabled to retain no-website opportunities.

## `discoveryItems` (type: `array`):

Previously collected business records to normalize and review without starting discovery. The prefilled example is fictional, not a real lead.

## `websitePages` (type: `array`):

Supplied saved HTML pages with source and observation metadata; these are not proof of a live scrape by this Actor.

## Actor input object example

```json
{
  "runMode": "snapshots",
  "qualificationBundle": {},
  "enableReviewPersistence": false,
  "reviewJob": {},
  "country": "United States",
  "state": "Tennessee",
  "city": "Nashville",
  "category": "real estate",
  "marketScope": "city",
  "businessSegment": "individual_agents",
  "discoveryLimit": 10,
  "allowReadOnlyApify": false,
  "enableLiveRequests": false,
  "maxWebsites": 10,
  "maxHttpRequests": 40,
  "maxResponseBytes": 500000,
  "maxTotalResponseBytes": 3000000,
  "minRequestIntervalSecs": 1,
  "maxCollectionElapsedSecs": 120,
  "httpFixtures": [],
  "dnsRecords": {},
  "pilotBudgetUsd": 5,
  "pilotSpentUsd": 0,
  "pendingCommitmentsUsd": 0,
  "parentReserveUsd": 1,
  "discoveryBudgetUsd": 1,
  "maxLeads": 50,
  "maxPagesPerWebsite": 4,
  "strictCityMatch": true,
  "requireWebsite": false,
  "discoveryItems": [
    {
      "placeId": "fictional-public-healthcheck-v1",
      "title": "FICTIONAL DEMO - NOT A REAL LEAD",
      "city": "Nashville",
      "state": "Tennessee",
      "countryCode": "US",
      "address": "100 Fictional Sample Way, Nashville, TN",
      "website": "https://fictional-lead-hunter.example/"
    }
  ],
  "websitePages": []
}
```

# Actor output Schema

## `leads` (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 = {
    "runMode": "snapshots",
    "state": "Tennessee",
    "city": "Nashville",
    "discoveryItems": [
        {
            "placeId": "fictional-public-healthcheck-v1",
            "title": "FICTIONAL DEMO - NOT A REAL LEAD",
            "city": "Nashville",
            "state": "Tennessee",
            "countryCode": "US",
            "address": "100 Fictional Sample Way, Nashville, TN",
            "website": "https://fictional-lead-hunter.example/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("wooden_turbojet/be-lead-hunter").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 = {
    "runMode": "snapshots",
    "state": "Tennessee",
    "city": "Nashville",
    "discoveryItems": [{
            "placeId": "fictional-public-healthcheck-v1",
            "title": "FICTIONAL DEMO - NOT A REAL LEAD",
            "city": "Nashville",
            "state": "Tennessee",
            "countryCode": "US",
            "address": "100 Fictional Sample Way, Nashville, TN",
            "website": "https://fictional-lead-hunter.example/",
        }],
}

# Run the Actor and wait for it to finish
run = client.actor("wooden_turbojet/be-lead-hunter").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 '{
  "runMode": "snapshots",
  "state": "Tennessee",
  "city": "Nashville",
  "discoveryItems": [
    {
      "placeId": "fictional-public-healthcheck-v1",
      "title": "FICTIONAL DEMO - NOT A REAL LEAD",
      "city": "Nashville",
      "state": "Tennessee",
      "countryCode": "US",
      "address": "100 Fictional Sample Way, Nashville, TN",
      "website": "https://fictional-lead-hunter.example/"
    }
  ]
}' |
apify call wooden_turbojet/be-lead-hunter --silent --output-dataset

```

## MCP server setup

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

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/k0Tgf9tQlorrFZpNB/builds/TaXKG9aj9xqNh43fC/openapi.json
