# Company Enrichment by Domain – LinkedIn URL, Socials, Tech (`gazidev/company-enrichment`) Actor

Enrich company domains: name, legal name, country, founded year, LinkedIn URL & socials, public emails/phones, tech stack, email provider (MX), SPF/DMARC and domain age. Read from the company's own website, DNS and RDAP. Dead and parked domains are free.

- **URL**: https://apify.com/gazidev/company-enrichment.md
- **Developed by:** [Cemal Atakli](https://apify.com/gazidev) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 company enricheds

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

## Company Enrichment by Domain – LinkedIn URL, Socials, Tech

**Company enrichment API for a list of domains.** For each domain you get the **company name, legal name, description, logo, country, city, founded year, LinkedIn company URL and other social profiles, public emails and phones, tech stack (CMS, ecommerce platform, analytics, CRM), email provider from MX (Google Workspace / Microsoft 365...), SPF/DMARC and domain age**. Use it for lead-list building, CRM cleanup and firmographic data enrichment. Every value is read from the company's **own website**, public DNS and the public RDAP registry, and comes back as one clean row per company. **Dead, parked and blocked domains are free.**

- **Data from the source, not a stale database.** The Actor reads the homepage and the most useful pages (about, contact, imprint/impressum, legal) right now. Each firmographic field states where it came from (`legalNameSource`, `foundedYearSource`, `countrySource`).
- **LinkedIn company URL without touching LinkedIn.** The LinkedIn, X/Twitter, Facebook, Instagram, YouTube, TikTok, GitHub and Pinterest links are the ones the company itself publishes on its site. Share buttons and post links are ignored. LinkedIn and other networks are never fetched.
- **Tech stack** from 7,600+ open-source fingerprints (webappanalyzer, GPL-3.0): WordPress, Shopify, HubSpot, Klaviyo, Google Analytics, Stripe, Cloudflare and so on, with summary columns such as `cms`, `ecommercePlatform`, `analytics` and `crm`. Services that the company has only verified in DNS (TXT tokens for Atlassian, HubSpot, OpenAI, DocuSign...) are listed separately in `dnsVerifiedServices`.
- **Email setup from DNS:** email provider (Google Workspace, Microsoft 365, Zoho...), security gateway (Proofpoint, Mimecast...), SPF and DMARC policy, and the sending services named in SPF (HubSpot, Salesforce, Mailchimp...). This is useful for cold-email and deliverability agencies.
- **Domain age** (creation date, expiry and registrar) from RDAP.
- **Optional AI classification:** industry, sub-industry, B2B/B2C, business model and a one-line summary, made from the company's own homepage text. The fields start with `ai` so they are never confused with source data.
- **No guesses.** Headcount appears only when the site states it in schema.org. Revenue is never estimated.
- **Polite and cheap.** HTTP only (no browser), robots.txt respected (including Crawl-delay), at most 2 parallel requests per site, and an honest User-Agent.

### What can I use it for?

- **Lead-list building:** turn a list of domains from Google Maps, a trade-show list, a CRM or a scraper into rows with company name, country, LinkedIn page and contacts.
- **CRM cleanup and enrichment:** fill in missing legal names, countries, logos, LinkedIn URLs and descriptions for existing accounts.
- **Cold email and deliverability:** segment prospects by email provider (Google vs Microsoft) and by SPF/DMARC setup.
- **Technographic segmentation:** find every Shopify store, WordPress site or HubSpot user in a list.
- **Due diligence and KYB pre-checks:** check the stated legal name, address, domain age and whether the site is live or parked.
- **AI agents:** give an agent a "tell me about this company" tool (see below).

### Input

| Field | Description |
|---|---|
| `domains` | Domains or URLs (`acme.com`, `https://www.acme.de/en/`, even `jane@acme.com`). One row per company domain; duplicates are merged. |
| `bulkText` | Paste any list: one per line, comma separated, or a whole CSV export |
| `sourceFileUrl` | Public URL of a `.txt`/`.csv` file (e.g. a published Google Sheet) |
| `datasetId`, `datasetField` | Read domains from another Actor's dataset (e.g. a Google Maps scraper run) |
| `includeContacts` | Public emails (MX-checked) and phone numbers (default on) |
| `includeTechStack` | Tech stack detection (default on) |
| `includeEmailDns` | Email provider, SPF and DMARC (default on) |
| `includeDomainAge` | Domain creation date and registrar from RDAP (default on) |
| `aiClassify`, `aiModel` | Optional AI industry/B2B classification (default off) |
| `maxPagesPerSite` | Pages per website, homepage included (default 5, max 20). **The price stays the same.** |
| `maxDomains`, `maxConcurrency`, `requestTimeoutSecs`, `proxyConfiguration` | Advanced |

```json
{
  "domains": ["hawksheadrelish.com", "puccinibomboni.com", "basecamp.com"],
  "includeContacts": true,
  "includeTechStack": true,
  "includeEmailDns": true,
  "includeDomainAge": true,
  "aiClassify": false
}
```

### Output

You get one row per domain. The Output tab has three tables (**Companies**, **LinkedIn & social profiles**, **Tech stack & email**). The full JSON looks like this (real result, shortened):

```json
{
  "domain": "zapier.com",
  "websiteUrl": "https://zapier.com",
  "companyName": "Zapier",
  "legalName": "Zapier Inc",
  "legalNameSource": "schema.org legalName",
  "description": "Build and scale AI workflows and agents across 9,000+ apps with Zapier—the most connected AI orchestration platform. Trusted by 3 million+ businesses.",
  "logo": "https://res.cloudinary.com/zapier-media/image/upload/f_png,h_224/v1757453971/Zapier_Logo_yjhvbo",
  "country": "US",
  "countryName": "United States",
  "countrySource": "schema.org address",
  "city": "San Francisco",
  "address": "548 Market St. #62411, 94104, San Francisco, CA, US",
  "foundedYear": 2011,
  "foundedYearSource": "schema.org foundingDate",
  "employees": null,
  "linkedin": "https://www.linkedin.com/company/zapier",
  "twitter": "https://x.com/zapier",
  "facebook": "https://www.facebook.com/ZapierApp",
  "instagram": "https://www.instagram.com/zapier",
  "youtube": "https://www.youtube.com/user/ZapierApp",
  "github": "https://github.com/zapier",
  "emails": [],
  "phones": [],
  "emailProvider": "Google Workspace",
  "hasSpf": true,
  "spfPolicy": "fail",
  "hasDmarc": true,
  "dmarcPolicy": "reject",
  "emailSendingServices": ["Google Workspace", "Mailgun", "HubSpot", "Zendesk"],
  "domainCreatedAt": "2011-10-30T20:11:40Z",
  "domainAgeYears": 15.0,
  "registrar": "Name.com, Inc.",
  "cms": "Contentful",
  "ecommercePlatform": null,
  "hosting": ["Amazon Web Services", "Heroku", "Vercel", "Amazon Route 53"],
  "webFrameworks": ["Next.js", "React"],
  "technologyNames": ["Contentful", "Next.js", "React", "Vercel", "Amazon CloudFront", "OneTrust", "..."],
  "dnsVerifiedServices": ["Atlassian Cloud", "Zendesk", "HubSpot", "Stripe", "OpenAI", "DocuSign", "..."],
  "parked": false,
  "blocked": false,
  "charged": true,
  "error": null
}
```

The fields are `null` when the website does not publish the information. Rows with `error` set (DNS failure, HTTP error, bot protection, parked domain, no company name) are **free**. See [SAMPLE_OUTPUT.json](SAMPLE_OUTPUT.json) for complete real rows.

**Where each field comes from:**

- `companyName`: schema.org Organization, `og:site_name` or the page title
- `legalName`: schema.org `legalName`, or a name with a legal form (Ltd, GmbH, Inc, BV...) on the imprint/legal page or in the copyright line. It must match the company's name or domain, so the web agency in the footer is skipped.
- `foundedYear`: schema.org `foundingDate`, or "founded in / since / seit / est." on the about page or homepage
- `country`: schema.org address, then the phone numbers' country, then the country-code domain, then the RDAP registrant country
- `employees`: only schema.org `numberOfEmployees`

### Pricing

Pay per event:

| Event | Price |
|---|---|
| **Company enriched** (the site answered and a company name was found) | **$0.001** ($1.00 per 1,000 companies) |
| AI classification (only with `aiClassify`) | $0.0005, plus LLM tokens of about $0.0002 billed by Apify's OpenRouter Actor |
| Actor start | $0.00005 |
| Dead, parked, blocked or failed domains | free |

How that compares with company-enrichment Actors in the Apify Store (listed prices, October 2026):

| Actor | Listed price per company |
|---|---|
| foxlabs/company-enrichment | $0.001 |
| bovi/company-lookup-scraper | $0.0015 |
| b2bsearch/domain-to-company | $0.0055 |
| Domain → LinkedIn URL finders (s-r, mambalabs) | $0.006–0.009 |
| **This Actor** | **$0.001, with dead and parked domains free** |

Set a **maximum cost per run** in the run options. The Actor stops cleanly before going over it.

### Limitations

- **Data appears only if the company publishes it.** Small sites often have no legal name, founded year or LinkedIn link. In that case the field is `null`; it is never guessed.
- **JavaScript-only sites** (`jsRenderedSite: true`) show little text to an HTTP client, so expect fewer fields there.
- **Bot-protected sites** (Cloudflare/Incapsula challenges) are returned with `blocked: true` and are free. Some sites rate-limit automated clients (HTTP 429/503). Those rows are also free; retry them later.
- **Domain age:** some registries (e.g. `.de`, `.jp`) publish no creation date over RDAP, so `rdapError` explains why it is missing.
- **Headcount and revenue** are not estimated.

### FAQ

**Is this legal?**
The Actor reads only information that companies publish about themselves on their own website, plus public DNS and RDAP registry data. It respects robots.txt and never logs in or fetches LinkedIn or other social networks. Emails and phone numbers of named people can still be personal data under the **GDPR/UK GDPR**, and email marketing is regulated (**CAN-SPAM**, **ePrivacy/PECR**, **CASL**). Make sure you have a lawful basis for your use. You are responsible for how you use the data.

**Why is the LinkedIn URL empty for some companies?**
The Actor only returns a LinkedIn page that the company links from its own website, which keeps the result verified and compliant. If the site has no LinkedIn link, the field is `null`.

**What does `charged: true` mean?**
It marks the rows you paid for. Rows with `charged: false` were free.

**Can I chain it after a Google Maps or lead scraper?**
Yes. Put that run's dataset ID in `datasetId`. If the website field has an unusual name, set it in `datasetField`.

### Use with AI agents / Apify MCP

This Actor is a good "company lookup" tool for AI agents: the input is small (a list of domains) and the output is one compact row per company. Through the [Apify MCP server](https://mcp.apify.com) (`https://mcp.apify.com?actors=gazidev/company-enrichment`), Claude, ChatGPT, Cursor and other MCP clients can call it directly, for example: *"enrich these 50 domains with country, LinkedIn page and email provider"*. You can also call it over the API: `POST https://api.apify.com/v2/acts/gazidev~company-enrichment/run-sync-get-dataset-items` with the input JSON.

### Categories

Lead generation · Marketing · Developer tools · Automation

# Actor input Schema

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

Company domains or website URLs, e.g. `acme.com`, `https://www.acme.de/en/` or even `jane@acme.com` (the domain is used). One row per company domain; duplicates (www, other paths) are merged.

## `bulkText` (type: `string`):

Paste a big list: one domain per line, comma/semicolon separated, or a whole CSV export (the first cell that looks like a domain/URL in each row is used).

## `sourceFileUrl` (type: `string`):

Public URL of a .txt or .csv file with domains (e.g. a Google Sheets 'publish to web' CSV link).

## `datasetId` (type: `string`):

Read domains from an existing Apify dataset, e.g. the output of a Google Maps or lead scraper. The field below is used, or the first of `domain`, `website`, `url`, `websiteUrl`, `companyWebsite`, `homepage`.

## `datasetField` (type: `string`):

Optional. Name of the field in the dataset items that holds the website or domain.

## `includeContacts` (type: `boolean`):

Add the emails (MX-checked) and phone numbers the company publishes on its own site (contact, about, imprint pages).

## `includeTechStack` (type: `boolean`):

Detect the website's technologies with 7,600+ open-source fingerprints (webappanalyzer, GPL-3.0): CMS, ecommerce platform, analytics, tag manager, marketing automation, CRM, live chat, payments, CDN, hosting.

## `includeEmailDns` (type: `boolean`):

Email provider from MX (Google Workspace, Microsoft 365, Zoho...), security gateway (Proofpoint, Mimecast...), SPF/DMARC presence and policy, and sending services named in SPF (HubSpot, Salesforce, Mailchimp...).

## `includeDomainAge` (type: `boolean`):

Domain creation date, age in years, expiry and registrar from the public RDAP registry service. Some country domains (e.g. .de) publish no dates.

## `aiClassify` (type: `boolean`):

Optional. Classifies each company from its own homepage/about text with an LLM through Apify's OpenRouter Actor: industry, sub-industry, B2B/B2C, business model and a one-line summary. Output fields start with `ai` and are AI estimates. Extra event per classified company; the LLM tokens (about $0.0002 per company) are billed to your Apify account.

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

Model used when AI classification is on. Default: `google/gemini-2.5-flash-lite` (fast, cheap).

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

Homepage + the most useful pages (about, contact, imprint/impressum, legal). 5 is enough for most sites. The price per company is the same whatever you choose.

## `maxDomains` (type: `integer`):

Stop after this many domains (0 = no limit). Useful to test a big list cheaply.

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

How many websites are processed at the same time. Each website gets at most 2 parallel requests and robots.txt Crawl-delay is honoured, so crawling stays polite.

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

Per-request timeout. Failed requests are retried.

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

Optional. Not needed for most sites.

## Actor input object example

```json
{
  "domains": [
    "hawksheadrelish.com",
    "puccinibomboni.com",
    "basecamp.com"
  ],
  "includeContacts": true,
  "includeTechStack": true,
  "includeEmailDns": true,
  "includeDomainAge": true,
  "aiClassify": false,
  "aiModel": "google/gemini-2.5-flash-lite",
  "maxPagesPerSite": 5,
  "maxDomains": 0,
  "maxConcurrency": 10,
  "requestTimeoutSecs": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

## `socials` (type: `string`):

No description

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

No description

## `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 = {
    "domains": [
        "hawksheadrelish.com",
        "puccinibomboni.com",
        "basecamp.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("gazidev/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": [
        "hawksheadrelish.com",
        "puccinibomboni.com",
        "basecamp.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("gazidev/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": [
    "hawksheadrelish.com",
    "puccinibomboni.com",
    "basecamp.com"
  ]
}' |
apify call gazidev/company-enrichment --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gazidev/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/xSectZFOyjY5MvbMi/builds/VD3lrCNddvMz8xNpP/openapi.json
