# CRM Lead Enrichment & Scoring – Emails, Phones, Social Links (`solutionssmart/crm-data-enrichment-agent`) Actor

Enrich CRM contacts and B2B leads with company data, validated emails, phone numbers, social links, and website signals. Supports JSON, CSV, and Apify datasets with deduplication, lead scoring, and optional Clearbit/Hunter enrichment for sales prospecting and automation workflows.

- **URL**: https://apify.com/solutionssmart/crm-data-enrichment-agent.md
- **Developed by:** [Solutions Smart](https://apify.com/solutionssmart) (community)
- **Categories:** Lead generation, Agents, Automation
- **Stats:** 11 total users, 0 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.10 / 1,000 results

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.md):

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

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

## CRM Lead Enrichment & Scoring – Emails, Phones, Social Links

### What this Actor does

It enriches CRM contacts with publicly available data and optional third-party APIs. It accepts contacts from JSON, CSV, or an Apify dataset, normalizes and validates contact fields, deduplicates records, enriches website and company signals, scores lead quality, and can deliver results to downstream integrations.

### What can this Actor do?

- Multiple input sources: JSON, CSV, or dataset ID
- Website enrichment for metadata, emails, social links, phone, address, and job-title hints
- Optional paid enrichment with Clearbit and Hunter
- Deduplication using configurable keys
- Quality scoring with signal breakdown
- Confidence, caching, learning, and budget-control features
- Optional webhook, n8n, and OpenClaw integrations

### Why use it

The Actor helps clean and enrich CRM data so teams can:

- Improve outbound targeting with validated contact signals
- Prioritize stronger leads using quality scores
- Reduce manual research and data cleanup
- Route high-value leads into sales workflows
- Control enrichment costs with adaptive and budget-aware settings

### How to use it

1. Open the Actor and choose `contactsSource`.
2. Provide contacts using `contactsJson`, `contactsCsv`, or `datasetId`.
3. Map fields with `emailField`, `firstNameField`, `lastNameField`, and `companyField`.
4. Configure enrichment, crawling, scoring, integrations, and intelligence settings as needed.
5. Run the Actor and review the Dataset and Output tabs.

### Input overview

Top-level input groups:

- `contactsSource`, `contactsJson`, `contactsCsv`, `datasetId`
- `emailField`, `firstNameField`, `lastNameField`, `companyField`
- `maxContacts`, `dedupeKeys`, `skipTestDomains`
- `enrichment`
- `crawling`
- `scoring`
- `integrations`
- `intelligence`
- `output`

Supported enrichment providers:

- Website fallback enrichment
- Clearbit
- Hunter

Useful controls:

- `crawling.maxRequestsPerMinute`
- `crawling.maxConcurrency`
- `crawling.requestTimeoutSecs`
- `crawling.maxRetries`
- `crawling.useProxy`
- `crawling.usePlaywrightFallback`

### Output

The Actor writes:

- Dataset items to the default dataset
- A summary to `OUTPUT_SUMMARY` in the default key-value store
- Summary plus full results to `OUTPUT` in the default key-value store

Each dataset item contains fields like:

- `contactId`
- `input`
- `normalized`
- `enrichment`
- `metrics`
- `dedupe`
- `score`
- `status`
- `chargeable`
- `reason`
- `leadType`
- `warnings`

Example dataset item:

