# Company Enrichment Tool & API: Domain to Tech, Jobs, Socials (`data-done-right/company-enrichment-api`) Actor

Enrich company data from a domain into one compact JSON profile: website metadata, socials, public contacts, tech stack, open jobs, recent news, Google ads activity and AI-crawler policy. Built for AI agents, CRMs and sales research. No guessed emails.

- **URL**: https://apify.com/data-done-right/company-enrichment-api.md
- **Developed by:** [Data Done Right](https://apify.com/data-done-right) (community)
- **Categories:** Lead generation, Agents, Business
- **Security:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 company snapshots

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 API: Domain to Tech Stack, Jobs, Socials & News

This **company enrichment API** takes a **domain** and returns **one compact JSON company profile**. It is built to be called by **AI agents (Apify MCP)**, sales tools, CRMs and research workflows that need a quick, honest picture of a company:

- **Website:** title, description, language, favicon, Open Graph, JSON-LD Organization (legal name, logo, address, phone, founding date). **Site size** from the sitemap: URL count, newest pages, top sections.
- **Social profiles:** LinkedIn, X/Twitter, Facebook, Instagram, YouTube, TikTok, GitHub.
- **Public contacts:** emails and phones published on the homepage and up to 2 contact/about pages, plus the address.
- **Tech stack from the website:** CMS (WordPress, Shopify, Webflow, Wix, Squarespace, HubSpot CMS...), analytics (GA4, GTM, Segment, Hotjar...), chat widgets (Intercom, Drift, Zendesk...), marketing and ad pixels, payments, CDN and hosting. Each technology comes with its **evidence**.
- **Open jobs:** the job board (Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Workable, Recruitee), open job count, top departments and locations, remote share, jobs posted in the last 30 days, the newest roles.
- **Tech from job posts:** languages, clouds, databases, SaaS tools the company hires for.
- **Recent news:** headlines about the brand from Google News, last 30 days.
- **Google ads:** whether the domain runs Google ads, the approximate total ad count, formats, and first/last seen dates.
- **AI crawler policy:** whether robots.txt allows or blocks GPTBot, ClaudeBot, Google-Extended and PerplexityBot (plus CCBot, Applebot-Extended, Bytespider and others).

**Missing data is never silent.** Every section has a `status`: `ok`, `not_found` (we looked and there is none) or `unavailable` (the source failed or timed out), always with a `reason`. Sections run in parallel with timeouts, so one slow or failing source never fails the snapshot.

### How does company enrichment work

Give it one or more domains. For each one it reads the public website, the company's public job board, Google News, the Google Ads Transparency Center and robots.txt, and merges the results into one profile. It does not look up revenue, headcount or private contact data, and it never guesses emails.

### Input

```json
{
  "domains": ["stripe.com", "linear.app"],
  "sections": ["website", "socials", "contacts", "techFromWebsite", "jobs"]
}
```

- `domains`: domains or URLs (`https://www.stripe.com/about` becomes `stripe.com`). One snapshot per domain.
- `sections` (optional): pick only what you need for **faster** runs. Leave it empty for all 9.
- `newsDays` (30), `maxNews` (10), `newsLanguage`, `newsCountry`, `newsQuery` (template, default `"{name}"`).
- `adsRegion` (`anywhere`, or a country code such as `US` or `DE`).
- `sectionTimeoutSecs` (60), `maxConcurrency` (3 domains in parallel), `maxJobsAnalyzed` (200, for paginated boards).
- `proxyConfiguration`: for websites and job boards. Off by default (direct requests).
- `googleProxyConfiguration`: for Google News and Google Ads. **Residential by default**, because Google throttles cloud IPs.

### Output (one item per domain, shortened)

```json
{
  "domain": "linear.app", "name": "Linear", "homepageUrl": "https://linear.app/", "snapshotAt": "2026-10-19T04:02:10Z",
  "website": {"status": "ok", "title": "Linear – The system for product development", "language": "en",
              "openGraph": {"image": "https://linear.app/api/og/main?title=Linear&v=4"}, "organization": null,
              "size": {"status": "ok", "sitemapUrlCount": 1030, "countIsLowerBound": false,
                       "topSections": [{"path": "/integrations", "urls": 339}, {"path": "/changelog", "urls": 253}]}},
  "socials": {"status": "ok", "profiles": {"twitter": "https://x.com/linear", "github": "https://github.com/linear",
              "youtube": "https://www.youtube.com/@linear", "linkedin": null}, "found": 3},
  "contacts": {"status": "ok", "emails": ["hello@linear.app"], "phones": [], "address": null,
               "pagesChecked": ["https://linear.app/", "https://linear.app/contact", "https://linear.app/contact/sales"]},
  "techFromWebsite": {"status": "ok", "technologies": [{"name": "Next.js", "category": "JavaScript framework", "evidence": "html: /_next/static/"},
                      {"name": "Cloudflare", "category": "CDN & hosting", "evidence": "header server: cloudflare"}]},
  "jobs": {"status": "ok", "ats": "ashby", "boardUrl": "https://jobs.ashbyhq.com/Linear", "matchedBy": "careers_page_link",
           "openJobs": 29, "postedLast30Days": 3, "remoteShare": 1.0,
           "topDepartments": [{"name": "Product", "jobs": 14}, {"name": "GTM", "jobs": 13}],
           "recentJobs": [{"title": "Senior / Staff Security Engineer", "postedAt": "2026-10-15T18:06:03.583+00:00", "url": "..."}]},
  "techFromJobs": {"status": "ok", "basis": "titles and descriptions", "jobsScanned": 29,
                   "technologies": [{"name": "TypeScript", "category": "Languages", "jobsMentioning": 7},
                                    {"name": "PostgreSQL", "category": "Databases", "jobsMentioning": 6}]},
  "news": {"status": "ok", "query": "\"Linear\" when:30d", "articlesFound": 100,
           "articles": [{"title": "...", "source": "...", "publishedAt": "2026-10-18T15:46:19Z", "url": "https://news.google.com/rss/articles/..."}]},
  "ads": {"status": "ok", "runsGoogleAds": true, "totalAdsRange": "26-26", "formatsInSample": {"text": 26},
          "firstShownInSample": "2024-09-23T00:31:42Z", "lastShownInSample": "2026-10-19T02:57:12Z",
          "transparencyUrl": "https://adstransparency.google.com/?domain=linear.app&region=anywhere"},
  "aiCrawlers": {"status": "ok", "robotsTxtFound": true, "blockedCount": 0,
                 "aiBots": {"GPTBot": "allowed", "ClaudeBot": "allowed", "Google-Extended": "allowed", "PerplexityBot": "allowed"}},
  "sectionStatus": {"ok": 9, "not_found": 0, "unavailable": 0}, "durationSecs": 10.8, "charged": true
}
```

A section that finds nothing looks like this: `"jobs": {"status": "not_found", "reason": "no public job board found: none linked from the website, and no Greenhouse, Lever, Ashby, SmartRecruiters, Workable or Recruitee board under hubspot"}`.

### Use cases

- **AI agents:** one tool call answers "tell me about this company" with structured, sourced data.
- **Sales and lead enrichment:** socials, contacts, tech stack, hiring and ad activity for every account in a CRM.
- **Market and competitor research:** who is hiring, what they build with, whether they advertise, how big the site is.
- **AI-visibility audits:** which brands block AI crawlers.

### Honest limits

- **Public data only.** Emails and phones are what the company publishes on its homepage and up to 2 contact/about pages. No guessing of email patterns, no third-party lookups, no personal profiles. Emails hidden by Cloudflare email protection are respected and not decoded.
- **Tech detection is light.** It reads the homepage HTML, headers and cookies with a fingerprint table of 74 technologies. Tags injected later through Google Tag Manager, and anything behind a login, are not visible. For big sites, expect the main CMS, analytics, chat, pixels and CDN, not a full BuiltWith-style list.
- **Bot protection is not bypassed.** If a website shows a Cloudflare/Akamai challenge, the website sections report `unavailable` with that reason.
- **Job boards:** a board linked from the homepage or careers page is used first (`matchedBy: website_link / careers_page_link`). Otherwise we try the brand name on 6 ATS APIs (`matchedBy: name_guess`, flagged for you to verify). Workday is found only through links. Companies with a home-grown careers site get `not_found`. Workday and SmartRecruiters listings carry no descriptions, so `techFromJobs` there is based on titles only (stated in `basis`).
- **News** searches Google News for the brand name. Brands that are common words (Linear, Notion, Ramp) pick up unrelated headlines. Set `newsQuery`, for example `"{name}" software OR "{domain}"`. Links are Google News links, and no article text is included.
- **Ads** come from the Google Ads Transparency Center for ads pointing to the domain. Partners and resellers can appear next to the company. `runsGoogleAds` is true only when an advertiser named like the company is in the sample. `adsPointingToDomain` covers anyone's ads. Formats and dates come from a sample of up to 40 ads, and the total is Google's own range.
- **Sitemap size** counts up to 100,000 URLs in up to 40 sitemaps within the section timeout. `countIsLowerBound: true` means there are more.

### How much does it cost

Pay per event: **one `company-snapshot` charge per domain delivered**, plus the standard Apify start fee. The price is the same whichever sections you pick. Domains where every section was unavailable (dead or fully blocked) are **not charged**.

### FAQ

#### What is company enrichment?

Company enrichment means starting from a little data (here, a domain) and adding facts about the company: its social profiles, public contacts, technologies, hiring activity and news.

#### What data does this company enrichment tool return?

Website metadata and site size, social profiles, public emails and phones, tech stack from the website and from job posts, open jobs, recent news, Google ads activity and AI-crawler policy. See the output example above.

#### Does it return revenue, employee count or funding?

No. It returns only what the company publishes or what is public on Google News, the Google Ads Transparency Center and its job board. Use another source for firmographics.

#### Does it find email addresses?

Only the emails and phones a company publishes on its homepage and up to 2 contact or about pages. It does not guess email patterns or look up people.

#### Can I use it with HubSpot or my CRM?

Results are available as JSON, CSV or Excel and through the Apify API, so you can load them into a CRM with your own workflow or an Apify integration. There is no built-in HubSpot connector in this Actor.

#### Can AI agents call it?

Yes. It returns one compact record per domain, so it works as an Apify MCP tool for agents.

### Related tools

- **Hiring Signals**: deeper tech stack and team growth from a company's job posts.
- **Competitor Monitoring**: weekly new pages, jobs, ads and news per competitor.
- **Google Ads Transparency Scraper**: the full list of a competitor's Google ads.

# Actor input Schema

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

One or more company domains or website URLs (stripe.com, https://www.hubspot.com/). One snapshot per domain.

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

Only the first N domains are processed (caps run time and cost).

## `sections` (type: `array`):

Pick only the sections you need for faster runs. Leave empty for all sections.

## `newsDays` (type: `integer`):

Only news from the last N days.

## `newsQuery` (type: `string`):

Google News query per domain. {name} is the detected brand name, {domain} the domain. Default: "{name}" (quoted). For brands that are common words, add context, e.g. "{name}" software OR "{domain}".

## `maxNews` (type: `integer`):

Most recent headlines kept in the news section.

## `newsLanguage` (type: `string`):

Google News interface language, e.g. en-US, en-GB, de, fr.

## `newsCountry` (type: `string`):

2-letter Google News edition, e.g. US, GB, DE.

## `adsRegion` (type: `string`):

2-letter country code where the ads were shown, or 'anywhere'.

## `maxJobsAnalyzed` (type: `integer`):

Paginated job boards stop after this many jobs; the true open-job total is still reported.

## `sectionTimeoutSecs` (type: `integer`):

Each section gives up after this long and reports 'unavailable' instead of holding up the snapshot.

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

How many domains are processed at the same time.

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

Optional. By default company websites and job-board APIs are fetched directly.

## `googleProxyConfiguration` (type: `object`):

Google throttles cloud IPs, so residential proxy is the default for the news and ads sections.

## Actor input object example

```json
{
  "domains": [
    "stripe.com"
  ],
  "maxDomains": 1000,
  "sections": [],
  "newsDays": 30,
  "maxNews": 10,
  "newsLanguage": "en-US",
  "newsCountry": "US",
  "adsRegion": "anywhere",
  "maxJobsAnalyzed": 200,
  "sectionTimeoutSecs": 60,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "googleProxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

All result items of this run (the default dataset), as JSON, CSV, Excel and more.

## `records` (type: `string`):

Key-value store records: the run summary, notes on any problems, and any files.

# 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": [
        "stripe.com"
    ],
    "googleProxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("data-done-right/company-enrichment-api").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": ["stripe.com"],
    "googleProxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("data-done-right/company-enrichment-api").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": [
    "stripe.com"
  ],
  "googleProxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call data-done-right/company-enrichment-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,data-done-right/company-enrichment-api"
        }
    }
}
```

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/08h5aDCtJGKF8we84/builds/TGUpi1lAiIulhTdrM/openapi.json
