# Company Signal Stack — Firmographics + Jobs + Funding (`bovi/company-signal-stack`) Actor

One row per company: firmographics, technology stack, open jobs (hiring signal), recent funding and headcount — joined from public sources. Buying-intent enrichment for sales & lead gen. Per-result pricing.

- **URL**: https://apify.com/bovi/company-signal-stack.md
- **Developed by:** [Vitalii Bondarev](https://apify.com/bovi) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.75 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Company Signal Stack — Firmographics + Jobs + Funding + Headcount

Turn a list of company domains into **one enriched row per company**, joining four
public signals that no single enrichment tool ships together:

| Signal | What you get | Source |
|---|---|---|
| **Firmographics + tech stack** | name, description, social profiles, detected technologies | company website |
| **Open jobs (hiring signal)** ⭐ | open-role count, breakdown by department, 30-day hiring velocity, top locations, sampled roles | Greenhouse / Lever / Ashby public APIs |
| **Funding** | recent SEC Form D private-placement filings → `recently_funded` flag + date | SEC EDGAR |
| **Headcount** | employee-count snapshot, founded year, HQ, industry | LinkedIn company page (no login) |

Plus a derived **`growth_signals`** block — a structured buying-intent summary
(`hiring` band, `recently_funded`, `is_growing`) you can filter on directly in a
CRM, a Clay table, or an AI agent. No prose reports — structured data you pipe.

### Why this exists

Firmographic tools (Clearbit/Apollo-style) tell you *what* a company is. They do
**not** tell you whether it is *growing right now* — and growth is what makes a
company worth a sales rep's time. Company Signal Stack adds the missing
buying-intent layer: a company aggressively hiring engineers and fresh off a
funding round is a hot account; the same firmographics with zero open roles is
cold. We join the hiring signal, the funding signal and the headcount snapshot to
the firmographics in one call.

### Input

```json
{
  "domains": ["stripe.com", "vercel.com"],
  "includeJobs": true,
  "includeFunding": true,
  "includeHeadcount": true,
  "maxJobsSample": 25,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

| Field | Default | Notes |
|---|---|---|
| `domains` | – | Company domains or URLs (one row per company) |
| `includeJobs` | `true` | Detect ATS, return open-role signal |
| `includeFunding` | `true` | SEC Form D lookup (US companies) |
| `includeHeadcount` | `true` | LinkedIn employee-count snapshot |
| `maxJobsSample` | `25` | How many individual roles to include (count/breakdown always reflect all roles) |
| `maxCompanies` | `200` | Safety cap per run |

### Output (one row per company)

```jsonc
{
  "domain": "stripe.com",
  "company_name": "Stripe",
  "company_description": "Financial infrastructure to grow your revenue …",
  "technologies": ["Next.js", "React", "Stripe", "Cloudflare"],
  "tech_count": 4,
  "social_profiles": { "linkedin": "…", "twitter": "…", "github": "…" },
  "linkedin_url": "https://www.linkedin.com/company/stripe/",
  "ats_provider": "greenhouse",
  "open_jobs_count": 312,
  "jobs_by_department": { "Engineering": 140, "Sales": 60, "…": 0 },
  "hiring_velocity_30d": 47,
  "top_locations": ["Remote", "San Francisco", "Dublin"],
  "jobs_sample": [{ "title": "Backend Engineer", "department": "Engineering", "location": "Remote", "url": "…", "posted_at": "2026-06-01" }],
  "recently_funded": true,
  "last_funding_date": "2025-03-12",
  "funding_filings_count": 3,
  "employee_count": 8000,
  "employee_count_basis": "linkedin-snapshot",
  "founded_year": 2010,
  "hq_location": "San Francisco, US",
  "industry": "Financial Services",
  "growth_signals": { "hiring": "high", "open_jobs": 312, "recently_funded": true, "is_growing": true },
  "sources_succeeded": ["website", "jobs", "funding", "headcount"],
  "parse_confidence": 0.95,
  "warnings": []
}
```

Every record carries the same fixed key set. A leg that finds nothing lowers
`parse_confidence` and is named in `warnings` — the row is never dropped, so a
run over 1,000 domains always returns 1,000 rows you can join on.

### Notes on the data

- **Headcount is a point-in-time snapshot, not a trend.** To track headcount over
  time, schedule the actor and diff `employee_count` across runs. We never
  fabricate a trend field; `employee_count_basis` always states the source.
- **Funding is best-effort and US-centric** (SEC Form D). Non-US or unfiled
  companies simply return `recently_funded: null` — not an error.
- **Open jobs** is read from the company's own ATS public job board (Greenhouse,
  Lever, Ashby). Companies on other systems return `ats_provider: null`,
  `open_jobs_count: 0`.

### Pricing

Pay per company enriched (PPE). The run executes on your Apify account, so you
pay only platform usage plus the per-result fee — no subscription, no minimums.

# Actor input Schema

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

Company domains or website URLs to enrich (e.g. "stripe.com", "https://vercel.com"). One row is returned per company.

## `includeJobs` (type: `boolean`):

Detect the company's ATS (Greenhouse / Lever / Ashby) and return open-role count, departments and 30-day hiring velocity.

## `includeFunding` (type: `boolean`):

Look up recent SEC Form D private-placement filings (US companies) as a recently-funded signal.

## `includeHeadcount` (type: `boolean`):

Read the company's LinkedIn page (no login) for an employee-count snapshot, founded year and HQ.

## `maxJobsSample` (type: `integer`):

How many individual open roles to include in the jobs\_sample array (the count and breakdown always reflect all roles).

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

Safety cap on how many companies to process in one run.

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

Apify proxy used to reach every source. Residential is the reliable default; the run is billed to your account.

## Actor input object example

```json
{
  "domains": [
    "stripe.com",
    "vercel.com"
  ],
  "includeJobs": true,
  "includeFunding": true,
  "includeHeadcount": true,
  "maxJobsSample": 25,
  "maxCompanies": 200,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Dataset of company records (firmographics, technologies, open\_jobs\_count, jobs\_by\_department, recently\_funded, employee\_count, growth\_signals).

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

// Run the Actor and wait for it to finish
const run = await client.actor("bovi/company-signal-stack").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",
        "vercel.com",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("bovi/company-signal-stack").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 '{
  "domains": [
    "stripe.com",
    "vercel.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call bovi/company-signal-stack --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=bovi/company-signal-stack",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

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