# Website Contact & Email Scraper: Emails, Phones & Socials (`scrapers_lat/website-contacts-scraper`) Actor

Turn company websites into contacts. Per site, extract public emails, phones, WhatsApp, 15 social profiles (LinkedIn, X, Facebook, Instagram, YouTube, TikTok and more), contact people, company name and address, plus the page each contact came from. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/scrapers_lat/website-contacts-scraper.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 10 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $18.91 / 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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

[![Website Contact & Email Scraper](https://scrapers.lat/banners/website-contacts-scraper.png)](https://console.apify.com/actors/Hku49wXUWZptNNDaf/input)

## Website Contact & Email Scraper

Here is one real result (the `addresses`, `contacts` and `pagesScanned` arrays are trimmed to the first entries to keep the example short; all values are real):

```json
{
  "website": "https://stripe.com",
  "originalStartUrl": "stripe.com",
  "domain": "stripe.com",
  "companyName": "Stripe",
  "description": "Stripe is a financial services platform that helps all types of businesses accept payments, build flexible billing models, and manage money movement.",
  "emails": ["jane.diaz@stripe.com", "sales@stripe.com"],
  "phones": [],
  "phonesUncertain": ["+13024732533"],
  "whatsapp": null,
  "telegram": null,
  "linkedin": "https://www.linkedin.com/company/stripe",
  "twitter": "https://twitter.com/stripe",
  "facebook": "https://www.facebook.com/StripeHQ",
  "instagram": "https://www.instagram.com/stripehq",
  "youtube": "https://youtube.com/@stripe",
  "tiktok": null,
  "pinterest": null,
  "github": "https://github.com/stripe",
  "discord": null,
  "contactName": "John Collison",
  "contactJobTitle": null,
  "contactPersons": [
    { "name": "John Collison", "jobTitle": null, "email": null },
    { "name": "Patrick Collison", "jobTitle": null, "email": null }
  ],
  "address": "354 Oyster Point Blvd, South San Francisco, CA 94080, US",
  "addresses": ["354 Oyster Point Blvd, South San Francisco, CA 94080, US"],
  "contacts": [
    { "type": "email", "value": "jane.diaz@stripe.com", "sourceUrl": "https://stripe.com/contact", "depth": 1 }
  ],
  "contactPageUrls": ["https://stripe.com/contact"],
  "aboutPageUrls": ["https://stripe.com/about"],
  "foundContactDetails": true,
  "sourceUrl": "https://stripe.com/contact",
  "pagesScanned": ["https://stripe.com/", "https://stripe.com/contact", "https://stripe.com/about"],
  "pagesFailed": 0,
  "emailVerification": null,
  "source": "Website Contacts",
  "observedAt": "2026-08-25T14:39:53.311Z"
}
```

The most complete website contact scraper on Apify. Give it a list of company websites and it returns one clean record per site with the public business emails, phone numbers, WhatsApp and Telegram, 15 social platforms (LinkedIn, Twitter/X, Facebook, Instagram, YouTube, TikTok, Pinterest, GitHub, Discord, Snapchat, Threads, Reddit, Yelp, Google Business), contact people with job titles, postal address, company name and description, and the exact page each contact was found on. It gives you more input filters, more valid output fields and wider social coverage than any competing actor, runs HTTP-only for speed, and only charges for records it actually returns.

**📥 [Input](https://apify.com/scrapers_lat/website-contacts-scraper/input-schema) · 📤 [Output](https://apify.com/scrapers_lat/website-contacts-scraper/output-schema) · 💰 [Pricing](https://apify.com/scrapers_lat/website-contacts-scraper/pricing) · ▶️ [Examples](https://apify.com/scrapers_lat/website-contacts-scraper/examples)**

![Apify](https://img.shields.io/badge/Platform-Apify-1CE1CE?logo=apify\&logoColor=white)
![Coverage](https://img.shields.io/badge/Coverage-Global-blue)
![Output](https://img.shields.io/badge/Output-JSON%20%7C%20CSV%20%7C%20Excel-orange)
![Billing](https://img.shields.io/badge/Billing-Pay%20per%20result-brightgreen)

### Table of contents

- [What it does](#what-it-does)
- [How we compare](#how-we-compare)
- [Quickstart](#quickstart)
- [Input reference](#input-reference)
- [Output reference](#output-reference)
- [Example output record](#example-output-record)
- [Run via API and CLI](#run-via-api-and-cli)
- [Fetch results](#fetch-results)
- [Billing and limits](#billing-and-limits)
- [FAQ and troubleshooting](#faq-and-troubleshooting)

### What it does

Give the actor a list of company websites. For each one it reads the homepage plus a few likely contact, about, and team pages, and extracts the public business emails, phone numbers, WhatsApp click-to-chat number, social profiles, and postal addresses it can find. It returns one clean, deduplicated record per website. Emails are validated and stripped of placeholder and asset noise (no `example.com`, no image filenames), addresses are read from structured JSON-LD data, and the `pagesScanned` list records exactly which pages produced the contacts. Missing values are returned as `null` or empty arrays, never invented.

This is a lead-enrichment tool: feed it domains from any list and get back contact records ready for a CRM.

### How we compare

An objective look at this actor next to the most popular website contact and email extractors on the Apify Store. Every claim below reflects each actor's own public listing.

| Capability | This actor | vdrmota `contact-info-scraper` | practicaltools `contact-details-scraper` | automation-lab `website-contact-details-extractor` | creative_tablecloth `extract-email-phone-social` |
|---|---|---|---|---|---|
| Input filters | 15 (depth, page cap, same-domain, subdomains, include/exclude URL globs, paths, concurrency, renderJs, dry run and more) | ~12 | ~8 | ~6 | 1 |
| Emails + phones | Yes, plus low-confidence `phonesUncertain` | Yes | Yes | Yes | Yes |
| Social platforms | 15 (LinkedIn, X, Facebook, Instagram, YouTube, TikTok, Pinterest, GitHub, Discord, Snapchat, Threads, Reddit, Yelp, Google Business, plus WhatsApp and Telegram) | ~14 | ~9 | 8 | 8 (incl. Yelp, Google) |
| Per-contact source URL + depth | Yes, on every email and phone (`contacts[]`) | No (domain-level) | Page-level only | No | No |
| Contact person name + job title | Yes, native (`contactPersons[]`) | Paid enrichment add-on | No | No | No |
| Company name + postal address | Yes | Partial | No | Yes | No |
| Contact / about page URLs | Yes | No | No | Yes | No |
| Email deliverability check | Optional MX add-on | Paid add-on | No | No | No |
| Cloudflare / WAF pages | Optional solver (renderJs) | Optional browser | Headless browser | No | No |
| Engine | HTTP-only (fast) | HTTP or browser | Headless browser | HTTP-only | Not disclosed |
| No charge on empty / failed run | Yes | Charges per page scanned | Charges per result | Charges per record | Rental plus usage |
| Spend cap (`maxTotalChargeUsd`) | Yes, enforced | Not advertised | Not advertised | Not advertised | Not advertised |
| Pricing | Pay per result (see pricing tab) | ~$0.00105 per page | ~$0.0045 per result | ~$0.0036 per website plus start fee | Rental ~$20 per month plus usage |

Where a competitor genuinely wins: several actors are cheaper per record. `automation-lab` at roughly $0.0036 per website and `practicaltools` at roughly $0.0045 per result undercut our per-result price, and `creative_tablecloth` is cheapest of all on a rental. We do not try to be the cheapest. We return more valid fields per record (per-contact source URL and depth, contact people, wider social coverage, company and address), run HTTP-only so a large list finishes faster, and never charge for an empty or failed run, so the cost per usable contact is lower even when the sticker price per record is higher.

### Quickstart

Open the actor, paste this into the input, and press Run. It enriches two websites, scanning up to 6 pages each.

```json
{
  "maxWebsites": 10,
  "websites": ["stripe.com", "apify.com"],
  "maxPagesPerSite": 6
}
```

Enter each website as a bare domain or a full URL. Every input field is optional except that at least one website must be provided.

### Input reference

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `websites` | string\[] | yes\* | `["stripe.com", "apify.com"]` | One or more company websites to enrich. Enter a domain (`example.com`) or a full URL. Each website returns one contact record. |
| `startUrls` | object\[] | no | (empty) | Same as `websites`, in Apify start-URL format (`{"url": "https://example.com"}`). Merged with `websites`. |
| `domain` | string | no | (empty) | A single domain to enrich, in addition to or instead of the list above. |
| `paths` | string\[] | no | (empty) | Extra paths visited on every website, for example `/contact`, `/about-us`. |
| `maxWebsites` | integer | no | `10` | Maximum number of websites to enrich in this run. |
| `maxPagesPerSite` | integer | no | `6` | Pages to read per website (homepage plus likely contact, about, and team pages). Range 1 to 30. Aliases: `maxPagesPerDomain`, `maxCrawlPages`. |
| `maxDepth` | integer | no | `1` | Link-hops to follow within a site. 0 = homepage only, 1 = homepage plus its linked contact/about pages, 2+ = deeper. Range 0 to 4. |
| `sameDomainOnly` | boolean | no | `true` | Only crawl pages on the same domain as each seed. |
| `includeSubdomains` | boolean | no | `false` | Also crawl subdomains (for example `blog.example.com`). |
| `includeUrlGlobs` | string\[] | no | (empty) | Only crawl page URLs matching these globs (supports `*` and `?`). |
| `excludeUrlGlobs` | string\[] | no | (empty) | Skip page URLs matching these globs. |
| `stopWhenContactsFound` | boolean | no | `true` | Stop crawling a site once enough contacts are found. Faster. |
| `renderJs` | boolean | no | `false` | For Cloudflare / AWS WAF pages, route the request through our browser solver. Paid plans only. |
| `withEmailVerify` | boolean | no | `false` | Paid add-on: check each email domain MX records and return a deliverability status. |
| `concurrency` | integer | no | `8` | Websites enriched in parallel. Range 1 to 10. |
| `dryRun` | boolean | no | `false` | Parse and return records without charging the result event. |

\*At least one website (via `websites`, `startUrls`, or `domain`) must be provided.

### Output reference

One dataset item per website. Types: `string`, `string[]`, `object`, or `null` when the value is absent.

| Field | Type | Description |
|---|---|---|
| `website` | string | Normalized site origin, for example `https://stripe.com`. |
| `originalStartUrl` | string | The website/URL exactly as provided in the input. |
| `domain` | string | Bare domain with `www.` stripped. |
| `companyName` | string | Company name from page metadata, or `null`. |
| `description` | string | Short company description from meta tags (up to 400 characters), or `null`. |
| `emails` | string\[] | Validated public business emails (up to 50). Empty array when none found. |
| `phones` | string\[] | Phone numbers from `tel:` links (up to 25). Empty array when none. |
| `phonesUncertain` | string\[] | Phone-like numbers found in page text (lower confidence, up to 25). |
| `whatsapp` | string | WhatsApp click-to-chat number, or `null`. |
| `telegram` | string | Telegram profile or channel URL, or `null`. |
| `linkedin` | string | LinkedIn company or profile URL, or `null`. |
| `twitter` | string | Twitter/X profile URL, or `null`. |
| `facebook` | string | Facebook page URL, or `null`. |
| `instagram` | string | Instagram profile URL, or `null`. |
| `youtube` | string | YouTube channel URL, or `null`. |
| `tiktok` | string | TikTok profile URL, or `null`. |
| `pinterest` | string | Pinterest profile URL, or `null`. |
| `github` | string | GitHub organization or user URL, or `null`. |
| `discord` | string | Discord invite URL, or `null`. |
| `snapchat` | string | Snapchat profile URL, or `null`. |
| `threads` | string | Threads profile URL, or `null`. |
| `reddit` | string | Reddit profile or community URL, or `null`. |
| `yelp` | string | Yelp business URL, or `null`. |
| `googleBusiness` | string | Google Business / Maps profile URL, or `null`. |
| `contactName` | string | Primary contact person name from JSON-LD, or `null`. |
| `contactJobTitle` | string | Primary contact person job title, or `null`. |
| `contactPersons` | object\[] | Contact people with `name`, `jobTitle`, and `email` when published. |
| `address` | string | First postal address found, or `null`. |
| `addresses` | string\[] | Postal addresses parsed from JSON-LD (up to 10). |
| `contacts` | object\[] | Every email and phone with the `sourceUrl` and `depth` it was found on. |
| `contactPageUrls` | string\[] | Scanned pages identified as contact pages. |
| `aboutPageUrls` | string\[] | Scanned pages identified as about/team pages. |
| `foundContactDetails` | boolean | True when any email, phone, WhatsApp, or main social was found. |
| `sourceUrl` | string | Page URL where the primary contact was found. |
| `pagesScanned` | string\[] | The exact page URLs the actor read for this website. |
| `pagesFailed` | integer | Number of pages that could not be fetched. |
| `emailVerification` | object\[] | Per-email MX deliverability results (only with the `withEmailVerify` add-on), else `null`. |
| `source` | string | Data source label: `Website Contacts`. |
| `observedAt` | string | ISO 8601 timestamp of when the record was collected. |
| `error` | string | Present only when a website could not be fetched. |

### Example output record

See the hero example at the top of this page. It is a real record from a live run with input `{"maxWebsites": 10, "websites": ["stripe.com", "apify.com"], "maxPagesPerSite": 6}`, with the `addresses` and `pagesScanned` arrays trimmed for readability. A live run returns every address found and the full list of scanned pages.

### Run via API and CLI

Start a run and wait for it to finish, then read the dataset. Replace `<TOKEN>` with your Apify API token.

Run synchronously and get dataset items in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~website-contacts-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"websites":["stripe.com","apify.com"],"maxPagesPerSite":6}'
```

Start a run asynchronously:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~website-contacts-scraper/runs?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"websites":["acme.com","globex.com","initech.com"],"maxWebsites":50}'
```

Apify CLI:

```bash
apify call scrapers_lat/website-contacts-scraper \
  --input '{"domain":"stripe.com","maxPagesPerSite":10}'
```

### Fetch results

Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing `format`:

```bash
## JSON
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"

## CSV
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"

## Paginate large datasets
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"
```

`<DATASET_ID>` is returned as `defaultDatasetId` in the run object. Use `offset` and `limit` to page through large result sets. `clean=true` drops empty and internal fields.

### Billing and limits

- **Pay per result.** You are charged per website record returned (`result` event). See the [pricing tab](https://apify.com/scrapers_lat/website-contacts-scraper/pricing) for the current per-result price.
- **Optional email verification add-on.** Turn on `withEmailVerify` (paid plans) to check each email domain MX records. Charged per record only when at least one email is verified, never on failure.
- **No charge on failure.** If a website cannot be fetched, the record is written with a populated `error` field. Empty runs cost nothing.
- **Spend cap respected.** Set `maxTotalChargeUsd` on the run; once reached, the actor stops emitting and charging further billable results.
- **Free Apify plans** are capped at 10 websites per run, and paid add-ons (`withEmailVerify`, `renderJs`) are disabled. Upgrade for higher `maxWebsites` and add-ons.

### FAQ and troubleshooting

**Which pages does it read?**
The homepage plus likely contact, about, and team pages (up to `maxPagesPerSite`). The exact URLs read are listed in `pagesScanned` on each record.

**How are emails validated?**
Emails are matched from `mailto:` links and page text, then filtered to remove placeholders (`example.com`, `yourdomain`), asset filenames, and tracking noise, so you only get real business addresses.

**Why are some fields null or empty?**
The website did not publish that contact publicly on the pages scanned. Missing values are returned as `null` or empty arrays, never invented. Raise `maxPagesPerSite` to search more pages.

**Can I enrich many domains at once?**
Yes. Pass an array of domains in `websites` (each returns one record) and raise `maxWebsites`.

**What happens if my run gets close to its timeout?**
Each website has its own time budget, so one slow or unreachable site cannot stall the run. If the run gets close to its timeout, the actor stops starting new websites, finishes cleanly and lists the websites it did not process in the run's key-value store under `UNPROCESSED_WEBSITES`. Those websites are not charged; re-run them or raise the run timeout.

**Is this an official tool of the websites scraped?**
No. This actor is independent and reads only data that is publicly available on each website. Use it in accordance with each site's terms of service and applicable law.

### Related scrapers

- [Website Tech Stack Scraper](https://apify.com/scrapers_lat/website-tech-stack-scraper): Detect the technologies a website runs on.
- [Contact Enrichment Tool](https://apify.com/scrapers_lat/contact-enrichment-tool): Enrich a contact from a name and company domain.
- [Email Finder & Enrichment Tool](https://apify.com/scrapers_lat/email-finder-enrichment-tool): Find and verify a person's work email.
- [Google Maps Business Leads Scraper](https://apify.com/scrapers_lat/google-maps-business-leads-scraper): Local business leads with contacts from Google Maps.
- [Company Research & Enrichment Tool](https://apify.com/scrapers_lat/company-research-enrichment-tool): Firmographics and enrichment for any company domain.

### More scrapers at scrapers.lat

Built and maintained by [scrapers.lat](https://scrapers.lat), where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at [scrapers.lat](https://scrapers.lat).

***

> Independent tool. Reads only data that is publicly available on each website. Use in accordance with each site's terms of service and applicable law.

# Actor input Schema

## `websites` (type: `array`):

One or more company websites to enrich. Enter a domain (example.com) or a full URL. Each website returns one contact record.

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

Same as Websites, in Apify start-URL format. Accepts a list of {"url": "https://example.com"} objects. Merged with the Websites list.

## `domain` (type: `string`):

Optional. A single domain to enrich, in addition to (or instead of) the list above.

## `paths` (type: `array`):

Optional. Extra paths to visit on every website, e.g. /contact, /about-us. Applied to each domain in addition to the pages discovered automatically.

## `maxWebsites` (type: `integer`):

Maximum number of websites to enrich in this run.

## `maxPagesPerSite` (type: `integer`):

How many pages to read per website (homepage plus likely contact / about / team pages). Higher finds more contacts but is slower.

## `maxDepth` (type: `integer`):

How many link-hops deep to follow within the same website. 0 = homepage only, 1 = homepage plus its linked contact/about pages, 2+ = follow deeper. Contact and about pages are always prioritized.

## `sameDomainOnly` (type: `boolean`):

Only crawl pages on the same domain as each seed website. Default true.

## `includeSubdomains` (type: `boolean`):

Also crawl subdomains of the seed website (for example blog.example.com). Default false.

## `includeUrlGlobs` (type: `array`):

Optional. Only crawl page URLs matching one of these glob patterns (supports \* and ?), e.g. https://example.com/team/\*. Leave empty to crawl all discovered pages.

## `excludeUrlGlobs` (type: `array`):

Optional. Skip page URLs matching one of these glob patterns, e.g. */blog/*, */careers/*.

## `stopWhenContactsFound` (type: `boolean`):

Stop crawling a website as soon as enough contacts (emails plus a social profile) are found. Faster; turn off to always crawl up to the page limit. Default true.

## `renderJs` (type: `boolean`):

For pages protected by Cloudflare or AWS WAF, route the request through our browser solver so JavaScript-rendered contacts are captured. Available on paid Apify plans. Default false.

## `withEmailVerify` (type: `boolean`):

Optional add-on (paid plans). For every email found, check the domain MX records and return a deliverability status. Charged per record only when at least one email is checked. Default false.

## `concurrency` (type: `integer`):

How many websites to enrich in parallel. Higher is faster. Default 8.

## `dryRun` (type: `boolean`):

Parse and return records without charging the result event. Useful for testing input coverage. Default false.

## Actor input object example

```json
{
  "websites": [
    "stripe.com",
    "apify.com"
  ],
  "maxWebsites": 10,
  "maxPagesPerSite": 6,
  "maxDepth": 1,
  "sameDomainOnly": true,
  "includeSubdomains": false,
  "stopWhenContactsFound": true,
  "renderJs": false,
  "withEmailVerify": false,
  "concurrency": 8,
  "dryRun": 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 = {
    "websites": [
        "stripe.com",
        "apify.com"
    ],
    "maxWebsites": 10,
    "maxPagesPerSite": 6,
    "maxDepth": 1,
    "concurrency": 8
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/website-contacts-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 = {
    "websites": [
        "stripe.com",
        "apify.com",
    ],
    "maxWebsites": 10,
    "maxPagesPerSite": 6,
    "maxDepth": 1,
    "concurrency": 8,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/website-contacts-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "websites": [
    "stripe.com",
    "apify.com"
  ],
  "maxWebsites": 10,
  "maxPagesPerSite": 6,
  "maxDepth": 1,
  "concurrency": 8
}' |
apify call scrapers_lat/website-contacts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers_lat/website-contacts-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Hku49wXUWZptNNDaf/builds/oPFmCIETZvc40KFm1/openapi.json
