# Website Intelligence + Contact Extractor (`kondasviktor/website-intelligence-contact-extractor`) Actor

Enrich company websites with emails, phones, social links, tech stack, and EU compliance signals. Optional BYOK AI business classification. Works standalone or after Google Maps CEE Supplier Shortlist Builder.

- **URL**: https://apify.com/kondasviktor/website-intelligence-contact-extractor.md
- **Developed by:** [Viktor Kondas](https://apify.com/kondasviktor) (community)
- **Categories:** Lead generation, Automation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 website record saveds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Website Intelligence + Contact Extractor

**Extract emails, phones, social links, tech stack, and EU compliance signals from company websites** — then optionally classify with BYOK AI.

Standalone Apify actor. Works with any public website list worldwide. Pairs well with the [Google Maps CEE Scraper — Supplier Shortlist](https://apify.com/kondasviktor/google-maps-cee-scraper) `website` field, but does **not** require it.

**Optional next step after Maps:** feed shortlist `website` URLs into this actor for emails, phones, tech stack, and EU compliance flags.

### What it does

- Fetches the homepage over HTTP (browser fallback + residential proxy for bot-walled sites).
- Crawls a small set of high-value pages (contact, about, imprint, privacy, careers).
- Returns structured JSON/CSV/Excel with contacts, social profiles, tech signals, and compliance flags.
- Extracts:
  - **Contacts:** emails, phones, LinkedIn/Facebook/X/Instagram/YouTube/WhatsApp, contact form URL
  - **IDs:** EU VAT heuristics, HU tax ID / PL NIP patterns when present
  - **Tech:** CMS, shop, analytics, chat, booking, CRM, tag managers, cookie tools
  - **Compliance flags:** cookie banner, privacy, imprint/impresszum, terms/ÁSZF, careers, newsletter
  - **Languages:** `html lang` + hreflang
- Optional **multi-provider AI enrichment** (BYOK): Gemini, Claude, ChatGPT, or OpenRouter.
- Built for **n8n**, **Make**, **Zapier**, and vibe-coder agent workflows.

### Who it's for

1. **Sales teams** enriching SME lead lists after Maps or CRM exports.
2. **Procurement teams** checking supplier website hygiene before outreach.
3. **Agencies** running batch website intelligence for clients.
4. **Vibe coders** powering enrichment steps in n8n / Make / Zapier / Apify.
5. **Market researchers** auditing contactability and tech stack across a domain list.

### What this actor is — and is not

This actor helps you **extract public website signals** useful for outreach and shortlist prep. It does **not** verify legal entity status, GDPR compliance quality, insurance, certifications, or formal vendor approval.

Use the output for:

- contact discovery
- tech / stack fingerprinting
- EU-style page hygiene checks (privacy, impresszum, terms)
- enrichment after Google Maps or CRM exports

Do **not** use it as the sole basis for KYB, contract award, or formal vendor qualification.

### What data you get

| Field | Description |
|-------|-------------|
| `website`, `domain`, `finalUrl` | Input URL, normalized domain, final resolved URL |
| `statusCode`, `pagesCrawled` | HTTP status and pages successfully fetched |
| `emails`, `phones` | Contact channels found on crawled pages |
| `linkedin`, `facebook`, `twitter`, `instagram`, `youtube`, `whatsapp` | Social profile URLs (posts/embeds filtered out) |
| `contactFormUrl` | Detected contact form page when present |
| `vatNumbers`, `taxIds` | EU VAT / local tax ID heuristics when present |
| `cms`, `shop`, `analytics`, `chat`, `booking`, `crm`, `tagManagers`, `cookies`, `otherTech` | Tech stack signals |
| `hasPrivacyPage`, `hasImprintPage`, `hasTermsPage`, `hasCareerPage`, `hasCookieBanner`, `hasNewsletter` | Compliance / page flags |
| `privacyPageUrl`, `imprintPageUrl`, `termsPageUrl`, `careerPageUrl`, `contactPageUrls` | Matched page URLs |
| `languages` | Detected language codes |
| `aiBusinessType`, `aiSummary` | When AI enrichment is enabled |
| `error` | Set when the site could not be fetched usefully |

### How to use it

1. **Configure input** — website list, max pages, concurrency, proxy.
2. **Run** on Apify cloud (recommended) or locally with `apify run`.
3. **Download** dataset as JSON, CSV, or Excel from the run page.

### Input presets

#### Enrich company websites (Store example)

```json
{
  "websites": [
    "https://www.vibecoderslife.com",
    "https://www.projectisconsulting.com"
  ],
  "maxPagesPerSite": 6,
  "concurrency": 2,
  "enableAIEnrichment": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

Published Store example: [Enrich company websites — contacts & tech stack](https://apify.com/kondasviktor/website-intelligence-contact-extractor/examples/enrich-company-websites-with-contacts-tech-stack).

#### After Google Maps shortlist

```json
{
  "websites": [
    "https://example-clinic.hu",
    "https://example-supplier.ro"
  ],
  "maxPagesPerSite": 6,
  "concurrency": 3,
  "enableAIEnrichment": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

Pipe `website` values from [Google Maps CEE Scraper — Supplier Shortlist](https://apify.com/kondasviktor/google-maps-cee-scraper) into this list.

#### With optional BYOK AI enrichment

```json
{
  "websites": [
    "https://www.vibecoderslife.com",
    "https://www.projectisconsulting.com"
  ],
  "maxPagesPerSite": 6,
  "enableAIEnrichment": true,
  "aiProvider": "openrouter",
  "openrouterApiKey": "YOUR_KEY",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Output example

```json
{
  "website": "https://www.projectisconsulting.com",
  "domain": "projectisconsulting.com",
  "finalUrl": "https://www.projectisconsulting.com/",
  "statusCode": 200,
  "pagesCrawled": 2,
  "emails": ["mariann@projectisconsulting.com"],
  "phones": [],
  "linkedin": ["https://www.linkedin.com/in/mariann-vamosi"],
  "facebook": [],
  "twitter": [],
  "instagram": [],
  "youtube": [],
  "whatsapp": [],
  "contactFormUrl": null,
  "vatNumbers": [],
  "taxIds": [],
  "languages": ["en", "hu"],
  "cms": ["Wix"],
  "analytics": ["GA4", "Google Analytics"],
  "hasCookieBanner": false,
  "hasPrivacyPage": true,
  "hasImprintPage": false,
  "hasTermsPage": false,
  "privacyPageUrl": "https://www.projectisconsulting.com/adatvedelem",
  "scrapedAt": "2026-07-16T15:54:29.848Z",
  "error": null,
  "aiBusinessType": null,
  "aiSummary": null
}
```

### AI enrichment (BYOK — bring your own key)

Scraping and contact/tech extraction work **without any LLM key**. AI is optional and classifies **only the public evidence collected**.

When `enableAIEnrichment` is true, choose **`aiProvider`** and paste your API key:

| Provider | Input key field | Get key |
|----------|-----------------|---------|
| **Gemini** (default in auto) | `geminiApiKey` | [Google AI Studio](https://aistudio.google.com/app/apikey) |
| **Claude** | `anthropicApiKey` | [Anthropic Console](https://console.anthropic.com/) |
| **ChatGPT** | `openaiApiKey` | [OpenAI API keys](https://platform.openai.com/api-keys) |
| **OpenRouter** | `openrouterApiKey` | [OpenRouter](https://openrouter.ai/keys) |
| **auto** | First available key above | Tries Gemini → Claude → OpenAI → OpenRouter |

**OpenRouter model:** override with `aiModel` when needed.

### Proxy and blocked sites

| Feature | Support |
|---------|---------|
| **Apify Proxy RESIDENTIAL** | Recommended default for Cloudflare / Vercel / enterprise walls |
| **Browser fallback** | Retries with rotating residential sessions when HTTP is challenged |
| **Plain HTTP sites** | Work without a browser on most SME sites |

If a run shows `HTTP 429` / bot challenge in `error`, confirm Proxy is **Apify Proxy + RESIDENTIAL** and re-run. The Console message “URL isn’t accessible” after a finished run usually refers to the temporary container URL — check the **Dataset** `error` field instead.

**Recommended demo run:**

```json
{
  "websites": [
    "https://www.vibecoderslife.com",
    "https://www.projectisconsulting.com"
  ],
  "maxPagesPerSite": 6,
  "concurrency": 2,
  "enableAIEnrichment": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Secrets and local development

- **Never commit** `apify/website-intelligence-contact-extractor/.env` — it is listed in `.gitignore`.
- **`apify push` excludes** `.env` via `.gitignore` and `.actorignore`.
- **Docker builds exclude** `.env` via `.dockerignore`.
- On Apify cloud, customers paste keys into **input fields** (`openrouterApiKey`, etc.) marked as secrets — not from your local `.env`.
- For local runs only, copy `.env.example` → `.env` and add optional BYOK keys (`GEMINI_API_KEY`, etc.).
- Only `.env.example` (placeholders, no real keys) is in git.

### FAQ

**How is this different from a generic email scraper?**\
This actor returns **one enriched domain record** with contacts, social profiles, tech stack, and EU-style compliance page flags — not a raw email dump.

**Does it work outside CEE?**\
Yes. Marketing ICP is CEE/Europe; the scanner works on public websites worldwide.

**What is AI enrichment and does it cost extra on Apify?**\
AI enrichment is optional and **BYOK**. You pay your LLM provider directly. The actor’s Apify fee is per saved website record. Extraction works with zero LLM keys.

**How do I extract emails and phones from a website?**\
Pass homepage URLs in `websites`. The Actor crawls contact/about/imprint pages and returns emails, phones, social links, tech stack, and compliance flags in one row per domain.

### Local development

```bash
cd apify/website-intelligence-contact-extractor
npm install
npm test
npm run build
apify run --input-file=INPUT.smoke-mix.json
```

### Pricing

Pay-per-event: **$3.50 per 1,000 website records** (`website` event @ `$0.0035`), minimum charge **$0.10** per run.

Enable **Pay per event + usage** in Apify Console so platform compute/proxy costs are passed through to users.

AI enrichment does not add an Apify AI event fee.

### Related actors (suite)

| Actor | Role |
|-------|------|
| [Google Maps CEE Scraper — Supplier Shortlist](https://apify.com/kondasviktor/google-maps-cee-scraper) | Discover local suppliers |
| **Website Intelligence + Contact Extractor** (this Actor) | Enrich websites (contacts, tech, compliance) |
| [Dealer / Distributor Locator Extractor](https://apify.com/kondasviktor/dealer-distributor-locator) | Expand brand locator pages |
| [PDF Procurement Document Extractor](https://apify.com/kondasviktor/pdf-procurement-document-extractor) | Find certs / reports / datasheets |
| [Website Change Monitor — Diff Tracker](https://apify.com/kondasviktor/website-change-monitor) | Watch pages for changes |
| [European Fuel Station Prices API (CEE + DACH)](https://apify.com/kondasviktor/cee-dach-fuel-intelligence) | CEE + DACH station fuel prices |

Each Actor runs standalone; use them as an optional suite when chaining discovery → enrichment → monitoring → fuel intelligence.

### Feedback

Open an issue on the actor’s Apify page or contact [Vibe Coder's Life](https://vibecoderslife.com/#contact).

# Actor input Schema

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

Company website URLs to enrich (homepage or any page on the domain). Works with Maps actor `website` fields or any public URL list. Demo: vibecoderslife.com + projectisconsulting.com.

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

Homepage plus priority contact/about/legal/career pages. Higher finds more emails; keep low for speed.

## `requestTimeoutSecs` (type: `integer`):

HTTP timeout per page fetch.

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

How many websites to scan in parallel.

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

Use Apify Proxy for sites that block datacenter IPs (Cloudflare/Vercel challenges). Prefer RESIDENTIAL for enterprise sites like Iron Mountain.

## `enableAIEnrichment` (type: `boolean`):

Optional. Classify business type and write a one-line ICP summary. You bring your own API key — no extra Apify AI fee.

## `aiProvider` (type: `string`):

Used when AI enrichment is enabled. `auto` tries Gemini → Claude → OpenAI → OpenRouter based on available keys.

## `aiModel` (type: `string`):

Optional. Only applied when provider is OpenRouter (or auto picks OpenRouter).

## `geminiApiKey` (type: `string`):

BYOK Gemini key (or set GEMINI\_API\_KEY env).

## `anthropicApiKey` (type: `string`):

BYOK Claude key (or set ANTHROPIC\_API\_KEY env).

## `openaiApiKey` (type: `string`):

BYOK OpenAI key (or set OPENAI\_API\_KEY env).

## `openrouterApiKey` (type: `string`):

BYOK OpenRouter key (or set OPENROUTER\_API\_KEY env).

## Actor input object example

```json
{
  "websites": [
    "https://www.vibecoderslife.com",
    "https://www.projectisconsulting.com"
  ],
  "maxPagesPerSite": 6,
  "requestTimeoutSecs": 25,
  "concurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "enableAIEnrichment": false,
  "aiProvider": "auto"
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `dataset` (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": [
        "https://www.vibecoderslife.com",
        "https://www.projectisconsulting.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kondasviktor/website-intelligence-contact-extractor").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": [
        "https://www.vibecoderslife.com",
        "https://www.projectisconsulting.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("kondasviktor/website-intelligence-contact-extractor").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 '{
  "websites": [
    "https://www.vibecoderslife.com",
    "https://www.projectisconsulting.com"
  ]
}' |
apify call kondasviktor/website-intelligence-contact-extractor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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