# Contact Details Scraper & Company Enrichment from Domain (`rs-automation-labs/contact-details-company-enrichment`) Actor

Contact details scraper and company enrichment from a domain: e-mails, phones, social profiles, address, company name, industry, tech stack, e-mail provider (MX/SPF/DMARC) and hiring with open job counts. Public website data, no login or API key. Priced per company, errors free.

- **URL**: https://apify.com/rs-automation-labs/contact-details-company-enrichment.md
- **Developed by:** [RS Automation Labs](https://apify.com/rs-automation-labs) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 companies

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

Paste a list of **domains or website URLs** and get one clean row per company: **e-mails, phone numbers, social profiles** (LinkedIn, X, Facebook, Instagram, YouTube, TikTok ...), contact page, HQ address, company name, description, industry, **tech stack**, **e-mail provider (MX/SPF/DMARC)**, hiring status with open job counts, languages, founded year, VAT ID and logo.

You pay **per company, not per crawled page**, and **errors are free**. No login, no API key, no AI tokens: every value comes from public sources (the company's own website, schema.org / JSON-LD, meta tags, public DNS, the sitemap and public job-board APIs). LinkedIn is never scraped and e-mails are never guessed.

### What does Contact Details Scraper & Company Enrichment do?

For every domain you give it, the Actor:

1. **Checks DNS** (MX, SPF, DMARC, NS, TXT). Dead domains become a free `DOMAIN_NOT_FOUND` row, and you see the **e-mail provider** (Google Workspace, Microsoft 365, Zoho ...), the sending tools (HubSpot, Mailchimp, SendGrid ...) and the DNS host.
2. **Reads the homepage** and up to 5 key pages: **contact, about, imprint / Impressum, careers**. It finds them from the site's own links in 20+ languages and respects `robots.txt`.
3. **Extracts contacts**: e-mails (including Cloudflare-obfuscated and `name [at] domain [dot] com` forms), `tel:` links and phone numbers near a phone label, normalised to **E.164**, plus 18 social networks.
4. **Extracts firmographics** from schema.org Organization data, meta tags and page text: name, legal name, description, address, VAT ID, founded year, employees, logo and languages.
5. **Fingerprints ~150 technologies**: CMS, e-commerce, analytics, tag managers, CDN, chat, CRM, marketing automation, frameworks, payments and more.
6. **Detects hiring**: careers page, applicant tracking system (Greenhouse, Lever, Ashby, Workable, Personio, Recruitee and 20 more) and **open job counts** from their public APIs.

### Who is it for?

- **Lead generation & cold outreach**: turn a list of websites (for example from Google Maps, a directory or a trade-show list) into e-mails, phones and social links.
- **Sales & SDR teams**: add the LinkedIn page, country and tech stack to every account before outreach.
- **RevOps / CRM admins**: fill empty company fields in HubSpot, Salesforce or Pipedrive from the domain alone.
- **Marketers & agencies**: segment accounts by technology (Shopify vs WooCommerce, HubSpot vs Marketo) or e-mail provider.
- **Investors & analysts**: screen companies by hiring activity, founding year, languages and site size.

### Why this Actor?

- **Per company, not per page.** One flat price per enriched domain. Contact scrapers that bill per crawled page (plus extra per lead or per social profile) cost 3-10x more and are hard to predict.
- **Errors are free.** Invalid, non-existent, parked, blocked and JavaScript-only domains come back as free error rows with a code and a hint. Duplicate domains in your list are enriched once and charged once.
- **More than contacts.** Tech stack, e-mail provider, DMARC, hiring and open jobs, VAT ID, founded year and address come in the same row at no extra cost.
- **No junk e-mails.** It drops image filenames (`logo@2x.png`), tracking addresses (sentry, wixpress), placeholders (`example.com`) and `noreply@`.
- **You choose the e-mail scope.** By default only **role mailboxes** (info@, sales@, support@, press@, kontakt@ ...) are returned. Turn on **Include named e-mails** to also get addresses of named people that the company itself publishes (for example on a team or imprint page).
- **One row per company.** A wide, stable schema that is ready for CSV/Excel or CRM import.
- **Fast and light.** Around 4 pages per domain at 256 MB memory; 12 small-business sites took 7 seconds in our test.

### How to use it

1. Paste domains, website URLs or business e-mails into **Domains or websites**. Whole columns work; duplicates are removed.
2. Optional: turn on **Include named e-mails**, or switch off DNS, sitemap or job counts for an even faster run.
3. Click **Start**. Download the results as Excel, CSV or JSON, or open the **Contacts**, **Tech & DNS** or **Hiring** views.

### Input example

```json
{
  "domains": ["plausible.io", "https://www.hetzner.com/en/", "info@zalando.de", "stumptowncoffee.com"],
  "maxPagesPerDomain": 6,
  "includePersonalEmails": false,
  "includeDns": true,
  "countOpenJobs": true
}
```

| Field | Default | What it does |
|---|---|---|
| `domains` | - | Domains, URLs or e-mails. Up to 10,000 per run. `startUrls` (`[{"url": ...}]`) is accepted too. |
| `maxPagesPerDomain` | 6 | Homepage plus key pages. The price doesn't change. |
| `includePersonalEmails` | false | Also return named e-mails published on the site in `personalEmails`. |
| `includeDns` | true | E-mail provider, SPF tools, DMARC, DNS host and verification records. |
| `includeSitemap` | true | Sitemap URL count and newest `lastmod`. |
| `countOpenJobs` | true | Open positions from public Greenhouse, Lever, Ashby, Workable, Recruitee and Personio boards. |
| `respectRobotsTxt` | true | Skip pages disallowed by robots.txt. |
| `proxyConfiguration` | Apify Proxy | Datacenter is enough for most sites. |
| `residentialFallback` | false | Retry a blocked site once via residential proxy (homepage + 2 pages). |
| `maxConcurrency` | 10 | Domains processed in parallel. |
| `pageTimeoutSecs` | 20 | Per-request timeout. |

### Output example

A real row from our test run on 2026-10-25, shortened:

```json
{
  "domain": "stumptowncoffee.com",
  "status": "ok",
  "companyName": "Stumptown Coffee Roasters",
  "description": "Stumptown Coffee Roasters brings you fresh beans, cold brew, and good vibes. Order online, visit a shop, or subscribe for the long haul.",
  "industry": "E-commerce & Retail",
  "country": "US",
  "address": "700 SW 5th Ave, 3rd Floor, #400, 97214 Portland, OR",
  "phones": [
    "+18557113385"
  ],
  "emails": [
    "jobs@stumptowncoffee.com",
    "info@stumptowncoffee.com"
  ],
  "personalEmails": null,
  "otherEmailsSkipped": 0,
  "contactUrl": "https://support.stumptowncoffee.com/hc/en-us/articles/17928599681933-Stumptown-Customer-Support",
  "instagramUrl": "https://www.instagram.com/stumptowncoffee",
  "facebookUrl": "https://www.facebook.com/stumptowncoffee",
  "linkedinUrl": null,
  "techStack": [
    "Cloudflare",
    "Contentful",
    "Google Analytics",
    "Google Fonts",
    "Google Tag Manager",
    "Shopify",
    "Zendesk"
  ],
  "emailProvider": "Google Workspace",
  "dmarcPolicy": "none",
  "isHiring": true,
  "hiringSignal": "ats",
  "careersUrl": "https://www.stumptowncoffee.com/pages/jobs",
  "atsProvider": "Workday",
  "openJobs": null,
  "languages": [
    "en"
  ],
  "logoUrl": "https://customers.seomanager.com/knowledgegraph/logo/stumptowncoffee_myshopify_com_logo.png",
  "sitemapUrlCount": null
}
```

#### Main fields

| Group | Fields |
|---|---|
| Identity | `companyName`, `legalName`, `description`, `industry` (+ confidence & source), `logoUrl`, `faviconUrl`, `foundedYear`, `employees`, `vatId` |
| Location | `address`, `addressParts` (street, postal code, city, region, country), `country` (ISO-2) + `countrySource` |
| Contacts | `emails` (role mailboxes), `personalEmails` (named e-mails, opt-in), `phones` (E.164), `contactUrl`, `aboutUrl` |
| Social | `linkedinUrl`, `xUrl`, `facebookUrl`, `instagramUrl`, `youtubeUrl`, `tiktokUrl`, `githubUrl`, `socialLinks` (Xing, Crunchbase, Trustpilot, Discord ...) |
| Tech & DNS | `techStack`, `techCategories`, `emailProvider`, `mxRecords`, `emailServices`, `dmarcPolicy`, `dnsProvider`, `verifiedServices` |
| Hiring | `isHiring`, `hiringSignal`, `careersUrl`, `atsProvider`, `openJobs` |
| Site | `languages`, `title`, `keywords`, `schemaTypes`, `sitemapUrlCount`, `sitemapLastModified`, `pagesCrawled`, `httpStatus`, `redirectedTo`, `responseTimeMs` |
| Errors | `errorCode`, `errorMessage`, `errorHint` |

The run summary (key-value store record `OUTPUT`) shows the **fill rate of every field**, the error codes and the charged events.

#### Fill rates in our tests

From tests on 2026-10-25 with real company websites (SaaS, restaurants, bakeries, retailers, law firms, hospitals) (30 domains, 8 countries):

| Field | Filled | Field | Filled |
|---|---|---|---|
| Company name | 100% | YouTube | 67% |
| Description | 100% | Tech stack | 100% |
| Industry | 97% | E-mail provider | 100% |
| Country | 53% | Hiring signal | 97% |
| Address | 47% | Careers page | 77% |
| Phones | 33% | Open job count | 20% |
| Role e-mails | 63% | Languages | 100% |
| LinkedIn page | 53% | Founded year | 47% |
| X / Twitter | 73% | Logo | 90% |
| Facebook | 87% | VAT ID | 20% |
| Instagram | 87% | Sitemap size | 90% |

These numbers reflect what companies publish. Many large US brands publish no e-mail or address at all, while EU sites usually have a complete imprint.

#### Error codes (all free)

| Code | Meaning |
|---|---|
| `INVALID_INPUT` | Not a domain / URL. |
| `DUPLICATE_INPUT` | Same domain earlier in the list; it was enriched once. |
| `DOMAIN_NOT_FOUND` | The domain doesn't exist (NXDOMAIN). |
| `SITE_UNREACHABLE` | DNS exists but no website answers. DNS fields such as the e-mail provider are still filled. |
| `PARKED_DOMAIN` | "This domain is for sale" pages. |
| `BLOCKED` | Bot protection (or still blocked after the optional residential retry). DNS fields are still filled. |
| `ROBOTS_DISALLOWED` | robots.txt forbids the homepage. |
| `EMPTY_PAGE` | JavaScript-only site with no server-rendered content. |
| `NOT_HTML`, `NETWORK_ERROR`, `TIMEOUT`, `BUDGET_LIMIT`, `INTERNAL_ERROR` | See `errorHint`. |

### How much does it cost?

Pay per event. There is **no start fee**, and **error rows are free**:

| Event | Price | When |
|---|---|---|
| Company | $0.004 | One domain enriched from its website (`status: ok`). Errors and duplicates are free. |

1,000 enriched domains cost **$4**, whatever the size of each site and whether you want named e-mails or not. Set **Maximum cost per run** and the Actor stops cleanly at your budget.

### Use it via API, Python, JavaScript or an AI agent

Every run is available through the [Apify API](https://docs.apify.com/api/v2). Start a run, wait for it to finish and read the dataset in a few lines of Python with the official [`apify-client`](https://docs.apify.com/api/client/python) package:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("rs-automation-labs/contact-details-company-enrichment").call(run_input={
        "domains": [
            "apify.com",
            "zalando.de",
            "basecamp.com"
        ]
    })
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

- **JavaScript / cURL:** the **API** tab on this page has ready-to-copy snippets with your token filled in.
- **Schedules and webhooks:** run it daily or weekly with [Apify Schedules](https://docs.apify.com/platform/schedules) and get notified with [webhooks](https://docs.apify.com/platform/integrations/webhooks).
- **No-code:** connect it to Make, Zapier, n8n, Google Sheets or Slack through [Apify integrations](https://apify.com/integrations).
- **AI agents:** call it from Claude, ChatGPT, Cursor or any MCP client through the [Apify MCP server](https://mcp.apify.com).

### FAQ

**Do you scrape LinkedIn?** No. The LinkedIn company page URL is taken from the company's own website, and LinkedIn itself is never requested.

**Do you find personal e-mail addresses?** Only if you turn on **Include named e-mails**, and only addresses the company itself publishes on its website. Patterns like first.last@ are never guessed. With the option off (default), only role mailboxes (info@, sales@, press@ ...) are returned, which keeps the data GDPR-friendly for B2B use.

**What about sites behind a login or a cookie wall?** Nothing behind a login is accessed. Cookie banners don't matter because the Actor reads the server-rendered HTML.

**Why is a field empty?** The company didn't publish it, or the site renders it only with JavaScript. The `pagesCrawled` field shows exactly what was read.

**Do I need an API key, login or AI credits?** No. It only reads public web pages and DNS.

**Can I use it via API / Make / Zapier / n8n?** Yes. It works like any Apify Actor: run it synchronously, then read the dataset.

**Is it legal?** It reads public business information that companies publish about themselves. You are responsible for how you use contact data, for example for marketing consent.

### Limitations

- No JavaScript rendering. Single-page apps still give meta tags, JSON-LD, DNS and tech, but often no contacts.
- Geo or language redirects return the version the site serves to the proxy location. For example, razorpay.com served its US site.
- `industry` is a keyword and schema.org heuristic, so treat it as a hint.
- Very large or bot-protected sites (Amazon, Klarna, some marketplaces) may end as free `BLOCKED` / `EMPTY_PAGE` rows.

### Other Actors by RS Automation Labs

| Actor | What it does |
|---|---|
| [PageSpeed Insights Bulk Checker](https://apify.com/rs-automation-labs/bulk-pagespeed-core-web-vitals-monitor) | Bulk Lighthouse scores and real-user Core Web Vitals for many URLs or a sitemap |
| [Video Transcript & AI Summary](https://apify.com/rs-automation-labs/video-transcripts-ai-summaries) | Transcripts, subtitles and AI summaries for YouTube, TikTok, Reels, X and podcasts |
| [AI PDF to JSON & Invoice OCR](https://apify.com/rs-automation-labs/ai-document-extractor) | Invoices, receipts, bank statements and any PDF or scan to validated JSON, CSV and Excel |
| [AI Search Visibility & GEO Rank Tracker](https://apify.com/rs-automation-labs/ai-search-visibility-checker) | Whether ChatGPT, Perplexity, Gemini, Claude, Grok and AI Overviews mention and cite your brand |
| [Career Site Jobs Scraper](https://apify.com/rs-automation-labs/career-site-jobs-scraper) | Every open job from company career sites and ATS boards (Greenhouse, Lever, Workday ...) |

### Support

Found a wrong value? Open an issue with the domain and the field. We fix extraction bugs quickly. Feature requests (new ATS, technologies, fields) are welcome.

# Changelog

This Actor's version history is a separate document: https://apify.com/rs-automation-labs/contact-details-company-enrichment/changelog.md

# Actor input Schema

## `domains` (type: `array`):

Company domains (apify.com), website URLs (https://www.apify.com/about) or even business e-mails (the domain is used). One row per unique domain, up to 10,000 per run.

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

Homepage plus key pages (contact, about, imprint, careers). Price is per company, not per page.

## `includePersonalEmails` (type: `boolean`):

Off (default): only role / department mailboxes (info@, sales@, support@, press@ ...). On: also e-mails of named people that the company itself publishes on its website (e.g. jane.doe@company.com on the team page). Addresses are only ever copied from the site, never guessed. You are responsible for using personal data lawfully (GDPR / CAN-SPAM).

## `includeDns` (type: `boolean`):

MX, SPF, DMARC, NS and verification TXT records (e-mail provider, sending tools, DNS host).

## `includeSitemap` (type: `boolean`):

Count sitemap URLs and the newest lastmod (site size and freshness).

## `countOpenJobs` (type: `boolean`):

Read public job boards (Greenhouse, Lever, Ashby, Workable, Recruitee, Personio) for the number of open positions.

## `respectRobotsTxt` (type: `boolean`):

Skip pages disallowed by robots.txt (domain becomes a free ROBOTS_DISALLOWED row).

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

Datacenter proxy is enough for most sites.

## `residentialFallback` (type: `boolean`):

Off by default. When on, a site that blocks the datacenter proxy is retried once through Apify residential proxy (homepage + 2 key pages). Blocked sites stay free either way.

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

How many domains are processed at the same time.

## `pageTimeoutSecs` (type: `integer`):

How long to wait for one page of a company website before giving up on it and moving on. Raise it for very slow sites.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "zalando.de",
    "basecamp.com"
  ],
  "maxPagesPerDomain": 6,
  "includePersonalEmails": false,
  "includeDns": true,
  "includeSitemap": true,
  "countOpenJobs": true,
  "respectRobotsTxt": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": false,
  "maxConcurrency": 10,
  "pageTimeoutSecs": 20
}
```

# Actor output Schema

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

One row per company.

## `contacts` (type: `string`):

Published business contacts and social profiles.

## `tech` (type: `string`):

Technologies, e-mail provider and DNS signals.

## `hiring` (type: `string`):

Careers page, ATS and open job counts.

## `errors` (type: `string`):

Domains that could not be enriched, with the reason (not charged).

## `data` (type: `string`):

Every field of every row.

## `summary` (type: `string`):

Counts, error codes, per-field fill rates and charges.

# 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 = {
    "domains": [
        "apify.com",
        "zalando.de",
        "basecamp.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rs-automation-labs/contact-details-company-enrichment").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 = {
    "domains": [
        "apify.com",
        "zalando.de",
        "basecamp.com",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("rs-automation-labs/contact-details-company-enrichment").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 '{
  "domains": [
    "apify.com",
    "zalando.de",
    "basecamp.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call rs-automation-labs/contact-details-company-enrichment --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rs-automation-labs/contact-details-company-enrichment"
        }
    }
}
```

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/yWDzPGmzHA4NKsUAN/builds/Z3uiMzg7hcflabo8I/openapi.json
