# Website Contact & Email Scraper (`sandy_yclept/website-contact-email-scraper`) Actor

Extract emails, phone numbers and social profiles from any list of websites. Finds an email on 73% of domains - and you pay only for contacts found.

- **URL**: https://apify.com/sandy\_yclept/website-contact-email-scraper.md
- **Developed by:** [Rafal Sav](https://apify.com/sandy_yclept) (community)
- **Categories:** Lead generation, Automation, SEO tools
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 verified contacts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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/docs.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

### What does Website Contact & Email Scraper do?

**Website Contact & Email Scraper** is an accurate **email scraper and contact extractor**: give it any list of websites and it pulls **emails, phone numbers and social media profiles** into clean, structured data — one record per site, with **MX-validated emails and a confidence score** — ready for your CRM, outreach tool or lead-generation pipeline.

It runs on the [Apify platform](https://apify.com), so you get API access, scheduling, integrations (Make, Zapier, n8n), proxy rotation and run monitoring out of the box.

### Why use Website Contact & Email Scraper?

Most contact scrapers miss data that is right there on the page — social links, obfuscated emails, contacts hidden on subpages — and return lists full of junk and empty fields. This Actor is built around one thing: **accuracy**. Fewer garbage rows, more real hits, validated and scored.

On a random sample of 150 company domains it found an email on **73.3%** of them, against **54.0%** for the category incumbent, at a **lower cost per email found** — the numbers and the method are below.

### Use cases

- **Sales prospecting** — you have a list of target companies from Crunchbase, a directory or a Google Maps scrape, and you need a reachable inbox for each. Feed the domains in, get `best_email` per company, push it to your CRM.
- **Lead-list enrichment** — an existing list has company names and websites but no contacts. This fills in emails, phones and social profiles without paying a per-record data-provider fee.
- **Agency and freelancer outreach** — scrape the websites of a niche (dentists, law firms, e-commerce shops in one city) and get the contact page details that a Google Maps listing does not carry.
- **Recruiting** — collect careers and HR contacts from a list of employer sites, including the ones that hide addresses behind Cloudflare or `name [at] domain`.
- **Market and competitor research** — map which companies in a segment publish a phone number, which only take contact forms, and which social platforms they actually use.
- **GDPR / imprint compliance checks** — verify that a list of sites publishes a reachable data-controller contact on its privacy policy or `Impressum` page.

### How the accuracy engine works

For every site it goes deeper and recovers data other scrapers drop:

- **Deep crawl** — not just the homepage, but the `/contact`, `/about`, `/team` and `/impressum` subpages where contacts actually live (bounded by `maxContactPages`, and it stays on the site's own domain).
- **Hidden-email recovery** — decodes Cloudflare `data-cfemail` / `email-protection` links, un-obfuscates `name [at] domain [dot] com`, and reads `mailto:` links and JSON-LD / schema.org metadata.
- **Validation & scoring** — checks each email against its domain's MX records, drops example/placeholder/asset noise, flags generic role inboxes (`info@`, `sales@`), and attaches a **confidence score** so you can pick the `best_email`.
- **Phones & socials** — parses phone numbers into E.164 with Google's libphonenumber, and extracts LinkedIn / X / Facebook / Instagram / YouTube / TikTok profiles while filtering out share/intent links.

It respects `robots.txt` and rate-limits its requests.

### How to use Website Contact & Email Scraper

1. Add one or more URLs under **Start URLs**.
2. (Optional) Set **Max contact subpages**, toggle **Validate emails** / **Extract social profiles**, set a **Default phone region**, or switch **JavaScript rendering** to `auto` for sites that need a browser (raise run memory to 2048 MB first).
3. Click **Start**.
4. Download your results as JSON, CSV, Excel or HTML from the **Output** tab, or pull them via the Apify API.

### Input

| Field | Type | Description |
|---|---|---|
| `startUrls` | array | Websites to extract contacts from (one record per URL). **Required.** |
| `maxContactPages` | integer | How many contact-like subpages to deep-crawl per site (0 = homepage only). Default 5. |
| `validateEmails` | boolean | Validate emails via MX records and attach a confidence score. Default true. |
| `includeSocials` | boolean | Extract LinkedIn / X / Facebook / Instagram / YouTube / TikTok profiles. Default true. |
| `renderJs` | string | `off` (default), `auto` or `on` — load pages in a real browser. See [JavaScript rendering](#javascript-rendering-renderjs). Needs ≥2048 MB run memory. |
| `phoneRegion` | string | ISO country code (e.g. `PL`, `US`) for parsing local-format phone numbers. Empty = auto-detect from the domain's TLD, then from page signals (address country, `og:locale`, `html lang`) so local numbers are still recovered on `.com`/`.org` sites. |
| `proxyConfiguration` | object | Optional proxy. Apify Proxy needs a paid plan; disabled by default (direct connection). |

### JavaScript rendering (`renderJs`)

Some sites hand a plain HTTP client nothing useful: they block non-browser clients outright (HTTP 403), or they build their footer and contact details client-side. Set **`renderJs`** to reach them.

| Mode | What happens | When to use it |
|---|---|---|
| `off` *(default)* | No browser. Fastest and cheapest. | Most sites — the accuracy engine already handles obfuscation, JSON-LD and Cloudflare-protected addresses. |
| `auto` **(recommended)** | Scans without a browser first; if a site yields **no contact at all**, the whole site is re-crawled in a browser. | Mixed lists of sites, where you don't know in advance which ones need a browser. |
| `on` | Always uses a browser. | You already know your targets are browser-only. |

`auto` is the cheap option by design: the browser starts only for sites the fast path could not read, so a list of ordinary sites costs the same as `renderJs=off`. On the four browser-only sites in our golden set this is the difference between **0-28%** recall without a browser and **100%** with one, while the browser stays switched off for the other 28 sites.

**Requirements:** `auto` and `on` need at least **2048 MB** of run memory (the browser needs roughly a gigabyte of its own). The default 512 MB is enough for `renderJs=off`. Each record carries a `rendered` flag so you can see which sites needed a browser.

**What a browser does not fix:** some sites reject requests based on the *IP address* rather than the client, and a datacenter IP — which is what every cloud run uses — gets an HTTP 403 whether or not a browser is driving it. `renderJs` reaches sites whose content is built in JavaScript and sites that turn away plain HTTP clients; it does not defeat IP-reputation protection. For those you need residential proxies (`proxyConfiguration`, paid Apify plans). When this happens the run log says so explicitly (`Browser got HTTP 403 for …`) instead of quietly returning nothing.

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
{
  "domain": "https://acme.example",
  "status": "ok",
  "best_email": "anna.nowak@acme.example",
  "emails": [
    { "email": "anna.nowak@acme.example", "valid_mx": true, "role": false, "confidence": 0.9 },
    { "email": "info@acme.example", "valid_mx": true, "role": true, "confidence": 0.85 }
  ],
  "phones": ["+48221234567"],
  "socials": {
    "linkedin": ["https://linkedin.com/company/acme"],
    "instagram": ["https://instagram.com/acme"]
  },
  "email_count": 2,
  "pages_crawled": 4,
  "rendered": false
}
````

#### When a site comes back `unreachable`

`unreachable` means no page was downloaded at all — the site refused the request or timed out — so it is **not** the same as "this company has no contact details". Nothing is charged for it. Two things are worth trying before you write such a domain off:

- Set **`renderJs`** to `auto`. Sites that turn away plain HTTP clients often serve a real browser normally.
- Add a **proxy** under `proxyConfiguration`. Some sites reject datacenter IP addresses no matter what client asks, and any cloud run uses one; residential proxies (paid Apify plans) are the way around that.

A site that answered but simply has nothing to give is reported as `no_contacts`, with `pages_crawled` showing how many pages were read.

#### Data fields

| Field | Description |
|---|---|
| `domain` | The site the record is for. |
| `status` | `ok` (contacts found), `no_contacts` (pages read, nothing to find) or `unreachable` (the site could not be fetched — see above). |
| `best_email` | Highest-confidence email (usually a named person over a role inbox). |
| `emails` | All emails found, each with `valid_mx`, `role` and `confidence` (0–1). |
| `phones` | Phone numbers normalized to E.164. |
| `socials` | Social profile URLs grouped by platform, deduplicated per account (a site linking both `twitter.com/acme` and `x.com/acme` yields one profile, not two). |
| `email_count` | Number of kept emails. |
| `pages_crawled` | How many pages were fetched for this site. |
| `rendered` | Whether a browser was needed for this site (see [`renderJs`](#javascript-rendering-renderjs)). |

### How it compares

We benchmarked this Actor against the category incumbent (`vdrmota/contact-info-scraper`, 12M+ runs) on an **independently hand-verified set of 28 real websites** - German legal `Impressum` pages, US nonprofits, SaaS contact pages, PL companies - each scraping a single page, no deep crawl, no browser, so it is a like-for-like test of extraction accuracy. Ground truth was read out of each page's raw HTML by hand and both Actors were scored identically.

| Field | Website Contact & Email Scraper | Incumbent |
|---|---|---|
| Emails (recall) | **100%** | 94% |
| Phone numbers (recall) | **100%**, clean E.164 | 0% usable |
| Social profiles (recall) | **100%** | 98% |

The biggest differences generalize to any site, not just the benchmark:

- **Phone numbers you can actually use.** We return normalized **E.164** numbers. The incumbent returned zero confident phone numbers across all 28 sites - it dumps raw strings into a separate "uncertain" bucket, mixing genuine numbers with garbage like `888 888 88888` and leaving the formatting to you.

- **Hidden emails other scrapers drop.** We recover Cloudflare-protected addresses, HTML-entity and `name at domain` obfuscations, and emails that live only in JSON-LD/schema.org or a `<link rel="author">` - cases where the incumbent returns nothing. And we don't invent them: prose like a heading "Advertising at PHP.net" is *not* turned into an email.

- **Browser rendering without the browser-sized bill.** Browser-only sites are covered by `renderJs` (see above), and the contacts it recovers cost exactly the same as any other — a flat fee per contact. The incumbent bills browser usage as a separate paid extra on top of its per-page fee.

#### Head-to-head on an uncurated list

We ran this Actor and the incumbent (`vdrmota/contact-info-scraper`, 12M+ runs) over the **same 150 randomly sampled company domains** on the same day, at the same crawl depth:

| Metric | This Actor | Incumbent |
|---|---|---|
| Domains with an email | **73.3%** | 54.0% |
| Emails found | **192** | 117 |
| Phone numbers | **12 usable (E.164)** | 4 confident, 38 unnormalized |
| Cost for the run | **$0.89** | $0.97 |
| **Cost per email found** | **$0.0046** | $0.0083 |

On **30 domains only we returned an address**; the reverse happened once. Full method, configuration and caveats: [`benchmark/head_to_head_yc150.md`](benchmark/head_to_head_yc150.md).

#### What it yields on a list you didn't curate

Accuracy on hand-picked pages is one thing; what matters when you buy a run is how many domains actually give you something. We scanned **300 randomly sampled Y Combinator companies** (public API, seed 42 — a deliberately hard list: modern JS-heavy startup sites, often with a contact form instead of an address):

| Metric | Value |
|---|---|
| Yielded at least one contact | **81.3%** |
| Yielded an email | 60.7% |
| Emails found | 247 — **47% addressed to a person**, 95% MX-valid |
| Could not be fetched | 1.0% |
| Cost | **$1.33 for 300 domains** (~$0.0044 per domain) |

Re-running only the domains that yielded nothing, with `renderJs: auto`, recovered **24 of 56 (43%)** for a further **$0.09** — taking coverage of the list from 81.3% to **89.3%**, and domains with an email from 60.7% to **66.3%**.

Full write-up and reproduction steps: [`benchmark/field_report_yc300.md`](benchmark/field_report_yc300.md).

The full per-site table is in [`benchmark/vdrmota_comparison.md`](benchmark/vdrmota_comparison.md); you can reproduce it with `python benchmark/run_benchmark.py`. The golden set now holds 32 sites — the 28 above plus 4 browser-only ones added to prove the `renderJs` path (`python benchmark/run_benchmark.py --render-js auto`, which scores 100% precision and recall across emails, phones and socials).

#### Check the numbers yourself

The golden set, the 300-domain sample list and the scoring script are published
as a public dataset: [github.com/RafalSav/website-contact-scraper-benchmark](https://github.com/RafalSav/website-contact-scraper-benchmark).
Every accuracy claim on this page can be audited or re-run against any scraper's
export. Corrections to the labels are welcome.

#### Scraping German sites?

There is a variant tuned for the DACH market: [Impressum Email Scraper](https://apify.com/sandy_yclept/impressum-email-scraper) — same engine, with Impressum-first crawling, `DE` phone parsing and `/datenschutz` as a fallback source.

### How much does it cost?

**You pay only for what is found — never for empty pages.** This Actor uses Apify's pay-per-event pricing, and the price follows what a result is actually worth to you:

- **Verified contact — $0.003** (~$3 per 1,000): an email or a phone number, i.e. something you can reach a person at.
- **Social profile — $0.001** (~$1 per 1,000): a clean, de-duplicated profile link. A footer link is worth less than a verified inbox, so it costs a third as much (and `twitter.com/acme` + `x.com/acme` count once, not twice).
- **Actor start:** Apify's standard ~$0.05 per 1,000 runs.
- **Free to try:** the Apify Free plan includes **$5 in monthly credits**.

Turn off `includeSocials` if you only want reachable contacts — then social links are neither extracted nor billed.

Because you are billed per result and not per page, deep-crawling extra subpages to recover a hidden email never inflates your bill on sites that have nothing to give. You can also cap spend per run with the **maximum cost** setting — the Actor stops charging as soon as your budget is reached.

### FAQ

#### How do I find the email address of a company from its website?

Paste the company's domain into **Start URLs** and run the Actor. It opens the homepage, then the contact-like subpages (`/contact`, `/about`, `/team`, `/impressum`, and privacy or terms pages as a fallback), collects every address it can prove is real, and returns the most promising one as `best_email`. No manual clicking through pages.

#### How many emails will I actually get?

On hand-picked contact pages, effectively all of them (100% recall on our 32-page verified benchmark). On an uncurated list of company domains, expect an email on roughly **two thirds to three quarters** of them: on 150 random company sites we returned an email for 73.3%. Sites that only offer a contact form are the usual reason for a miss — nobody can scrape an address that was never published.

#### Does it verify that the emails are valid?

Yes. Every address is checked against its domain's MX records (`valid_mx`), filtered against placeholder and asset noise, flagged as a role inbox (`info@`, `sales@`) or a named person, and scored with a `confidence` value between 0 and 1. Unlike most competitors, verification is included in the price rather than sold as a paid add-on.

#### What is the difference between `best_email` and the `emails` list?

`emails` holds everything found. `best_email` is the single highest-confidence pick — a named person's address outranks a general contact inbox, which outranks a technical or legal mailbox. It is the field to use when you want exactly one contact per company.

#### Can it scrape sites that need JavaScript?

Yes, via `renderJs`. Set it to `auto` (recommended) and a real browser is used only for sites the fast path could not read, so an ordinary list costs the same as running without a browser. Note that a browser does not defeat IP-reputation blocking — see [`renderJs`](#javascript-rendering-renderjs).

#### Why did a site come back empty?

Check the `status` field. `no_contacts` means pages were read and there was genuinely nothing to extract (typically a contact-form-only site). `unreachable` means nothing could be downloaded — retry with `renderJs: auto` or a residential proxy. Empty results are never charged.

#### How much does it cost to scrape 1,000 websites?

You pay per contact found, not per page. On the 300-domain field test the total was **$1.33 for 300 domains** (~$0.0044 each), which extrapolates to roughly **$4.4 per 1,000 typical company websites** — and domains that yield nothing cost you nothing. The Apify Free plan's $5 monthly credit covers about a thousand domains at that rate. Curated contact pages, which are richer in contacts, cost more per domain; empty ones cost zero.

#### Can I run it on a schedule or from my own code?

Yes. It is a standard Apify Actor: schedule it in the Console, call it from the Apify API or any of the client libraries, or connect it to Make, Zapier or n8n. The output dataset exports as JSON, CSV, Excel or HTML.

#### Is scraping contact details from websites legal?

Collecting business contact details that a company publishes on its own website is generally permitted, but the responsibility for how you use them is yours: under GDPR and similar regimes you are the data controller, you need a lawful basis for outreach, and you must honour opt-outs. This Actor respects `robots.txt` and rate-limits its requests. See the disclaimer below.

#### How is this different from the other contact scrapers on Apify?

Two things: it recovers addresses others drop (Cloudflare-protected, HTML-entity and `name at domain` obfuscation, JSON-LD, `<link rel="author">`, privacy-policy pages), and it charges for results rather than pages, so a deep crawl that finds nothing is free. Every accuracy claim in this README comes from a benchmark you can re-run yourself.

### Disclaimer

This Actor is a **tool**. You are the data controller for any personal data you collect and are responsible for using it in compliance with applicable laws (GDPR and equivalents), the target site's Terms of Service, and robots.txt. It does not build or sell contact databases.

### Support

Found a site where contacts were missed? Open an issue on the **Issues** tab — accuracy reports directly shape the roadmap.

# Actor input Schema

## `startUrls` (type: `array`):

List of websites (domains or URLs) to extract contact details from. One record per URL is produced.

## `maxContactPages` (type: `integer`):

How many contact-like subpages (/contact, /about, /team, /impressum, footer links) to deep-crawl per site, on top of the homepage. Set to 0 to scan the homepage only.

## `validateEmails` (type: `boolean`):

Check each discovered email against its domain's MX records and attach a confidence score. Turn off for a faster run without deliverability checks.

## `includeSocials` (type: `boolean`):

Extract LinkedIn, X/Twitter, Facebook, Instagram, YouTube and TikTok profile links (share/intent URLs are filtered out).

## `renderJs` (type: `string`):

Load pages in a real browser to reach contacts that are rendered by JavaScript. Off (default) is the fastest and cheapest. Auto scans without a browser first and only re-crawls a site in the browser when nothing was found — best accuracy/cost ratio. On always uses the browser. Auto and On require the run memory to be at least 2048 MB.

## `phoneRegion` (type: `string`):

ISO 3166-1 alpha-2 country code (e.g. PL, US, GB, DE) used to parse phone numbers written without an international prefix. Leave empty to auto-detect from each site's TLD; numbers written with a leading + are always parsed.

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

Optional proxy for fetching pages. Apify Proxy requires a paid plan; when left disabled the Actor connects directly.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://apify.com/"
    }
  ],
  "maxContactPages": 5,
  "validateEmails": true,
  "includeSocials": true,
  "renderJs": "off",
  "phoneRegion": "PL",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://apify.com/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sandy_yclept/website-contact-email-scraper").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 = { "startUrls": [{ "url": "https://apify.com/" }] }

# Run the Actor and wait for it to finish
run = client.actor("sandy_yclept/website-contact-email-scraper").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 '{
  "startUrls": [
    {
      "url": "https://apify.com/"
    }
  ]
}' |
apify call sandy_yclept/website-contact-email-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Website Contact & Email Scraper",
        "description": "Extract emails, phone numbers and social profiles from any list of websites. Finds an email on 73% of domains - and you pay only for contacts found.",
        "version": "0.2",
        "x-build-id": "fhlViWwoakLTe67Zv"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sandy_yclept~website-contact-email-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sandy_yclept-website-contact-email-scraper",
                "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/sandy_yclept~website-contact-email-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sandy_yclept-website-contact-email-scraper",
                "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/sandy_yclept~website-contact-email-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sandy_yclept-website-contact-email-scraper",
                "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": [
                    "startUrls"
                ],
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "List of websites (domains or URLs) to extract contact details from. One record per URL is produced.",
                        "default": [
                            {
                                "url": "https://apify.com/"
                            }
                        ],
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "maxContactPages": {
                        "title": "Max contact subpages",
                        "minimum": 0,
                        "maximum": 20,
                        "type": "integer",
                        "description": "How many contact-like subpages (/contact, /about, /team, /impressum, footer links) to deep-crawl per site, on top of the homepage. Set to 0 to scan the homepage only.",
                        "default": 5
                    },
                    "validateEmails": {
                        "title": "Validate emails (MX + scoring)",
                        "type": "boolean",
                        "description": "Check each discovered email against its domain's MX records and attach a confidence score. Turn off for a faster run without deliverability checks.",
                        "default": true
                    },
                    "includeSocials": {
                        "title": "Extract social profiles",
                        "type": "boolean",
                        "description": "Extract LinkedIn, X/Twitter, Facebook, Instagram, YouTube and TikTok profile links (share/intent URLs are filtered out).",
                        "default": true
                    },
                    "renderJs": {
                        "title": "JavaScript rendering",
                        "enum": [
                            "off",
                            "auto",
                            "on"
                        ],
                        "type": "string",
                        "description": "Load pages in a real browser to reach contacts that are rendered by JavaScript. Off (default) is the fastest and cheapest. Auto scans without a browser first and only re-crawls a site in the browser when nothing was found — best accuracy/cost ratio. On always uses the browser. Auto and On require the run memory to be at least 2048 MB.",
                        "default": "off"
                    },
                    "phoneRegion": {
                        "title": "Default phone region",
                        "type": "string",
                        "description": "ISO 3166-1 alpha-2 country code (e.g. PL, US, GB, DE) used to parse phone numbers written without an international prefix. Leave empty to auto-detect from each site's TLD; numbers written with a leading + are always parsed."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional proxy for fetching pages. Apify Proxy requires a paid plan; when left disabled the Actor connects directly.",
                        "default": {
                            "useApifyProxy": 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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
