# Company Enrichment — Domain to Firmographics, Tech & Signals (`inovaflow/company-enrichment`) Actor

Company data enrichment from a domain or a company name: industry, headcount, HQ, founded year, description, socials, LinkedIn and the live tech stack, plus optional hiring, funding, ad and leadership buying signals. One unified profile per row, with a confidence score on every field.

- **URL**: https://apify.com/inovaflow/company-enrichment.md
- **Developed by:** [inovaflow](https://apify.com/inovaflow) (community)
- **Categories:** Lead generation, AI
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 company profiles

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 — Domain to Firmographics, Tech & Signals

**You have a domain. You need a company.** A form fill says `jane@acme.io` and nothing else. A CSV from a
conference has 400 company names and no websites. A CRM record has a URL and eleven empty fields. Every one
of those is the same job: turn the one thing you know into everything you need to decide whether this account
is worth a sequence.

That is this Actor. **One domain or one company name in, one complete company profile out** — who they are,
how big, where, since when, what they run, and (if you ask) what just changed at the company that makes this
a good week to call.

***

### Who it is for

- **RevOps and CRM owners** — fill the empty columns behind a domain: industry, headcount band, HQ, founded,
  description, LinkedIn, socials. Bulk, flat, ready to upsert.
- **AI / GTM agents** — one tool call, a flat dataset, no login and no API key. `domain`, `industry`,
  `companySize`, `techStack`, `signalScore` and `whyNow` are all on the row.
- **Outbound teams** — qualify before you write. Tech stack tells you whether they are a fit; the signals
  block tells you whether now is the moment.
- **Anyone building a lead list** — the connective step between "I found some companies" and "I know which
  ones to work".

***

### What makes it different

| | A firmographics API | This Actor |
| --- | --- | --- |
| Input | a domain | a domain **or** a company name — names are resolved to domains for you |
| Tech stack | rarely, or a stale list | detected **live on the site**, with the actively-used ones flagged |
| "Why now" | never | optional hiring, funding, paid-ad and new-executive signals, scored 0–100 |
| Trust | one number for the whole record, or none | **a confidence score on every field**, plus where that field came from |
| When a source is down | the run fails | the row still ships, and `sourcesSkipped` says what was missing |
| Cost | flat per record | you choose what to attach; the row carries what it cost |

***

### What you get per company

**Identity** — `name`, `domain`, `website`, `linkedinUrl`, `logoUrl`
**Firmographics** — `industry`, `industries`, `specialties`, `companySize`, `employeesMin` / `employeesMax`,
`foundedYear`, `companyType`
**Location** — `headquarters`, `city`, `region`, `country`, `address`, `phone`
**Story** — `description`, `tagline`
**Reach** — `socials` (LinkedIn, X, Facebook, Instagram, YouTube, GitHub)
**Tech** — `techStack`, `techCount`, `techVerified`, and per-category columns: `cms`, `analytics`, `crm`,
`marketingAutomation`, `chat`, `support`, `payments`, `hosting`, `cdn`, `advertising`, `tagManagers`…
**Signals** (optional) — `signals` with a block per trigger, plus flat `hiringOpenRoles`, `fundingRound`,
`fundingAmountUsd`, `activeAdCount`, `newExecutive`, and the derived `signalScore`, `signalTags`, `sellTo`,
`whyNow`
**Trust** — `confidence` per field, `fieldSources` per field, `completeness`, `status`, `sourcesUsed`,
`sourcesSkipped`, `cost`

***

### How to use it

Paste the companies. Everything else already has a sensible default.

```json
{
  "companies": ["gong.io", "Ramp", "https://www.hubspot.com"],
  "includeTechStack": true
}
```

Add the "why now" layer when you are building a call list rather than cleaning a CRM:

```json
{
  "companies": ["gong.io", "ramp.com", "lemlist.com"],
  "includeTechStack": true,
  "includeSignals": true,
  "signals": ["funding", "leadership", "hiring"],
  "signalDaysBack": 90
}
```

Cheapest possible pass — identity, description and socials straight off the company's own site:

```json
{
  "companies": ["gong.io"],
  "useCompanyProfile": false,
  "includeTechStack": false
}
```

***

### Confidence, and why it is per field

A company record is never uniformly true. The domain might be certain and the headcount a guess; the
description might come straight from the company and the founding year from a footer. So every field that got
a value carries its own `confidence` (0–100) and its own entry in `fieldSources`. Two independent sources that
agree raise the number; nothing is ever invented to fill a blank. `completeness` is the average across the
fields that were filled — one number to sort or threshold on.

***

### Graceful by design

Sources are independent. If the tech detection is unavailable, you still get firmographics. If the company's
website is down, you still get the profile. If everything optional fails, you still get an identified,
deduplicated row — and `sourcesSkipped` tells you exactly what was missing and why. A run does not fail
because one part of it did.

***

### Cost control

Three switches decide what a run costs: `includeTechStack`, `includeSignals` and `maxCompanies`. The base
profile and the website read are included. `maxSpendUsd` puts a hard ceiling on the attached lookups, and
every row carries a `cost` breakdown so you can see what you actually spent per company. No subscription, no
API key, no minimum.

***

### Notes

- **Dataset-only.** No UI, no dashboard, no login. Four ready-made views: profile, tech, signals, audit.
- **Deduplicated by domain** — the same company sent twice comes back once.
- **Public data only.** Nothing behind a login is ever touched.

# Actor input Schema

## `companies` (type: `array`):

A domain (`gong.io`), a company name (`Gong`) or a website URL (`https://www.ramp.com`). Also accepted as `domains`, `companyNames`, `websites` or `urls`.

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

Detect the CMS, analytics, CRM, marketing automation, chat, payments, hosting and CDN a company actually runs, verified live on the site. Adds a paid lookup per resolved domain.

## `includeSignals` (type: `boolean`):

Also answer "why now?": open roles, a recent funding round, paid-ad activity and new executives — each as a block on the row, with a combined 0–100 signal score, who to sell to and an opening line. Off by default because each signal is a paid lookup.

## `signals` (type: `array`):

Only used when buying signals are on. Empty = all four.

## `signalDaysBack` (type: `integer`):

How far back a signal still counts. 90 days catches a funding round or an executive change that is still fresh enough to open with.

## `useCompanyProfile` (type: `boolean`):

Reads the company's public profile for the fields a website never states: industry, employee band, HQ and founded year. This is also what turns a company NAME into a domain — turn it off only when every input is already a domain and firmographics do not matter.

## `crawlWebsite` (type: `boolean`):

Reads the company's own home page for the description, socials, phone, address, logo and founding year. Costs nothing beyond compute and is what keeps a row useful when nothing else answers.

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

The home page plus, if needed, the about and contact pages. More pages fill more fields on sites that keep the detail off the front page.

## `hiringRoles` (type: `array`):

Only used when the hiring signal is on. Which open roles mean something to you — e.g. `Account Executive`, `Data Engineer`. Empty = a broad revenue-and-build set.

## `countries` (type: `array`):

Only used when the ads signal is on. Two-letter country codes for the ad library to search. Empty = US.

## `maxCompanies` (type: `integer`):

Stop after this many companies. Also caps what the run can cost, since this Actor charges per company delivered.

## `maxSpendUsd` (type: `integer`):

A hard ceiling on what the paid lookups behind the tech stack and the signals may charge your account in this run. Leave empty for no ceiling. The base profile and the website read are unaffected.

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

How many company websites are read at once.

## `nestedTimeoutSecs` (type: `integer`):

How long any one attached lookup may take before the run continues without it. The row is still delivered, with that source listed under sourcesSkipped.

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

Used for the company-website read. The default is fine; a residential group helps on sites that block datacentre IPs.

## Actor input object example

```json
{
  "companies": [
    "gong.io",
    "Ramp",
    "https://www.hubspot.com"
  ],
  "includeTechStack": true,
  "includeSignals": false,
  "signals": [
    "hiring",
    "funding",
    "ads",
    "leadership"
  ],
  "signalDaysBack": 90,
  "useCompanyProfile": true,
  "crawlWebsite": true,
  "maxPagesPerSite": 2,
  "hiringRoles": [
    "Account Executive",
    "RevOps",
    "Data Engineer"
  ],
  "countries": [
    "US",
    "GB"
  ],
  "maxCompanies": 50,
  "maxConcurrency": 6,
  "nestedTimeoutSecs": 900,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `companies` (type: `string`):

One row per company: name, domain, industry, size, HQ, founded, description, socials and LinkedIn.

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

The CMS, analytics, CRM, marketing automation, chat, payments, hosting and CDN detected per company.

## `signals` (type: `string`):

Open roles, funding, paid ads and new executives per company, with the combined signal score, who to sell to and the opening line.

## `audit` (type: `string`):

Per-field confidence, which source filled each field, what was skipped and what the run cost per company.

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

Companies resolved, field coverage, signal coverage, per-source report and the full cost breakdown.

# 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 = {
    "companies": [
        "gong.io",
        "ramp.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("inovaflow/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 = { "companies": [
        "gong.io",
        "ramp.com",
    ] }

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

```

## MCP server setup

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