Live Actor and maintained API: Run B2B Lead Cleaner on Apify
Real public Task inputs, PII-safe run outputs, and a strict JSON Schema for routing B2B lead rows into ACCEPT, REVIEW, or REJECT.
The Actor checks email syntax, provider type, DNS mail routing, company-domain consistency, duplicates, freshness, and optional ICP rules. It keeps one explained output decision per delivered source row.
These results came from successful public Task runs on 2026-07-28 using Actor build 0.0.29. The dataset contract was checked against the current 0.0.30 Actor source.
| Public Task | Actual run result | Input |
|---|---|---|
| Audit Purchased B2B Leads Before Vendor Renewal | 7 delivered: 5 ACCEPT, 1 REVIEW, 1 REJECT. A supplied $70 audited-scope cost produced a reported $14 per accepted lead. | JSON |
| Clean a B2B Lead List Before Cold Outreach | 7 delivered: 5 ACCEPT, 1 role-inbox REVIEW, 1 duplicate REJECT. | JSON |
| Prepare Complete B2B Leads for CRM Import | 5 delivered: 5 ACCEPT with score 100 in this synthetic sample. | JSON |
| Need | Raw-list handling | This Actor |
|---|---|---|
| Routing | Manual judgment or one opaque score | Explained ACCEPT, REVIEW, or REJECT |
| Email evidence | Often just a non-empty string | Syntax, provider class, and DNS MX evidence |
| Duplicates | Rows may be silently removed | Every delivered row remains, with duplicate flags and reason codes |
| Source formats | Fixed column names | Common aliases, nested paths, and manual field mapping |
| Targeting | Separate spreadsheet filters | Optional country, city, title, industry, and account rules |
| Run audit | Row output only | Dataset decisions plus an OUTPUT run report |
flowchart LR
A["Dataset, email strings, or lead objects"] --> B["Field detection and normalization"]
B --> C["Syntax, provider, and DNS MX checks"]
C --> D["Duplicate, freshness, domain, and ICP rules"]
D --> E{"Final decision"}
E -->|Pass| F["ACCEPT"]
E -->|Uncertain| G["REVIEW"]
E -->|Hard rule failed| H["REJECT"]
F --> I["Decision dataset and OUTPUT report"]
G --> I
H --> I
01. Audit purchased leads before vendor renewal
{
"maxItems": 7,
"qualityMode": "BALANCED",
"rows": [
{
"full_name": "Maya Chen",
"job_title": "VP Growth",
"email": "maya.chen@apify.com",
"company_name": "Apify",
"company_domain": "apify.com",
"country": "Czechia",
"city": "Prague",
"industry": "Software",
"sample_record": true
}
],
"rules": {
"requireEmail": false,
"sourceCostUsd": 70
},
"targeting": {
"countries": ["Czechia", "United States", "Germany"],
"industries": ["Software"],
"titleKeywords": [
"VP",
"Marketing Director",
"Revenue Operations",
"Demand Generation",
"Sales Operations"
]
}
}The complete seven-row input is in 01_audit_purchased_b2b_leads_before_vendor_renewal_input.json.
02. Clean a messy B2B list before outreach
{
"maxItems": 7,
"qualityMode": "BALANCED",
"rows": [
{
"full_name": "Maya Chen",
"job_title": "VP Marketing",
"work_email": "maya.chen@hubspot.com",
"company_website": "https://www.hubspot.com",
"sample_record": true
}
],
"rules": {
"acceptScore": 90
}
}The complete mixed-schema input is in 02_clean_a_b2b_lead_list_before_cold_outreach_input.json.
03. Prepare complete leads for CRM import
{
"maxItems": 5,
"qualityMode": "BALANCED",
"rows": [
{
"full_name": "Sofia Bennett (sample)",
"job_title": "VP Sales",
"email": "apify-task-demo-401@hubspot.com",
"company_name": "HubSpot",
"company_domain": "hubspot.com"
}
]
}The complete five-row input is in 03_prepare_complete_b2b_leads_for_crm_import_input.json.
These are schema-valid records from successful public Task runs. The duplicate example has identity values redacted while preserving its decision and evidence.
ACCEPT: complete business-domain record
{
"decision": "ACCEPT",
"qualityScore": 100,
"reasonCodes": [],
"emailStatus": "BUSINESS",
"mxStatus": "VALID",
"duplicate": false,
"evidence": {
"email": {
"syntaxValid": true,
"status": "BUSINESS",
"mailboxExistence": "NOT_CLAIMED"
}
}
}REVIEW: valid domain routing, but role inbox
{
"decision": "REVIEW",
"qualityScore": 85,
"primaryReason": "Quality score is below the ACCEPT threshold.",
"reasonCodes": [
"QUALITY_SCORE_NEEDS_REVIEW",
"EMAIL_ROLE_BASED"
],
"emailStatus": "ROLE_BASED",
"mxStatus": "VALID"
}REJECT: duplicate stays visible and explained
{
"decision": "REJECT",
"qualityScore": 30,
"primaryReason": "The same lead already appeared in this batch.",
"reasonCodes": ["DUPLICATE_LEAD"],
"duplicate": true,
"historicalDuplicate": false
}curl -X POST \
"https://api.apify.com/v2/acts/kamerozkan~b2b-lead-cleaner/runs" \
-H "Authorization: Bearer YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"emails": [
"person@company.example",
"team@company.example"
],
"qualityMode": "BALANCED"
}'After the run finishes, read decision rows from the default dataset and the run report from the default key-value store record OUTPUT.
The complete consumer contract is in dataset_record.schema.json. Important fields include:
decision,qualityScore,primaryReason, andreasonCodes- normalized contact and company fields
emailStatus,mxStatus, and optionalwebsiteStatusduplicate,historicalDuplicate, anddedupeKey- typed
evidenceand orderedreasons - raw-row preservation fields and
checkedAt
qualityScore is a deterministic rule-based quality score. It is not an email deliverability percentage.
VALIDMX means the domain had usable public mail-routing evidence at check time.- No SMTP mailbox probing is performed.
- The Actor does not prove that a specific mailbox exists or belongs to a person.
- Phone and LinkedIn values are normalized and preserved, not verified.
- The Actor does not guarantee current employment, consent, replies, or legal permission to contact someone.
- Process only data you are authorized to use and follow applicable privacy and marketing laws.
See DATA_NOTICE.md for sample provenance and privacy notes.
The repository files are available under the MIT License.