# B2B Lead Cleaner — Bulk Email Verification & Data Quality (`kamerozkan/b2b-lead-cleaner`) Actor

Bulk email verification and lead list cleaning for any Apify dataset. Verify business emails with MX and deliverability checks, remove duplicates, catch role and disposable addresses, and flag off-target contacts with an explained ACCEPT, REVIEW or REJECT decision on every row.

- **URL**: https://apify.com/kamerozkan/b2b-lead-cleaner.md
- **Developed by:** [Kamer Ozkan](https://apify.com/kamerozkan) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 lead auditeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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.

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

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

## B2B Lead Cleaner — Bulk Email Verification & Data Quality

**Verify business emails in bulk and stop bad leads before they reach your CRM.**

Every row gets syntax, MX, provider, role-inbox, disposable, and company-domain email checks, plus duplicate detection and ICP targeting rules.

This Actor turns raw Apify lead datasets into explained decisions before you spend outreach credits or SDR time. Give it a dataset ID and receive one decision for every row:

- `ACCEPT`: usable under the configured rules
- `REVIEW`: evidence is incomplete or uncertain
- `REJECT`: a deterministic quality or targeting rule failed

It works with output from Google Maps, company databases, people search tools, contact scrapers, custom Actors, and uploaded JSON rows.

**From $2 per 1,000 audited leads. No start fee.**

### What you get

| Result | Why it matters |
| --- | --- |
| One explained decision per lead | Route usable leads automatically and keep uncertain rows out of live campaigns |
| Duplicate and historical duplicate detection | Stop paying twice for the same contact |
| Email syntax, MX, provider, role, and company-domain checks | Catch risky contact data before it reaches outreach |
| Country, city, industry, title, and account targeting | Reject leads that do not match the audience you paid for |
| Stable JSON fields and reason codes | Connect the result to Make, Zapier, n8n, webhooks, CRMs, or AI agents |
| Source economics report | See the real source cost per accepted lead |

### What problem does it solve?

A successful scraper run does not mean every returned lead is useful.

Raw lead datasets commonly contain:

- duplicate contacts
- invalid email syntax
- domains with no mail server
- personal and disposable inboxes
- role inboxes such as `info@` and `support@`
- email and company domain mismatches
- contacts outside the requested country, city, industry, title, or account list
- stale records
- inconsistent field names across different lead sources

The Firewall checks these problems in one step and explains every decision with machine-readable reason codes.

### Who it is for

- lead generation agencies checking scraped lists before delivery
- sales teams protecting CRM and cold email workflows
- automation builders connecting multiple Apify Actors
- data buyers comparing the usable yield of different lead sources
- AI agents that need a deterministic gate before taking outreach actions

### Quick start

1. Run any lead scraper.
2. Select its result under **Source Apify dataset**.
3. Keep **Balanced** quality mode.
4. Click **Start**.

The Actor automatically detects common fields such as name, job title, email, phone, LinkedIn URL, company, website, industry, country, city, and timestamp.

No API token or manual field mapping is normally required. The Actor receives read-only access to the dataset you select and cannot access other datasets in your account.

#### Minimal input

```json
{
  "datasetId": "YOUR_DATASET_ID",
  "qualityMode": "BALANCED",
  "maxItems": 1000
}
````

You can also paste rows directly:

```json
{
  "rows": [
    {
      "full_name": "Ada Rivera",
      "job_title": "VP Marketing",
      "email": "ada@stripe.com",
      "country": "United States",
      "company_name": "Stripe",
      "company_domain": "stripe.com",
      "industry": "Software"
    }
  ]
}
```

#### Optional targeting contract

Use targeting rules when the source promised a specific audience:

```json
{
  "datasetId": "YOUR_DATASET_ID",
  "qualityMode": "BALANCED",
  "targeting": {
    "countries": ["United States"],
    "titleKeywords": ["CMO", "VP Marketing", "Head of Growth"],
    "industries": ["Software", "SaaS"],
    "excludedTitleKeywords": ["Assistant", "Intern"]
  }
}
```

A missing or mismatched targeting field is rejected with a specific reason. The Actor never silently treats missing evidence as a match.

#### Real example output

This row comes from a successful cloud run of the current build candidate:

```json
{
  "sourceIndex": 1,
  "decision": "REJECT",
  "qualityScore": 60,
  "primaryReason": "Email uses a personal inbox provider.",
  "reasonCodes": [
    "EMAIL_PERSONAL"
  ],
  "fullName": "Personal Inbox",
  "title": "CMO",
  "email": "buyer@gmail.com",
  "companyName": "Acme",
  "companyDomain": "acme.com",
  "emailStatus": "PERSONAL",
  "mxStatus": "VALID",
  "duplicate": false,
  "historicalDuplicate": false,
  "reasons": [
    {
      "code": "EMAIL_PERSONAL",
      "severity": "REJECT",
      "penalty": 40,
      "message": "Email uses a personal inbox provider.",
      "evidence": {
        "domain": "gmail.com"
      }
    }
  ]
}
```

The original source row is preserved in `original`, so downstream systems do not lose fields that are specific to the source Actor.

`qualityScore` measures how completely a row passes the configured checks. It is not an email deliverability percentage and does not claim that an individual mailbox exists.

### Quality modes

#### Balanced

Recommended for most B2B workflows.

- requires an email by default
- validates syntax and MX records
- rejects personal and disposable inboxes
- rejects confirmed email and company domain mismatches
- warns about role inboxes
- does not require a website request

#### Strict

Designed for higher-value outreach where false positives are expensive.

- includes all Balanced checks
- rejects role inboxes
- checks company website reachability
- checks freshness up to 365 days
- uses higher score thresholds

#### Custom

Use the advanced section to choose your own rules and score thresholds.

### Historical duplicate protection

Set a `monitorName` when running the Actor on a schedule:

```json
{
  "datasetId": "YOUR_DATASET_ID",
  "monitorName": "us-saas-outbound"
}
```

Later runs with the same key reject previously processed leads as `HISTORICAL_DUPLICATE`.

The history store contains SHA-256 hashes of deduplication keys. It does not store raw email addresses in the history record.

### Source economics

If you enter the original batch cost, the quality report calculates the real cost per accepted lead:

```json
{
  "rules": {
    "sourceCostUsd": 50
  }
}
```

A cheap list can become expensive when most rows are duplicates or unusable. This metric exposes that cost.

### Use in automations

Each row includes stable fields for Make, Zapier, n8n, webhooks, and AI agents:

- `decision`
- `qualityScore`
- `reasonCodes`
- normalized contact and company fields
- validation evidence
- the untouched original row

Route only `decision = ACCEPT` to your CRM or outreach system. Send `REVIEW` to a manual queue and archive `REJECT`.

### More than an email validator

An email validator normally checks one address at a time. This Actor evaluates the whole lead record and the dataset around it.

It combines email and domain evidence with duplicate detection, ICP targeting, freshness checks, historical suppression, source economics, and automation-ready decisions. It does not claim SMTP mailbox verification.

### What the Actor does not claim

MX records prove that a domain is configured to receive email. They do not prove that a specific mailbox exists.

Public web evidence cannot guarantee that a person still works at a company, will read a message, or will reply.

The Actor reports uncertainty instead of inventing certainty:

- temporary DNS errors go to `REVIEW`
- uncertain website results go to `REVIEW`
- missing freshness evidence goes to `REVIEW` when freshness rules are enabled

### Security

- private, local, and reserved network targets are never requested
- no lead values are written to logs
- manual field paths block prototype pollution segments
- historical deduplication stores hashes instead of raw contact data
- the source dataset is read-only

### Pricing

The Actor costs **$2 per 1,000 audited leads**. A `lead-audited` event represents one delivered `ACCEPT`, `REVIEW`, or `REJECT` quality decision.

There is no start fee. Rows blocked by the Apify run budget are not delivered or charged.

### Responsible use

Process only data you are authorized to use. Follow applicable privacy, marketing, and anti-spam laws, including GDPR, CAN-SPAM, and local equivalents. A technical quality decision does not create a lawful basis for outreach.
N rows.

**From $2 per 1,000 audited leads. No start fee.**

### What you get

| Result | Why it matters |
| --- | --- |
| One explained decision per lead | Route usable leads automatically and keep uncertain rows out of live campaigns |
| Duplicate and historical duplicate detection | Stop paying twice for the same contact |
| Email syntax, MX, provider, role, and company-domain checks | Catch risky contact data before it reaches outreach |
| Country, city, industry, title, and account targeting | Reject leads that do not match the audience you paid for |
| Stable JSON fields and reason codes | Connect the result to Make, Zapier, n8n, webhooks, CRMs, or AI agents |
| Source economics report | See the real source cost per accepted lead |

### What problem does it solve?

A successful scraper run does not mean every returned lead is useful.

Raw lead datasets commonly contain:

- duplicate contacts
- invalid email syntax
- domains with no mail server
- personal and disposable inboxes
- role inboxes such as `info@` and `support@`
- email and company domain mismatches
- contacts outside the requested country, city, industry, title, or account list
- stale records
- inconsistent field names across different lead sources

The Firewall checks these problems in one step and explains every decision with machine-readable reason codes.

### Who it is for

- lead generation agencies checking scraped lists before delivery
- sales teams protecting CRM and cold email workflows
- automation builders connecting multiple Apify Actors
- data buyers comparing the usable yield of different lead sources
- AI agents that need a deterministic gate before taking outreach actions

### Quick start

1. Run any lead scraper.
2. Select its result under **Source Apify dataset**.
3. Keep **Balanced** quality mode.
4. Click **Start**.

The Actor automatically detects common fields such as name, job title, email, phone, LinkedIn URL, company, website, industry, country, city, and timestamp.

No API token or manual field mapping is normally required. The Actor receives read-only access to the dataset you select and cannot access other datasets in your account.

#### Minimal input

```json
{
  "datasetId": "YOUR_DATASET_ID",
  "qualityMode": "BALANCED",
  "maxItems": 1000
}
```

You can also paste rows directly:

```json
{
  "rows": [
    {
      "full_name": "Ada Rivera",
      "job_title": "VP Marketing",
      "email": "ada@stripe.com",
      "country": "United States",
      "company_name": "Stripe",
      "company_domain": "stripe.com",
      "industry": "Software"
    }
  ]
}
```

#### Optional targeting contract

Use targeting rules when the source promised a specific audience:

```json
{
  "datasetId": "YOUR_DATASET_ID",
  "qualityMode": "BALANCED",
  "targeting": {
    "countries": ["United States"],
    "titleKeywords": ["CMO", "VP Marketing", "Head of Growth"],
    "industries": ["Software", "SaaS"],
    "excludedTitleKeywords": ["Assistant", "Intern"]
  }
}
```

A missing or mismatched targeting field is rejected with a specific reason. The Actor never silently treats missing evidence as a match.

#### Real example output

This row comes from a successful cloud run of the current build candidate:

```json
{
  "sourceIndex": 1,
  "decision": "REJECT",
  "qualityScore": 60,
  "primaryReason": "Email uses a personal inbox provider.",
  "reasonCodes": [
    "EMAIL_PERSONAL"
  ],
  "fullName": "Personal Inbox",
  "title": "CMO",
  "email": "buyer@gmail.com",
  "companyName": "Acme",
  "companyDomain": "acme.com",
  "emailStatus": "PERSONAL",
  "mxStatus": "VALID",
  "duplicate": false,
  "historicalDuplicate": false,
  "reasons": [
    {
      "code": "EMAIL_PERSONAL",
      "severity": "REJECT",
      "penalty": 40,
      "message": "Email uses a personal inbox provider.",
      "evidence": {
        "domain": "gmail.com"
      }
    }
  ]
}
```

The original source row is preserved in `original`, so downstream systems do not lose fields that are specific to the source Actor.

`qualityScore` measures how completely a row passes the configured checks. It is not an email deliverability percentage and does not claim that an individual mailbox exists.

### Quality modes

#### Balanced

Recommended for most B2B workflows.

- requires an email by default
- validates syntax and MX records
- rejects personal and disposable inboxes
- rejects confirmed email and company domain mismatches
- warns about role inboxes
- does not require a website request

#### Strict

Designed for higher-value outreach where false positives are expensive.

- includes all Balanced checks
- rejects role inboxes
- checks company website reachability
- checks freshness up to 365 days
- uses higher score thresholds

#### Custom

Use the advanced section to choose your own rules and score thresholds.

### Historical duplicate protection

Set a `monitorName` when running the Actor on a schedule:

```json
{
  "datasetId": "YOUR_DATASET_ID",
  "monitorName": "us-saas-outbound"
}
```

Later runs with the same key reject previously processed leads as `HISTORICAL_DUPLICATE`.

The history store contains SHA-256 hashes of deduplication keys. It does not store raw email addresses in the history record.

### Source economics

If you enter the original batch cost, the quality report calculates the real cost per accepted lead:

```json
{
  "rules": {
    "sourceCostUsd": 50
  }
}
```

A cheap list can become expensive when most rows are duplicates or unusable. This metric exposes that cost.

### Use in automations

Each row includes stable fields for Make, Zapier, n8n, webhooks, and AI agents:

- `decision`
- `qualityScore`
- `reasonCodes`
- normalized contact and company fields
- validation evidence
- the untouched original row

Route only `decision = ACCEPT` to your CRM or outreach system. Send `REVIEW` to a manual queue and archive `REJECT`.

### More than an email validator

An email validator normally checks one address at a time. This Actor evaluates the whole lead record and the dataset around it.

It combines email and domain evidence with duplicate detection, ICP targeting, freshness checks, historical suppression, source economics, and automation-ready decisions. It does not claim SMTP mailbox verification.

### What the Actor does not claim

MX records prove that a domain is configured to receive email. They do not prove that a specific mailbox exists.

Public web evidence cannot guarantee that a person still works at a company, will read a message, or will reply.

The Actor reports uncertainty instead of inventing certainty:

- temporary DNS errors go to `REVIEW`
- uncertain website results go to `REVIEW`
- missing freshness evidence goes to `REVIEW` when freshness rules are enabled

### Security

- private, local, and reserved network targets are never requested
- no lead values are written to logs
- manual field paths block prototype pollution segments
- historical deduplication stores hashes instead of raw contact data
- the source dataset is read-only

### Pricing

The Actor costs **$2 per 1,000 audited leads**. A `lead-audited` event represents one delivered `ACCEPT`, `REVIEW`, or `REJECT` quality decision.

There is no start fee. Rows blocked by the Apify run budget are not delivered or charged.

### Responsible use

Process only data you are authorized to use. Follow applicable privacy, marketing, and anti-spam laws, including GDPR, CAN-SPAM, and local equivalents. A technical quality decision does not create a lawful basis for outreach.

# Actor input Schema

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

Select the dataset produced by any lead scraper. The Actor receives read-only access to this dataset and cannot access other account data. Leave empty when using pasted rows.

## `rows` (type: `array`):

Useful for a quick test. When a source dataset is selected above, that dataset automatically takes priority over these example rows.

## `qualityMode` (type: `string`):

Balanced is recommended. Strict requires more company evidence. Custom uses the advanced rule overrides below.

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

Start with 100 to inspect the decisions, then increase the limit.

## `targeting` (type: `object`):

When values are supplied, non-matching leads are rejected with an exact reason.

## `rules` (type: `object`):

Defaults come from the selected quality mode. Set only the values you need to change.

## `fieldMap` (type: `object`):

Usually unnecessary. Override auto-detection with dot paths such as contact.email or company.website.

## `monitorName` (type: `string`):

Optional. Reuse the same name on scheduled runs to reject leads already seen in earlier runs.

## `historyKey` (type: `string`):

Deprecated compatibility field for existing saved tasks. New integrations should use monitorName.

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

Controls parallel MX and optional website checks.

## Actor input object example

```json
{
  "rows": [
    {
      "full_name": "Ada Rivera",
      "job_title": "VP Marketing",
      "email": "ada@stripe.com",
      "country": "United States",
      "company_name": "Stripe",
      "company_domain": "stripe.com",
      "industry": "Software"
    },
    {
      "full_name": "Duplicate Ada",
      "job_title": "VP Marketing",
      "email": "ada@stripe.com",
      "country": "United States",
      "company_name": "Stripe",
      "company_domain": "stripe.com",
      "industry": "Software"
    },
    {
      "full_name": "Personal Inbox",
      "job_title": "Marketing Manager",
      "email": "someone@gmail.com",
      "country": "United States",
      "company_name": "Example Co",
      "company_domain": "example.com",
      "industry": "Software"
    }
  ],
  "qualityMode": "BALANCED",
  "maxItems": 1000
}
```

# Actor output Schema

## `decisions` (type: `string`):

Audited lead rows with normalized fields, quality scores, and machine-readable reason codes.

## `qualityReport` (type: `string`):

Run summary, detected field mapping, rejection reasons, source economics, and billing evidence.

# 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 = {
    "rows": [
        {
            "full_name": "Ada Rivera",
            "job_title": "VP Marketing",
            "email": "ada@stripe.com",
            "country": "United States",
            "company_name": "Stripe",
            "company_domain": "stripe.com",
            "industry": "Software"
        },
        {
            "full_name": "Duplicate Ada",
            "job_title": "VP Marketing",
            "email": "ada@stripe.com",
            "country": "United States",
            "company_name": "Stripe",
            "company_domain": "stripe.com",
            "industry": "Software"
        },
        {
            "full_name": "Personal Inbox",
            "job_title": "Marketing Manager",
            "email": "someone@gmail.com",
            "country": "United States",
            "company_name": "Example Co",
            "company_domain": "example.com",
            "industry": "Software"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kamerozkan/b2b-lead-cleaner").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 = { "rows": [
        {
            "full_name": "Ada Rivera",
            "job_title": "VP Marketing",
            "email": "ada@stripe.com",
            "country": "United States",
            "company_name": "Stripe",
            "company_domain": "stripe.com",
            "industry": "Software",
        },
        {
            "full_name": "Duplicate Ada",
            "job_title": "VP Marketing",
            "email": "ada@stripe.com",
            "country": "United States",
            "company_name": "Stripe",
            "company_domain": "stripe.com",
            "industry": "Software",
        },
        {
            "full_name": "Personal Inbox",
            "job_title": "Marketing Manager",
            "email": "someone@gmail.com",
            "country": "United States",
            "company_name": "Example Co",
            "company_domain": "example.com",
            "industry": "Software",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("kamerozkan/b2b-lead-cleaner").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 '{
  "rows": [
    {
      "full_name": "Ada Rivera",
      "job_title": "VP Marketing",
      "email": "ada@stripe.com",
      "country": "United States",
      "company_name": "Stripe",
      "company_domain": "stripe.com",
      "industry": "Software"
    },
    {
      "full_name": "Duplicate Ada",
      "job_title": "VP Marketing",
      "email": "ada@stripe.com",
      "country": "United States",
      "company_name": "Stripe",
      "company_domain": "stripe.com",
      "industry": "Software"
    },
    {
      "full_name": "Personal Inbox",
      "job_title": "Marketing Manager",
      "email": "someone@gmail.com",
      "country": "United States",
      "company_name": "Example Co",
      "company_domain": "example.com",
      "industry": "Software"
    }
  ]
}' |
apify call kamerozkan/b2b-lead-cleaner --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "B2B Lead Cleaner — Bulk Email Verification & Data Quality",
        "description": "Bulk email verification and lead list cleaning for any Apify dataset. Verify business emails with MX and deliverability checks, remove duplicates, catch role and disposable addresses, and flag off-target contacts with an explained ACCEPT, REVIEW or REJECT decision on every row.",
        "version": "0.0",
        "x-build-id": "IUx0Q5QL4boaDFOkr"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/kamerozkan~b2b-lead-cleaner/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-kamerozkan-b2b-lead-cleaner",
                "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/kamerozkan~b2b-lead-cleaner/runs": {
            "post": {
                "operationId": "runs-sync-kamerozkan-b2b-lead-cleaner",
                "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/kamerozkan~b2b-lead-cleaner/run-sync": {
            "post": {
                "operationId": "run-sync-kamerozkan-b2b-lead-cleaner",
                "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",
                "properties": {
                    "datasetId": {
                        "title": "Source Apify dataset",
                        "type": "string",
                        "description": "Select the dataset produced by any lead scraper. The Actor receives read-only access to this dataset and cannot access other account data. Leave empty when using pasted rows."
                    },
                    "rows": {
                        "title": "Or paste lead rows",
                        "maxItems": 5000,
                        "type": "array",
                        "description": "Useful for a quick test. When a source dataset is selected above, that dataset automatically takes priority over these example rows.",
                        "items": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "qualityMode": {
                        "title": "Quality mode",
                        "enum": [
                            "BALANCED",
                            "STRICT",
                            "CUSTOM"
                        ],
                        "type": "string",
                        "description": "Balanced is recommended. Strict requires more company evidence. Custom uses the advanced rule overrides below.",
                        "default": "BALANCED"
                    },
                    "maxItems": {
                        "title": "Maximum leads to audit",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Start with 100 to inspect the decisions, then increase the limit.",
                        "default": 1000
                    },
                    "targeting": {
                        "title": "Optional targeting contract",
                        "type": "object",
                        "description": "When values are supplied, non-matching leads are rejected with an exact reason.",
                        "properties": {
                            "countries": {
                                "title": "Accepted countries",
                                "type": "array",
                                "description": "Examples: United States, Germany, United Kingdom.",
                                "editor": "stringList",
                                "uniqueItems": true,
                                "maxItems": 50,
                                "items": {
                                    "type": "string"
                                }
                            },
                            "cities": {
                                "title": "Accepted cities",
                                "type": "array",
                                "description": "Optional city targeting.",
                                "editor": "stringList",
                                "uniqueItems": true,
                                "maxItems": 100,
                                "items": {
                                    "type": "string"
                                }
                            },
                            "titleKeywords": {
                                "title": "Accepted job title keywords",
                                "type": "array",
                                "description": "A lead passes when its title contains at least one value, for example CMO or Head of Growth.",
                                "editor": "stringList",
                                "uniqueItems": true,
                                "maxItems": 100,
                                "items": {
                                    "type": "string"
                                }
                            },
                            "excludedTitleKeywords": {
                                "title": "Excluded job title keywords",
                                "type": "array",
                                "description": "Reject titles containing any of these values.",
                                "editor": "stringList",
                                "uniqueItems": true,
                                "maxItems": 100,
                                "items": {
                                    "type": "string"
                                }
                            },
                            "industries": {
                                "title": "Accepted industries",
                                "type": "array",
                                "description": "A lead passes when its industry contains at least one value.",
                                "editor": "stringList",
                                "uniqueItems": true,
                                "maxItems": 100,
                                "items": {
                                    "type": "string"
                                }
                            },
                            "companyDomains": {
                                "title": "Accepted company domains",
                                "type": "array",
                                "description": "Optional account list. Subdomains of an accepted domain also pass.",
                                "editor": "stringList",
                                "uniqueItems": true,
                                "maxItems": 500,
                                "items": {
                                    "type": "string"
                                }
                            }
                        },
                        "additionalProperties": false
                    },
                    "rules": {
                        "title": "Quality rule overrides",
                        "type": "object",
                        "description": "Defaults come from the selected quality mode. Set only the values you need to change.",
                        "properties": {
                            "requireEmail": {
                                "title": "Require an email",
                                "type": "boolean",
                                "description": "Reject leads without an email address."
                            },
                            "checkMx": {
                                "title": "Check email domain MX records",
                                "type": "boolean",
                                "description": "Confirm that the email domain is configured to receive mail. This does not claim that the individual mailbox exists."
                            },
                            "requireMx": {
                                "title": "Require a valid MX result",
                                "type": "boolean",
                                "description": "Reject emails whose domain has no mail server. Temporary DNS errors are sent to REVIEW."
                            },
                            "rejectPersonalEmail": {
                                "title": "Reject personal email providers",
                                "type": "boolean",
                                "description": "Reject Gmail, Yahoo, Outlook, Proton, and similar personal inboxes."
                            },
                            "rejectDisposableEmail": {
                                "title": "Reject disposable email providers",
                                "type": "boolean",
                                "description": "Reject known temporary inbox domains."
                            },
                            "rejectRoleBasedEmail": {
                                "title": "Reject role-based inboxes",
                                "type": "boolean",
                                "description": "Reject addresses such as info@, support@, and sales@. Balanced mode only warns."
                            },
                            "requireEmailCompanyDomainMatch": {
                                "title": "Require email and company domain match",
                                "type": "boolean",
                                "description": "Reject a business email when its domain differs from the supplied company website."
                            },
                            "requireCompanyDomain": {
                                "title": "Require a company domain",
                                "type": "boolean",
                                "description": "Strict mode requires company domain evidence. Balanced mode sends missing domains to REVIEW."
                            },
                            "checkWebsite": {
                                "title": "Check company website reachability",
                                "type": "boolean",
                                "description": "Safely probe public company domains. Private and local network targets are never requested."
                            },
                            "requireWebsiteReachable": {
                                "title": "Require a reachable company website",
                                "type": "boolean",
                                "description": "Reject confirmed unreachable domains. Blocked or uncertain responses go to REVIEW."
                            },
                            "maxAgeDays": {
                                "title": "Maximum lead age in days",
                                "type": "integer",
                                "description": "When set, old evidence is rejected and missing timestamps go to REVIEW.",
                                "minimum": 1,
                                "maximum": 3650
                            },
                            "acceptScore": {
                                "title": "Minimum ACCEPT score",
                                "type": "integer",
                                "description": "Rows below this score go to REVIEW unless a hard reject rule applies.",
                                "minimum": 1,
                                "maximum": 100
                            },
                            "reviewScore": {
                                "title": "Minimum REVIEW score",
                                "type": "integer",
                                "description": "Rows below this score are rejected.",
                                "minimum": 0,
                                "maximum": 99
                            },
                            "sourceCostUsd": {
                                "title": "Original lead batch cost",
                                "type": "number",
                                "description": "Optional. Used to calculate the real source cost per accepted lead.",
                                "minimum": 0,
                                "maximum": 1000000
                            }
                        },
                        "additionalProperties": false
                    },
                    "fieldMap": {
                        "title": "Manual field mapping",
                        "type": "object",
                        "description": "Usually unnecessary. Override auto-detection with dot paths such as contact.email or company.website.",
                        "properties": {
                            "fullName": {
                                "title": "Full name path",
                                "type": "string",
                                "description": "Dot path for the contact's full name.",
                                "editor": "textfield"
                            },
                            "title": {
                                "title": "Job title path",
                                "type": "string",
                                "description": "Dot path for the contact's job title.",
                                "editor": "textfield"
                            },
                            "email": {
                                "title": "Email path",
                                "type": "string",
                                "description": "Dot path for the contact's email.",
                                "editor": "textfield"
                            },
                            "phone": {
                                "title": "Phone path",
                                "type": "string",
                                "description": "Dot path for the contact's phone.",
                                "editor": "textfield"
                            },
                            "linkedin": {
                                "title": "LinkedIn path",
                                "type": "string",
                                "description": "Dot path for the contact's LinkedIn URL.",
                                "editor": "textfield"
                            },
                            "country": {
                                "title": "Country path",
                                "type": "string",
                                "description": "Dot path for the contact's country.",
                                "editor": "textfield"
                            },
                            "city": {
                                "title": "City path",
                                "type": "string",
                                "description": "Dot path for the contact's city.",
                                "editor": "textfield"
                            },
                            "companyName": {
                                "title": "Company name path",
                                "type": "string",
                                "description": "Dot path for the company name.",
                                "editor": "textfield"
                            },
                            "companyDomain": {
                                "title": "Company domain path",
                                "type": "string",
                                "description": "Dot path for the company domain or website.",
                                "editor": "textfield"
                            },
                            "industry": {
                                "title": "Industry path",
                                "type": "string",
                                "description": "Dot path for the company industry.",
                                "editor": "textfield"
                            },
                            "updatedAt": {
                                "title": "Freshness timestamp path",
                                "type": "string",
                                "description": "Dot path for the lead's last update or verification time.",
                                "editor": "textfield"
                            }
                        },
                        "additionalProperties": false
                    },
                    "monitorName": {
                        "title": "Monitoring list name",
                        "maxLength": 80,
                        "type": "string",
                        "description": "Optional. Reuse the same name on scheduled runs to reject leads already seen in earlier runs."
                    },
                    "historyKey": {
                        "title": "Legacy history key",
                        "type": "string",
                        "description": "Deprecated compatibility field for existing saved tasks. New integrations should use monitorName."
                    },
                    "maxConcurrency": {
                        "title": "Maximum network concurrency",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Controls parallel MX and optional website checks."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