```json
{
  "contactId": "abc123",
  "input": {
    "email": "john@example.com",
    "firstName": "John",
    "company": "Example Inc"
  },
  "normalized": {
    "email": "john@example.com",
    "emailValid": true,
    "domain": "example.com",
    "rootDomain": "example.com",
    "isSubdomain": false,
    "subdomainLabel": null,
    "isTestDomain": false,
    "isFreeEmailProvider": false,
    "companyNameNormalized": "Example Inc",
    "firstName": "John",
    "lastName": null
  },
  "enrichment": {
    "website": {
      "url": "https://example.com",
      "title": "Example Inc - Home",
      "metaDescription": "Example company homepage",
      "foundEmails": ["info@example.com"],
      "socialLinks": {
        "facebook": null,
        "instagram": null,
        "linkedin": "https://linkedin.com/company/example",
        "twitter": null,
        "youtube": null
      },
      "phone": null,
      "address": null,
      "jobTitle": null
    },
    "clearbit": null,
    "hunter": null
  },
  "metrics": {
    "enrichmentSourcesUsed": ["website"],
    "fetchTimesMs": {
      "website": 2341
    },
    "errors": [],
    "confidenceScore": 92
  },
  "dedupe": {
    "isDuplicate": false,
    "duplicateOf": null,
    "dedupeHash": "..."
  },
  "score": {
    "value": 78,
    "breakdown": {
      "emailValid": 25,
      "hasWebsite": 20,
      "hasPhone": 15,
      "hasSocial": 10,
      "companySignals": 8
    }
  },
  "status": "ok",
  "chargeable": true,
  "leadType": "business",
  "warnings": []
}
````

### Intelligence and automation features

- Adaptive enrichment can skip paid providers when confidence is already high.
- Domain cache can reuse website and provider results across runs.
- Progressive pipeline can limit paid APIs to a top-confidence subset.
- AI fallback supports `off`, `heuristic`, and `webhook` modes.
- Domain learning tracks reliable and unreliable domains over time.
- Budget guardrails cap Clearbit and Hunter calls per run.
- Integrations can send results to generic webhooks, n8n, or OpenClaw.
- Route-specific webhooks can be used for high-score or failed contacts.

### Marketing and intent signals

Use these as GTM signals:

- Contactability: valid email, phone, social presence.
- Company maturity: richer metadata, address presence, about/contact pages.
- Quality/intent proxy: stronger company signals and lower failure patterns.
- Reliability: confidence score, explainability notes, domain-learning state.

Suggested workflow:

- Route `score >= threshold` and strong confidence to outbound sequence.
- Route failed/partial leads to nurture or verification workflows.

### Tips and advanced options

- Start with website-only enrichment to keep costs low.
- Keep concurrency/rate conservative for stable crawling.
- Enable caching and learning for recurring runs on similar domains.
- Enable adaptive/progressive mode before turning on paid APIs at scale.
- Use route webhooks for high-score and failed queues.

### Compliance

Use the Actor responsibly and in compliance with privacy laws, target-site policies, and third-party API terms, including GDPR and CCPA where applicable.

### Support

If this Actor helps your workflow, please leave a **5-star rating** on the Actor page.

Quick video walkthrough:
https://youtu.be/81tHxtsWMb8?si=K3MYD\_WpcUM3rjLU

# Actor input Schema

## `contactsSource` (type: `string`):

Where to load contacts from: JSON input, CSV text, or an Apify dataset ID.

## `contactsJson` (type: `array`):

Array of contact objects when source is 'json'. Each object should have at least an email; optional fields: firstName, lastName, company, phone.

## `contactsCsv` (type: `string`):

CSV string with headers when source is 'csv'. First row must be header names; use the field mapping options to match column names.

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

Apify dataset ID when source is 'dataset'. The Actor will read items from this dataset up to the maximum contacts limit.

## `emailField` (type: `string`):

Property or column name for the contact's email in your data.

## `firstNameField` (type: `string`):

Property or column name for first name (optional).

## `lastNameField` (type: `string`):

Property or column name for last name (optional).

## `companyField` (type: `string`):

Property or column name for company (optional).

## `maxContacts` (type: `integer`):

Maximum number of contacts to process. Earlier contacts are processed first.

## `dedupeKeys` (type: `array`):

Keys used to identify duplicates. Allowed: email, domain, companyNameNormalized, firstName, lastName. Add one key per line or use the JSON editor.

## `enrichment` (type: `object`):

Configure enrichment providers: website fallback (no API key), Clearbit, and Hunter.

## `crawling` (type: `object`):

HTTP request settings: rate limit (global across website, Clearbit, and Hunter), timeout, retries, and concurrency.

## `scoring` (type: `object`):

Configure contact quality scoring. Weights should sum to about 1.0.

## `integrations` (type: `object`):

Send run summary/results to n8n, OpenClaw, or a generic webhook endpoint after processing completes.

## `intelligence` (type: `object`):

Advanced controls for adaptive enrichment, caching, AI fallback, learning memory, routing intelligence, and cost guardrails.

## `output` (type: `object`):

Configure how results are written to the dataset and key-value store.

## Actor input object example

```json
{
  "contactsSource": "json",
  "contactsJson": [
    {
      "email": "john.doe@example.com",
      "firstName": "John",
      "lastName": "Doe",
      "company": "Example Inc"
    },
    {
      "email": "jane.smith@example.com",
      "firstName": "Jane",
      "lastName": "Smith",
      "company": "Acme Corp"
    }
  ],
  "contactsCsv": "",
  "datasetId": "",
  "emailField": "email",
  "firstNameField": "firstName",
  "lastNameField": "lastName",
  "companyField": "company",
  "maxContacts": 500,
  "dedupeKeys": [
    "email",
    "domain"
  ],
  "enrichment": {
    "enableWebsiteFallback": true,
    "enableClearbit": false,
    "clearbitApiKey": "",
    "enableHunter": false,
    "hunterApiKey": ""
  },
  "crawling": {
    "maxRequestsPerMinute": 60,
    "requestTimeoutSecs": 12,
    "maxRetries": 2,
    "maxConcurrency": 10,
    "useProxy": false,
    "usePlaywrightFallback": false
  },
  "scoring": {
    "enabled": true,
    "emailValid": 0.25,
    "hasWebsite": 0.2,
    "hasPhone": 0.15,
    "hasSocial": 0.15,
    "companySignals": 0.25
  },
  "integrations": {
    "enableWebhook": false,
    "webhookUrl": "",
    "webhookSecret": "",
    "payloadMode": "summary",
    "webhookTimeoutMs": 10000,
    "webhookMaxRetries": 2,
    "webhookRetryDelayMs": 1000,
    "enableN8n": false,
    "n8nWebhookUrl": "",
    "n8nApiKey": "",
    "enableOpenClaw": false,
    "openClawWebhookUrl": "",
    "openClawApiKey": "",
    "highScoreWebhookUrl": "",
    "failedWebhookUrl": "",
    "highScoreThreshold": 75
  },
  "intelligence": {
    "adaptiveEnrichment": true,
    "minConfidenceForApiEnrichment": 70,
    "enableDomainCache": true,
    "cacheTtlHours": 24,
    "aiFallbackMode": "heuristic",
    "aiFallbackWebhookUrl": "",
    "progressivePipeline": true,
    "maxApiEnrichmentPercent": 30,
    "enableConfidenceExplainability": true,
    "enableDomainLearning": true,
    "learningBlockThreshold": 5,
    "learningAllowThreshold": 3,
    "smartRetry": true,
    "budgetGuardrails": false,
    "maxExternalApiCalls": 1000
  },
  "output": {
    "pushPartialResultsEvery": 50,
    "saveDebugArtifacts": false
  }
}
```

# Actor output Schema

## `enrichedContacts` (type: `string`):

Dataset containing one item per enriched contact (input, normalized, enrichment, score, etc.).

## `summaryAndResults` (type: `string`):

Key-value store record with run summary and full results (OUTPUT key).

# 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 = {
    "contactsJson": [
        {
            "email": "john.doe@example.com",
            "firstName": "John",
            "lastName": "Doe",
            "company": "Example Inc"
        },
        {
            "email": "jane.smith@example.com",
            "firstName": "Jane",
            "lastName": "Smith",
            "company": "Acme Corp"
        }
    ],
    "dedupeKeys": [
        "email",
        "domain"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("solutionssmart/crm-data-enrichment-agent").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 = {
    "contactsJson": [
        {
            "email": "john.doe@example.com",
            "firstName": "John",
            "lastName": "Doe",
            "company": "Example Inc",
        },
        {
            "email": "jane.smith@example.com",
            "firstName": "Jane",
            "lastName": "Smith",
            "company": "Acme Corp",
        },
    ],
    "dedupeKeys": [
        "email",
        "domain",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("solutionssmart/crm-data-enrichment-agent").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 '{
  "contactsJson": [
    {
      "email": "john.doe@example.com",
      "firstName": "John",
      "lastName": "Doe",
      "company": "Example Inc"
    },
    {
      "email": "jane.smith@example.com",
      "firstName": "Jane",
      "lastName": "Smith",
      "company": "Acme Corp"
    }
  ],
  "dedupeKeys": [
    "email",
    "domain"
  ]
}' |
apify call solutionssmart/crm-data-enrichment-agent --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=solutionssmart/crm-data-enrichment-agent",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "CRM Lead Enrichment & Scoring – Emails, Phones, Social Links",
        "description": "Enrich CRM contacts and B2B leads with company data, validated emails, phone numbers, social links, and website signals. Supports JSON, CSV, and Apify datasets with deduplication, lead scoring, and optional Clearbit/Hunter enrichment for sales prospecting and automation workflows.",
        "version": "1.0",
        "x-build-id": "t2bxtZ3If5ILFJpEh"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/solutionssmart~crm-data-enrichment-agent/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-solutionssmart-crm-data-enrichment-agent",
                "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/solutionssmart~crm-data-enrichment-agent/runs": {
            "post": {
                "operationId": "runs-sync-solutionssmart-crm-data-enrichment-agent",
                "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/solutionssmart~crm-data-enrichment-agent/run-sync": {
            "post": {
                "operationId": "run-sync-solutionssmart-crm-data-enrichment-agent",
                "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",
                "required": [
                    "contactsSource"
                ],
                "properties": {
                    "contactsSource": {
                        "title": "Contact source",
                        "enum": [
                            "json",
                            "csv",
                            "dataset"
                        ],
                        "type": "string",
                        "description": "Where to load contacts from: JSON input, CSV text, or an Apify dataset ID.",
                        "default": "json"
                    },
                    "contactsJson": {
                        "title": "Contacts (JSON)",
                        "type": "array",
                        "description": "Array of contact objects when source is 'json'. Each object should have at least an email; optional fields: firstName, lastName, company, phone.",
                        "items": {
                            "type": "object"
                        },
                        "default": []
                    },
                    "contactsCsv": {
                        "title": "Contacts (CSV)",
                        "type": "string",
                        "description": "CSV string with headers when source is 'csv'. First row must be header names; use the field mapping options to match column names.",
                        "default": ""
                    },
                    "datasetId": {
                        "title": "Dataset ID",
                        "type": "string",
                        "description": "Apify dataset ID when source is 'dataset'. The Actor will read items from this dataset up to the maximum contacts limit.",
                        "default": ""
                    },
                    "emailField": {
                        "title": "Email field name",
                        "type": "string",
                        "description": "Property or column name for the contact's email in your data.",
                        "default": "email"
                    },
                    "firstNameField": {
                        "title": "First name field",
                        "type": "string",
                        "description": "Property or column name for first name (optional).",
                        "default": "firstName"
                    },
                    "lastNameField": {
                        "title": "Last name field",
                        "type": "string",
                        "description": "Property or column name for last name (optional).",
                        "default": "lastName"
                    },
                    "companyField": {
                        "title": "Company field",
                        "type": "string",
                        "description": "Property or column name for company (optional).",
                        "default": "company"
                    },
                    "maxContacts": {
                        "title": "Maximum contacts",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum number of contacts to process. Earlier contacts are processed first.",
                        "default": 500
                    },
                    "dedupeKeys": {
                        "title": "Deduplication keys",
                        "type": "array",
                        "description": "Keys used to identify duplicates. Allowed: email, domain, companyNameNormalized, firstName, lastName. Add one key per line or use the JSON editor.",
                        "items": {
                            "type": "string"
                        },
                        "default": [
                            "email",
                            "domain"
                        ]
                    },
                    "enrichment": {
                        "title": "Enrichment settings",
                        "type": "object",
                        "description": "Configure enrichment providers: website fallback (no API key), Clearbit, and Hunter.",
                        "properties": {
                            "enableWebsiteFallback": {
                                "title": "Enable website fallback",
                                "description": "Fetch company websites for light enrichment (no API key required).",
                                "type": "boolean",
                                "default": true
                            },
                            "enableClearbit": {
                                "title": "Enable Clearbit",
                                "description": "Use Clearbit API for enrichment. Requires Clearbit API key.",
                                "type": "boolean",
                                "default": false
                            },
                            "clearbitApiKey": {
                                "title": "Clearbit API key",
                                "description": "Your Clearbit API key.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "enableHunter": {
                                "title": "Enable Hunter",
                                "description": "Use Hunter API for email finding. Requires Hunter API key.",
                                "type": "boolean",
                                "default": false
                            },
                            "hunterApiKey": {
                                "title": "Hunter API key",
                                "description": "Your Hunter API key.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            }
                        },
                        "default": {
                            "enableWebsiteFallback": true,
                            "enableClearbit": false,
                            "clearbitApiKey": "",
                            "enableHunter": false,
                            "hunterApiKey": ""
                        }
                    },
                    "crawling": {
                        "title": "Crawling settings",
                        "type": "object",
                        "description": "HTTP request settings: rate limit (global across website, Clearbit, and Hunter), timeout, retries, and concurrency.",
                        "properties": {
                            "maxRequestsPerMinute": {
                                "title": "Max requests per minute",
                                "description": "Global rate limit for all enrichment requests (website, Clearbit, Hunter) combined.",
                                "type": "integer",
                                "default": 60,
                                "minimum": 1,
                                "maximum": 1000,
                                "editor": "number"
                            },
                            "requestTimeoutSecs": {
                                "title": "Request timeout (seconds)",
                                "description": "HTTP request timeout in seconds.",
                                "type": "integer",
                                "default": 12,
                                "minimum": 5,
                                "maximum": 120,
                                "editor": "number"
                            },
                            "maxRetries": {
                                "title": "Max retries",
                                "description": "Number of retries on failed requests.",
                                "type": "integer",
                                "default": 2,
                                "minimum": 0,
                                "maximum": 10,
                                "editor": "number"
                            },
                            "maxConcurrency": {
                                "title": "Max concurrency",
                                "description": "Maximum concurrent requests.",
                                "type": "integer",
                                "default": 10,
                                "minimum": 1,
                                "maximum": 100,
                                "editor": "number"
                            },
                            "useProxy": {
                                "title": "Use proxy (Tier 2)",
                                "description": "When website fetch is blocked (403/429), retry with Apify Proxy (residential/rotating).",
                                "type": "boolean",
                                "default": false,
                                "editor": "checkbox"
                            },
                            "usePlaywrightFallback": {
                                "title": "Use Playwright fallback (Tier 3)",
                                "description": "When proxy fails, try headless browser (Playwright). Requires Playwright optional dependency.",
                                "type": "boolean",
                                "default": false,
                                "editor": "checkbox"
                            }
                        },
                        "default": {
                            "maxRequestsPerMinute": 60,
                            "requestTimeoutSecs": 12,
                            "maxRetries": 2,
                            "maxConcurrency": 10,
                            "useProxy": false,
                            "usePlaywrightFallback": false
                        }
                    },
                    "scoring": {
                        "title": "Scoring settings",
                        "type": "object",
                        "description": "Configure contact quality scoring. Weights should sum to about 1.0.",
                        "properties": {
                            "enabled": {
                                "title": "Enable scoring",
                                "description": "Calculate quality scores for each contact.",
                                "type": "boolean",
                                "default": true
                            },
                            "emailValid": {
                                "title": "Email valid weight",
                                "description": "Weight for valid email in the score (0-1).",
                                "type": "number",
                                "default": 0.25,
                                "minimum": 0,
                                "maximum": 1,
                                "editor": "number"
                            },
                            "hasWebsite": {
                                "title": "Has website weight",
                                "description": "Weight for having website data in the score (0-1).",
                                "type": "number",
                                "default": 0.2,
                                "minimum": 0,
                                "maximum": 1,
                                "editor": "number"
                            },
                            "hasPhone": {
                                "title": "Has phone weight",
                                "description": "Weight for having phone number in the score (0-1).",
                                "type": "number",
                                "default": 0.15,
                                "minimum": 0,
                                "maximum": 1,
                                "editor": "number"
                            },
                            "hasSocial": {
                                "title": "Has social weight",
                                "description": "Weight for having social links in the score (0-1).",
                                "type": "number",
                                "default": 0.15,
                                "minimum": 0,
                                "maximum": 1,
                                "editor": "number"
                            },
                            "companySignals": {
                                "title": "Company signals weight",
                                "description": "Weight for company enrichment signals in the score (0-1).",
                                "type": "number",
                                "default": 0.25,
                                "minimum": 0,
                                "maximum": 1,
                                "editor": "number"
                            },
                            "weights": {
                                "title": "Legacy weights object",
                                "description": "Legacy input compatibility only. Use individual scoring fields above.",
                                "type": "object",
                                "editor": "hidden",
                                "default": {
                                    "emailValid": 0.25,
                                    "hasWebsite": 0.2,
                                    "hasPhone": 0.15,
                                    "hasSocial": 0.15,
                                    "companySignals": 0.25
                                }
                            }
                        },
                        "default": {
                            "enabled": true,
                            "emailValid": 0.25,
                            "hasWebsite": 0.2,
                            "hasPhone": 0.15,
                            "hasSocial": 0.15,
                            "companySignals": 0.25
                        }
                    },
                    "integrations": {
                        "title": "Integrations",
                        "type": "object",
                        "description": "Send run summary/results to n8n, OpenClaw, or a generic webhook endpoint after processing completes.",
                        "properties": {
                            "enableWebhook": {
                                "title": "Enable generic webhook",
                                "description": "Send payload to a custom webhook URL.",
                                "type": "boolean",
                                "default": false
                            },
                            "webhookUrl": {
                                "title": "Generic webhook URL",
                                "description": "HTTPS endpoint for generic webhook delivery.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "webhookSecret": {
                                "title": "Webhook signing secret",
                                "description": "Optional HMAC SHA256 secret for X-Webhook-Signature header.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "payloadMode": {
                                "title": "Payload mode",
                                "description": "Choose whether webhook payload includes summary, full results, or both.",
                                "type": "string",
                                "enum": [
                                    "summary",
                                    "results",
                                    "both"
                                ],
                                "default": "summary",
                                "editor": "select"
                            },
                            "webhookTimeoutMs": {
                                "title": "Webhook timeout (ms)",
                                "description": "HTTP timeout for webhook requests.",
                                "type": "integer",
                                "default": 10000,
                                "minimum": 1000,
                                "maximum": 120000,
                                "editor": "number"
                            },
                            "webhookMaxRetries": {
                                "title": "Webhook max retries",
                                "description": "Retry attempts for failed webhook requests.",
                                "type": "integer",
                                "default": 2,
                                "minimum": 0,
                                "maximum": 10,
                                "editor": "number"
                            },
                            "webhookRetryDelayMs": {
                                "title": "Webhook retry delay (ms)",
                                "description": "Base delay between webhook retry attempts.",
                                "type": "integer",
                                "default": 1000,
                                "minimum": 100,
                                "maximum": 60000,
                                "editor": "number"
                            },
                            "enableN8n": {
                                "title": "Enable n8n webhook",
                                "description": "Send payload to an n8n webhook endpoint.",
                                "type": "boolean",
                                "default": false
                            },
                            "n8nWebhookUrl": {
                                "title": "n8n webhook URL",
                                "description": "n8n incoming webhook URL.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "n8nApiKey": {
                                "title": "n8n API key (optional)",
                                "description": "Optional X-N8N-API-KEY header value.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "enableOpenClaw": {
                                "title": "Enable OpenClaw webhook",
                                "description": "Send payload to an OpenClaw webhook endpoint.",
                                "type": "boolean",
                                "default": false
                            },
                            "openClawWebhookUrl": {
                                "title": "OpenClaw webhook URL",
                                "description": "OpenClaw webhook endpoint URL.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "openClawApiKey": {
                                "title": "OpenClaw API key (optional)",
                                "description": "Optional X-API-KEY header value.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "highScoreWebhookUrl": {
                                "title": "High-score route URL",
                                "description": "Optional route: send high-score contacts to this webhook URL.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "failedWebhookUrl": {
                                "title": "Failed route URL",
                                "description": "Optional route: send failed contacts to this webhook URL.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "highScoreThreshold": {
                                "title": "High-score threshold",
                                "description": "Minimum score for high-score route.",
                                "type": "integer",
                                "default": 75,
                                "minimum": 0,
                                "maximum": 100,
                                "editor": "number"
                            }
                        },
                        "default": {
                            "enableWebhook": false,
                            "webhookUrl": "",
                            "webhookSecret": "",
                            "payloadMode": "summary",
                            "webhookTimeoutMs": 10000,
                            "webhookMaxRetries": 2,
                            "webhookRetryDelayMs": 1000,
                            "enableN8n": false,
                            "n8nWebhookUrl": "",
                            "n8nApiKey": "",
                            "enableOpenClaw": false,
                            "openClawWebhookUrl": "",
                            "openClawApiKey": "",
                            "highScoreWebhookUrl": "",
                            "failedWebhookUrl": "",
                            "highScoreThreshold": 75
                        }
                    },
                    "intelligence": {
                        "title": "Intelligence & efficiency",
                        "type": "object",
                        "description": "Advanced controls for adaptive enrichment, caching, AI fallback, learning memory, routing intelligence, and cost guardrails.",
                        "properties": {
                            "adaptiveEnrichment": {
                                "title": "Adaptive enrichment",
                                "description": "Skip paid providers when confidence is already high.",
                                "type": "boolean",
                                "default": true
                            },
                            "minConfidenceForApiEnrichment": {
                                "title": "Min confidence for paid APIs",
                                "description": "If confidence is >= this value, adaptive mode skips paid APIs.",
                                "type": "integer",
                                "default": 70,
                                "minimum": 0,
                                "maximum": 100,
                                "editor": "number"
                            },
                            "enableDomainCache": {
                                "title": "Enable domain cache",
                                "description": "Reuse domain-level enrichment across contacts/runs.",
                                "type": "boolean",
                                "default": true
                            },
                            "cacheTtlHours": {
                                "title": "Cache TTL (hours)",
                                "description": "How long cached domain enrichments stay valid.",
                                "type": "integer",
                                "default": 24,
                                "minimum": 1,
                                "maximum": 720,
                                "editor": "number"
                            },
                            "aiFallbackMode": {
                                "title": "AI fallback mode",
                                "description": "Fallback when extraction is weak: off, local heuristic, or webhook.",
                                "type": "string",
                                "enum": [
                                    "off",
                                    "heuristic",
                                    "webhook"
                                ],
                                "default": "heuristic",
                                "editor": "select"
                            },
                            "aiFallbackWebhookUrl": {
                                "title": "AI fallback webhook URL",
                                "description": "Used only when AI fallback mode is 'webhook'.",
                                "type": "string",
                                "default": "",
                                "editor": "textfield"
                            },
                            "progressivePipeline": {
                                "title": "Progressive pipeline",
                                "description": "Limit paid APIs to top confidence band of contacts.",
                                "type": "boolean",
                                "default": true
                            },
                            "maxApiEnrichmentPercent": {
                                "title": "Top contacts for paid APIs (%)",
                                "description": "Only this percentage of contacts are eligible for paid APIs.",
                                "type": "integer",
                                "default": 30,
                                "minimum": 1,
                                "maximum": 100,
                                "editor": "number"
                            },
                            "enableConfidenceExplainability": {
                                "title": "Enable confidence explainability",
                                "description": "Attach confidence score, breakdown, and reasons per contact.",
                                "type": "boolean",
                                "default": true
                            },
                            "enableDomainLearning": {
                                "title": "Enable domain learning",
                                "description": "Persist domain allow/block learning across runs.",
                                "type": "boolean",
                                "default": true
                            },
                            "learningBlockThreshold": {
                                "title": "Learning block threshold",
                                "description": "Mark domain as blocklisted after this many failures.",
                                "type": "integer",
                                "default": 5,
                                "minimum": 1,
                                "maximum": 50,
                                "editor": "number"
                            },
                            "learningAllowThreshold": {
                                "title": "Learning allow threshold",
                                "description": "Mark domain as allowlisted after this many successes.",
                                "type": "integer",
                                "default": 3,
                                "minimum": 1,
                                "maximum": 50,
                                "editor": "number"
                            },
                            "smartRetry": {
                                "title": "Smart retry",
                                "description": "Use exponential backoff + jitter for outbound integrations.",
                                "type": "boolean",
                                "default": true
                            },
                            "budgetGuardrails": {
                                "title": "Enable budget guardrails",
                                "description": "Cap paid provider calls per run.",
                                "type": "boolean",
                                "default": false
                            },
                            "maxExternalApiCalls": {
                                "title": "Max external API calls",
                                "description": "Hard cap for Clearbit + Hunter calls in a run.",
                                "type": "integer",
                                "default": 1000,
                                "minimum": 1,
                                "maximum": 100000,
                                "editor": "number"
                            }
                        },
                        "default": {
                            "adaptiveEnrichment": true,
                            "minConfidenceForApiEnrichment": 70,
                            "enableDomainCache": true,
                            "cacheTtlHours": 24,
                            "aiFallbackMode": "heuristic",
                            "aiFallbackWebhookUrl": "",
                            "progressivePipeline": true,
                            "maxApiEnrichmentPercent": 30,
                            "enableConfidenceExplainability": true,
                            "enableDomainLearning": true,
                            "learningBlockThreshold": 5,
                            "learningAllowThreshold": 3,
                            "smartRetry": true,
                            "budgetGuardrails": false,
                            "maxExternalApiCalls": 1000
                        }
                    },
                    "output": {
                        "title": "Output settings",
                        "type": "object",
                        "description": "Configure how results are written to the dataset and key-value store.",
                        "properties": {
                            "pushPartialResultsEvery": {
                                "title": "Push results every N contacts",
                                "description": "Stream results to the dataset in batches of this size.",
                                "type": "integer",
                                "default": 50,
                                "minimum": 1,
                                "maximum": 500,
                                "editor": "number"
                            },
                            "saveDebugArtifacts": {
                                "title": "Save debug artifacts",
                                "description": "Store HTML snippets for debugging in the key-value store.",
                                "type": "boolean",
                                "default": false
                            }
                        },
                        "default": {
                            "pushPartialResultsEvery": 50,
                            "saveDebugArtifacts": false
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
