# Contact Finder Pro — MX-Verified Emails, E.164 Phones (`tugelbay/contact-finder-pro`) Actor

Premium contact extractor. Multi-page crawl, MX-verified emails (junk dropped), role classification (sales/support/careers/...), phone E.164 normalization, social-profile validation, Firecrawl anti-bot fallback, per-record quality score.

- **URL**: https://apify.com/tugelbay/contact-finder-pro.md
- **Developed by:** [Tugelbay Konabayev](https://apify.com/tugelbay) (community)
- **Categories:** Lead generation, Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

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

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

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

## Contact Finder Pro — MX-Verified Emails, Validated Socials, Role Detection

> **Premium contact-info extractor.** Built for B2B teams who need contact data they can actually use — not regex dumps full of dead emails and broken social links.
> **MX-verified emails** — every email's domain is checked for live MX records. Junk gets dropped, not shipped.
> **Role classification** — `sales@`, `careers@`, `support@`, `legal@`, `press@`, `personal` automatically tagged so you can target the right inbox.
> **Phone E.164 normalization** — international format ready for dialer/CRM import.
> **Social profile HEAD validation** — Facebook, Instagram, Twitter/X, LinkedIn, YouTube, TikTok, GitHub URLs verified to actually resolve before they're emitted.
> **Multi-page crawl per domain** — homepage + `/contact`, `/about`, `/team`, `/careers`, `/privacy` (where DPO emails live).
> **Firecrawl anti-bot fallback** — when direct fetch fails on Cloudflare/Akamai sites, retry through full browser rendering.

<a href="https://apify.com/tugelbay/contact-finder-pro">
  <img src="https://api.apify.com/v2/key-value-stores/bplRdpnd85eGQkW1N/records/contact-finder-pro-hero.png" alt="Contact Finder Pro premium contact extraction with MX verified emails and role detection" width="100%">
</a>

<p>
  <img src="https://api.apify.com/v2/key-value-stores/bplRdpnd85eGQkW1N/records/contact-finder-pro-input-output.png" alt="Contact Finder Pro input and output example" width="49%">
  <img src="https://api.apify.com/v2/key-value-stores/bplRdpnd85eGQkW1N/records/contact-finder-pro-dataset-preview.png" alt="Contact Finder Pro verified contact dataset preview" width="49%">
</p>

### Why Pro

The cheap contact-info scrapers on Apify Store ship raw extraction. They regex any `something@something.com` they find, dump the result, and call it done. The most popular alternative, [`vdrmota/contact-info-scraper`](https://apify.com/vdrmota/contact-info-scraper) (3.59 ★, 79 reviews), has 99% reliability — the complaint isn't that it fails. The complaint is the **output is unusable**: bounced emails, broken social URLs, no role context, raw phones in 5 different formats.

Pro is built around the validation gap:

| Layer                                      | Pro                                                                   | Incumbent                        |
| ------------------------------------------ | --------------------------------------------------------------------- | -------------------------------- |
| Email MX verification (drops dead domains) | Yes                                                                   | Mostly no                        |
| Email role classification                  | sales / support / careers / legal / press / billing / personal / info | Raw email only                   |
| Phone normalization (E.164)                | International format                                                  | As-found                         |
| Social profile validation (HEAD 200 check) | Yes                                                                   | Raw URL only                     |
| Multi-path crawl per domain                | 6 paths, single price                                                 | Configurable but billed per page |
| Anti-bot fallback (Firecrawl)              | Built-in                                                              | Manual config                    |
| Per-record quality score                   | 0.0-1.0                                                               | None                             |
| JSON-LD `Organization` schema parsing      | Yes                                                                   | No                               |
| Pricing model                              | PPE — pay per delivered VALUE                                         | PPE — pay per page scraped       |

### What You Get

For each input URL, one structured record:

#### Core fields

- `inputUrl` — what you submitted
- `domain` — extracted domain (lowercased, no `www.`)
- `companyName` — pulled from JSON-LD Organization, og:site_name, og:title, or `<title>`
- `pagesFetched` — how many candidate pages were actually retrieved
- `firecrawlUsed` — `true` if Firecrawl rescue was triggered
- `extractedAt` — ISO 8601 UTC timestamp
- `qualityScore` — 0.0-1.0 weighted completeness

#### Emails

```json
"emails": [
  { "email": "sales@stripe.com", "role": "sales", "verified": true },
  { "email": "press@stripe.com", "role": "press", "verified": true },
  { "email": "info@stripe.com",  "role": "info",  "verified": true }
]
````

Roles: `sales`, `support`, `careers`, `legal`, `press`, `billing`, `info`, `personal`.

#### Phones

```json
"phones": [
  { "raw": "+1 (415) 555-2671", "e164": "+14155552671" }
]
```

Numbers that fail E.164 normalization but contain at least 10 digits are still emitted with `e164: null` so you can normalize them yourself.

#### Socials

```json
"socials": [
  { "platform": "twitter",  "url": "https://twitter.com/stripe",  "validated": true  },
  { "platform": "linkedin", "url": "https://linkedin.com/company/stripe", "validated": true },
  { "platform": "github",   "url": "https://github.com/stripe",   "validated": false }
]
```

Platforms detected: `facebook`, `instagram`, `twitter` (X), `linkedin`, `youtube`, `tiktok`, `github`. `validated: true` means the profile URL responded HTTP 200 to a HEAD request.

### Quality SLA

Pro enforces a contract on every run before publishing the dataset:

| Metric                        | Target | What it means                                                                                   |
| ----------------------------- | ------ | ----------------------------------------------------------------------------------------------- |
| **Min items returned**        | 1      | If a query returns nothing, the run fails loudly instead of silently shipping an empty dataset. |
| **Min contact rate**          | 50%    | At least half of input URLs must return at least one email/phone/social.                        |
| **Min average quality score** | 0.30   | Average completeness across the dataset.                                                        |

If the dataset misses these targets, the run is flagged so you can re-run on a different input/proxy instead of paying for junk.

### Input Examples

#### Quick test (3 domains)

```json
{
  "urls": [
    "https://www.intercom.com",
    "https://stripe.com",
    "https://shopify.com"
  ]
}
```

#### CRM enrichment (large list, full validation)

```json
{
  "urls": ["acme.com", "globex.io", "initech.co.uk"],
  "verifyEmailMx": true,
  "firecrawlFallback": true,
  "validateSocialProfiles": true,
  "maxPagesPerDomain": 8,
  "maxConcurrency": 5
}
```

#### Cost-controlled bulk run (skip social validation)

```json
{
  "urls": ["..."],
  "validateSocialProfiles": false,
  "firecrawlFallback": false,
  "maxPagesPerDomain": 3
}
```

#### Region-specific (UK phones)

```json
{
  "urls": ["https://www.john-lewis.co.uk", "https://tesco.com"],
  "countryHint": "GB"
}
```

### Output Example

```json
{
  "inputUrl": "https://www.intercom.com",
  "domain": "intercom.com",
  "companyName": "Intercom — The only helpdesk designed for AI-first customer service",
  "emails": [
    { "email": "team@intercom.com", "role": "personal", "verified": true }
  ],
  "phones": [{ "raw": "+1 (415) 660-9690", "e164": "+14156609690" }],
  "socials": [
    {
      "platform": "twitter",
      "url": "https://twitter.com/intercom",
      "validated": true
    },
    {
      "platform": "linkedin",
      "url": "https://www.linkedin.com/company/intercom",
      "validated": true
    },
    {
      "platform": "facebook",
      "url": "https://www.facebook.com/intercom",
      "validated": true
    },
    {
      "platform": "youtube",
      "url": "https://www.youtube.com/c/intercom",
      "validated": true
    },
    {
      "platform": "github",
      "url": "https://github.com/intercom",
      "validated": false
    }
  ],
  "pagesFetched": 5,
  "firecrawlUsed": false,
  "extractedAt": "2026-05-06T22:46:57Z",
  "qualityScore": 0.9
}
```

### Pricing — Pay Per Event (effective 2026-05-20)

Charged only when delivered value matches:

| Event              | Price     | When charged                                           |
| ------------------ | --------- | ------------------------------------------------------ |
| `actor-start`      | **$0.05** | Once per run                                           |
| `url-processed`    | **$0.02** | Per input URL with at least one contact field returned |
| `email-verified`   | **$0.05** | Per email confirmed deliverable via MX                 |
| `social-validated` | **$0.02** | Per social profile that responded HTTP 200             |

#### Realistic run costs

| Scenario                                               | Breakdown                                     | Total      |
| ------------------------------------------------------ | --------------------------------------------- | ---------- |
| 100 domains, 30 returned 1+ verified email + 3 socials | $0.05 + 100 × $0.02 + 30 × $0.05 + 90 × $0.02 | **$5.35**  |
| 50 domains, full enrichment, 40 hits                   | $0.05 + 50 × $0.02 + 40 × $0.05 + 80 × $0.02  | **$4.65**  |
| 1,000 domains bulk, no enrichment                      | $0.05 + 1000 × $0.02                          | **$20.05** |

You pay for delivered VALUE, not for infrastructure. If a domain returns nothing, no `url-processed` charge fires.

### Best Use Cases

1. **B2B sales prospecting** — feed your TAM domain list, get sales@/info@ contacts you can mail.
2. **CRM enrichment** — append role-tagged emails, normalized phones, validated socials to existing accounts.
3. **Investor research** — extract press@, founder personal emails, and verified LinkedIn/Twitter profiles from portfolio companies.
4. **Recruitment** — pull careers@/jobs@ contacts from target companies for outbound recruiter outreach.
5. **Compliance / DPO discovery** — many privacy@ and dpo@ emails live on `/legal/privacy` pages — Pro's multi-path crawl finds them.
6. **PR / media outreach** — `press@` and `media@` emails pre-classified, ready for distribution lists.
7. **Competitor intel** — quickly gather public contact surface from competitor sites with quality score 0.6+.

### Programmatic Usage

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("tugelbay/contact-finder-pro").call(run_input={
    "urls": ["intercom.com", "stripe.com", "shopify.com"],
    "verifyEmailMx": True,
    "firecrawlFallback": True,
    "validateSocialProfiles": True,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    sales_emails = [e["email"] for e in item["emails"]
                    if e["verified"] and e["role"] == "sales"]
    if sales_emails:
        print(f"{item['domain']:<25} -> {sales_emails[0]}")
```

#### JavaScript / TypeScript

```typescript
import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "YOUR_TOKEN" });

const run = await client.actor("tugelbay/contact-finder-pro").call({
  urls: ["acme.com", "globex.io"],
  verifyEmailMx: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const verified = items
  .flatMap((it) => it.emails.filter((e) => e.verified))
  .filter((e) => e.role === "sales");
console.log(`${verified.length} verified sales emails`);
```

#### LangChain tool

```python
from langchain_core.tools import tool

@tool
def find_contacts(domain: str) -> dict:
    """Get verified contact info (emails by role, phones, socials) for a company domain."""
    from apify_client import ApifyClient
    client = ApifyClient("YOUR_TOKEN")
    run = client.actor("tugelbay/contact-finder-pro").call(run_input={
        "urls": [domain],
        "verifyEmailMx": True,
        "firecrawlFallback": True,
    })
    items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
    return items[0] if items else {}
```

#### MCP (Streamable HTTP)

```bash
npx mcpc connect mcp.apify.com
npx mcpc call tugelbay/contact-finder-pro --json '{"urls":["stripe.com"]}'
```

### FAQ

**Q: How is "MX-verified" different from full SMTP probe?**
A: MX verification confirms the domain is set up to receive mail at all — it catches ~80% of dead/junk addresses (typos, parked domains, abandoned sites) without the false-positive rate of SMTP probing (which many mail servers refuse). For deeper validation pipe `email` through NeverBounce or ZeroBounce after this run.

**Q: Why don't most modern SaaS sites return any emails?**
A: They moved to contact forms behind `/contact-sales`. There is no email on the page to extract. Pro will still return `companyName`, validated `socials`, and any `phones`. For raw email harvesting at SaaS companies, follow up with a tool that extracts founder/employee emails from LinkedIn (separate actor).

**Q: Will Firecrawl be charged when my run uses it?**
A: Firecrawl calls happen on the actor's compute cost, not yours. The premium PPE pricing already accounts for fallback usage. You don't pay separately.

**Q: What if a domain returns nothing?**
A: No `url-processed` charge is fired (you only pay for VALUE). The actor logs `no contacts found for X` and moves on.

**Q: Does it follow redirects?**
A: Yes — `httpx` follows redirects, and the final URL's domain is what gets emitted in the `domain` field.

**Q: International support?**
A: All extraction works globally. For phone normalization, set `countryHint` to the most-common country code in your input list (`GB`, `DE`, `FR`, etc.). US is the default.

**Q: How does this differ from official Hunter.io / Apollo / ZoomInfo APIs?**
A: Those services charge per-lead with monthly minimums ($49+ Hunter, $99+ Apollo). Pro is PPE — pay only when you actually receive a verified contact. For occasional prospecting, dramatically cheaper.

### Troubleshooting

**Empty dataset across all URLs**

- Check that `urls` is set; the actor falls back to a demo URL and warns if not.
- Some domains (LinkedIn, Twitter accounts directly) are heavily rate-limited — try variants.
- Disable `firecrawlFallback` to rule out timeouts at the fallback layer.

**Many emails returned but `verified: false`**

- Domain might have temporary DNS issues — retry the run.
- The MX lookup falls back to `8.8.8.8` / `1.1.1.1` automatically; if your domain has authoritative-only DNS, verification will be inconclusive.

**Phones look like CSS color codes**

- Pro filters phones to E.164-normalized OR 10+-digit. If you still see noise, lower `maxPagesPerDomain` to 3 (skips footer/legal pages where SPA color tokens live).

**Slow runs**

- Set `validateSocialProfiles: false` to skip the per-profile HEAD checks (saves about 3s per social URL).
- Set `firecrawlFallback: false` if you don't need the anti-bot rescue.
- Drop `maxPagesPerDomain` to 3 (homepage + /contact + /about only).

### Limitations

- **Email harvesting depends on the site exposing emails on its public pages.** Modern SaaS rarely does — Pro will return `companyName` + validated `socials` + `phones` even when emails are zero.
- **MX verification is necessary but not sufficient.** A domain with MX records can still have a non-existent mailbox. Pipe `email` through SMTP-probe service for deeper validation.
- **HEAD validation may miss profiles that block HEAD but allow GET.** Pro retries with GET on 403/405, but a few platforms (Instagram for non-public profiles) return 200 even for nonexistent users.
- **Phone normalization is best-effort.** If `phonenumbers` library cannot parse the number, the raw is still emitted (with `e164: null`) when 10+ digits.
- **Crawl is shallow by design** — only the listed contact paths, not full-site crawl. For deep crawl, use a separate Apify crawler upstream.

### Changelog

- **0.1 (2026-05-06)** — Initial release. Multi-path crawl, MX verification, role classification, E.164 phone normalization, social HEAD validation, Firecrawl fallback, JSON-LD parser, quality score. Premium PPE pricing scheduled for 2026-05-20.

# Actor input Schema

## `urls` (type: `array`):

Each entry can be a full URL ('https://stripe.com/contact') or a bare domain ('stripe.com'). The actor will probe homepage + common contact paths automatically.

## `verifyEmailMx` (type: `boolean`):

Premium quality gate: only emit emails whose domain has live MX records. Junk/dead domains are dropped instead of shipped.

## `firecrawlFallback` (type: `boolean`):

When direct httpx returned no email/phone for a domain, retry through Firecrawl with anti-bot bypass + JS rendering. Recovers contacts from Cloudflare/Akamai-protected sites.

## `validateSocialProfiles` (type: `boolean`):

For each found social URL (Facebook, Instagram, Twitter/X, LinkedIn, YouTube, TikTok, GitHub), send a HEAD request to confirm the profile exists. Broken links are flagged.

## `maxPagesPerDomain` (type: `integer`):

How many candidate paths per domain (homepage, /contact, /about, /team, /careers, /privacy). Higher = more contacts but slower and more expensive.

## `countryHint` (type: `string`):

Two-letter country code (US, GB, DE, FR, ...) used as the default region when a phone number is not already in international format. Leave empty for US default.

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

Number of URLs processed in parallel. Lower = more polite, higher = faster.

## `proxyConfiguration` (type: `object`):

Apify residential proxies recommended for best success rate on protected sites.

## Actor input object example

```json
{
  "urls": [
    "https://www.intercom.com",
    "https://www.shopify.com"
  ],
  "verifyEmailMx": true,
  "firecrawlFallback": true,
  "validateSocialProfiles": true,
  "maxPagesPerDomain": 6,
  "countryHint": "US",
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "urls": [
        "https://www.intercom.com",
        "https://www.shopify.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tugelbay/contact-finder-pro").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 = { "urls": [
        "https://www.intercom.com",
        "https://www.shopify.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("tugelbay/contact-finder-pro").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 '{
  "urls": [
    "https://www.intercom.com",
    "https://www.shopify.com"
  ]
}' |
apify call tugelbay/contact-finder-pro --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=tugelbay/contact-finder-pro",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Contact Finder Pro — MX-Verified Emails, E.164 Phones",
        "description": "Premium contact extractor. Multi-page crawl, MX-verified emails (junk dropped), role classification (sales/support/careers/...), phone E.164 normalization, social-profile validation, Firecrawl anti-bot fallback, per-record quality score.",
        "version": "0.1",
        "x-build-id": "tZP10SKQ784bu4Sna"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/tugelbay~contact-finder-pro/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-tugelbay-contact-finder-pro",
                "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/tugelbay~contact-finder-pro/runs": {
            "post": {
                "operationId": "runs-sync-tugelbay-contact-finder-pro",
                "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/tugelbay~contact-finder-pro/run-sync": {
            "post": {
                "operationId": "run-sync-tugelbay-contact-finder-pro",
                "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": {
                    "urls": {
                        "title": "URLs or domains to scan",
                        "type": "array",
                        "description": "Each entry can be a full URL ('https://stripe.com/contact') or a bare domain ('stripe.com'). The actor will probe homepage + common contact paths automatically.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "verifyEmailMx": {
                        "title": "Verify email via MX lookup",
                        "type": "boolean",
                        "description": "Premium quality gate: only emit emails whose domain has live MX records. Junk/dead domains are dropped instead of shipped.",
                        "default": true
                    },
                    "firecrawlFallback": {
                        "title": "Use Firecrawl when direct fetch returns nothing",
                        "type": "boolean",
                        "description": "When direct httpx returned no email/phone for a domain, retry through Firecrawl with anti-bot bypass + JS rendering. Recovers contacts from Cloudflare/Akamai-protected sites.",
                        "default": true
                    },
                    "validateSocialProfiles": {
                        "title": "Validate social profile URLs (HEAD check)",
                        "type": "boolean",
                        "description": "For each found social URL (Facebook, Instagram, Twitter/X, LinkedIn, YouTube, TikTok, GitHub), send a HEAD request to confirm the profile exists. Broken links are flagged.",
                        "default": true
                    },
                    "maxPagesPerDomain": {
                        "title": "Max pages crawled per domain",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "How many candidate paths per domain (homepage, /contact, /about, /team, /careers, /privacy). Higher = more contacts but slower and more expensive.",
                        "default": 6
                    },
                    "countryHint": {
                        "title": "Country hint for phone normalization (ISO 3166-1)",
                        "type": "string",
                        "description": "Two-letter country code (US, GB, DE, FR, ...) used as the default region when a phone number is not already in international format. Leave empty for US default.",
                        "default": "US"
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Number of URLs processed in parallel. Lower = more polite, higher = faster.",
                        "default": 5
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify residential proxies recommended for best success rate on protected sites.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
