# Company Signals — Competitor Hiring & Product Watch (`dev_web_col/company-signals`) Actor

Competitor monitoring from a domain: finds their job board, store, community and status page, then reports hiring shifts, launches and outages.

- **URL**: https://apify.com/dev\_web\_col/company-signals.md
- **Developed by:** [Diseño Web de Colombia](https://apify.com/dev_web_col) (community)
- **Categories:** Lead generation, Jobs, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 signal detecteds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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 Signals — Competitor Hiring & Product Watch

**Give it a domain. It finds the competitor's job board, store, community and status page — then tells you when they move.**

### What is Company Signals?

Most competitor tracking asks you to configure every source by hand. This Actor starts from a domain and discovers what that company exposes publicly: its applicant tracking system, its Shopify storefront, its Discourse community, its status page. Then it watches all of them and reports typed signals.

Hiring pushes, product launches, price moves, outages, community activity — each one is a dated, categorised row, not a wall of text.

### Discovery is the hard part

The reason competitor monitors are painful is setup. You have to know that a company uses Greenhouse, find their board token, locate their status page, and repeat that for every competitor.

This Actor probes for all of it from the domain alone, then diffs each source against a snapshot held in **your own account**. Adding a competitor is one line: their domain.

Signals are typed so you can route them — a hiring surge goes to sales, an outage goes to support, a product launch goes to product. The first run is a baseline: no per-result charge, small sample.

### What you can use it for

| What you want | How to ask for it |
|---|---|
| **Competitor monitoring** from one domain | `companyDomains: ["rival.com"]` — sources auto-discovered |
| **Sales triggers** — a competitor staffing up | Read hiring signals, route to the rep |
| **Product launch detection** | Storefront and community signals |
| **Outage and reliability watch** | Status-page signals |
| **Market research** across a competitive set | Several domains, one run |
| **Investor or portfolio tracking** | Operational tempo without asking the company |
| **Agency reporting for clients** | One monitor key per client |
| **Churn signals in a rival's community** | Community activity shifts |

Typical jobs: **competitor monitoring**, **competitive intelligence**, **market
research**, and sales-trigger detection.

### What data you get

For each signal: the signal type, the company domain, the source it came from, a human-readable summary, the underlying values that changed, a URL to the evidence, and the detection timestamp.

### Input

Every field is optional unless marked required.

| Field | Type | Description |
|---|---|---|
| `oneShot` | boolean | Return everything these companies publish right now instead of what changed. Use this for a single lookup or from an AI agent — as a monitor, the first run returns nothing because there is no history to compare against yet. |
| `companyDomains` | array, **required** | Just the domains of your competitors: stripe.com, vanta.com, allbirds.com. The actor finds their job board, online store, community forum and status page by itself — you do not paste any URLs. |
| `monitorKey` | string | Keep this the same across runs — it is how the actor remembers what it already saw. Use a different name for an independent watchlist. |
| `trackSignals` | array | Leave empty to get all of them. Hiring shifts are the earliest indicator of a competitor's strategy. |
| `sources` | array | Leave empty to use every source the company exposes. Restricting them makes runs faster and cheaper. |
| `maxSignals` | integer | Safety cap. You are charged per signal returned. |
| `resetBaseline` | boolean | Forget everything seen before and take a fresh baseline. The baseline run is never charged. |
| `proxyConfiguration` | object | Recommended. Shopify and some stores block datacenter IPs, including Apify's, so a residential proxy avoids gaps in store data. |

#### Input sample

```json
{
  "companyDomains": [
    "stripe.com",
    "vanta.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

### Output sample

One real row from an actual run:

```json
{
  "signal": "current",
  "detectedAt": "2026-07-30T19:06:25.273Z",
  "domain": "vanta.com",
  "source": "jobs",
  "title": "Senior Account Executive, Growth Stage",
  "url": "https://jobs.ashbyhq.com/vanta/fe5fd1a4-12ff-4703-bed5-6c2f34ba7768",
  "summary": "jobs: Senior Account Executive, Growth Stage",
  "value": null,
  "previousValue": null,
  "changePct": null,
  "state": null,
  "detail": "Remote U.S.",
  "key": "vanta.com:jobs:fe5fd1a4-12ff-4703-bed5-6c2f34ba7768"
}
```

### Who uses this

- **Competitive intelligence** — one row per meaningful competitor move
- **Sales teams** — a competitor hiring surge is a market signal with timing
- **Product managers** — see launches and deprecations as they ship
- **Investors** — track a portfolio's operational tempo without asking
- **Agencies** — monitor a client's whole competitive set from one place

### Honest limits

These are real and none of them is fixable by any tool. They are here so you know what you are buying before you run it.

- **A company is only as visible as what it exposes publicly.** A competitor with no public job board, no Shopify store and no status page will produce few signals. The run tells you which sources were found.
- **The first run is a baseline** and returns a sample, not the full state.
- **Discovery is heuristic.** It probes likely locations and confirms with real data, but a company using an unusual setup may not be detected.
- **A residential proxy is recommended.** Some of the sources probed block datacenter IPs.
- **A change between runs is invisible.** Schedule according to how fast you need to know.

### FAQ

#### What sources does it actually check?

Applicant tracking systems (Greenhouse, Lever, Ashby, Workable), Shopify storefronts, Discourse communities and public status pages. It probes each from the domain and keeps the ones that return real data.

#### Do I have to configure each competitor's sources?

No, that is the point. You give a domain and discovery does the rest. If nothing is found, the log says so instead of failing silently.

#### Why did a competitor return no signals?

Either nothing changed since your last run, or that company exposes none of the sources this Actor understands. The run log distinguishes the two.

#### What is a typed signal?

A change categorised by what it means — hiring surge, product launch, price change, outage — rather than a raw diff. It makes routing and alerting straightforward.

#### How often should I run it?

Daily suits most competitive tracking. Faster only helps if you act on outages or launches within hours.

#### Where is the history kept?

In a named key-value store in your own Apify account, one per monitor key. It never leaves your account.

#### Do I need an account or an API key for the source?

No. This Actor only reads public pages and public endpoints, the same ones any
logged-out visitor sees. You never give it credentials, and nothing is done on
your behalf.

#### Is it legal to scrape this data?

Scraping publicly available information is broadly accepted as legal, and this
Actor only ever touches pages that require no login. That said, what you may do
with the data afterwards is a separate question — personal data in particular is
regulated by GDPR and CCPA. If you plan to process personal data, take advice
first. Apify has a good primer: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

#### How much will a run cost me?

You are charged per result, so the cost scales with what you actually get back.
The pricing is shown on this page above the input form. Start with a small run to
see real numbers before you scale up.

#### Can I export to Excel, CSV or Google Sheets?

Yes. Every run's dataset can be downloaded as CSV, Excel, JSON, XML or HTML from
the **Storage** tab, and Apify integrates directly with Google Sheets, Airtable,
Zapier, Make and Slack.

#### Can I run this on a schedule?

Yes. Open the **Schedules** tab and pick an interval — hourly, daily, weekly.
Each run only costs you what it returns.

#### Can I call it from my own code instead of the console?

Yes. Every Actor on Apify is also an API endpoint. There are official clients for
[Python](https://docs.apify.com/api/client/python/) and
[JavaScript](https://docs.apify.com/api/client/js/), plus a plain REST API. The
**API** tab on this page shows ready-made snippets with your input already filled in.

#### Something came back empty. Is it broken?

Usually not. An empty result normally means the filters were too narrow, or the
source genuinely has nothing to return for that query. This Actor is written to
finish successfully and tell you what happened rather than fail — check the run
log, it says which step returned nothing.

### Related Actors

- **ATS Job Monitor** — deeper tracking of hiring changes alone
- **Shopify Sales Tracker** — deeper tracking of storefront changes alone
- **Company Enrichment** — turn a domain into firmographics and contacts

### Where the data comes from

Public applicant tracking system endpoints, public Shopify product feeds, public Discourse endpoints and public status pages. No login anywhere. Snapshots are kept in your own Apify account.

# Actor input Schema

## `oneShot` (type: `boolean`):

Return everything these companies publish right now instead of what changed. Use this for a single lookup or from an AI agent — as a monitor, the first run returns nothing because there is no history to compare against yet.

## `companyDomains` (type: `array`):

Just the domains of your competitors: stripe.com, vanta.com, allbirds.com. The actor finds their job board, online store, community forum and status page by itself — you do not paste any URLs.

## `monitorKey` (type: `string`):

Keep this the same across runs — it is how the actor remembers what it already saw. Use a different name for an independent watchlist.

## `trackSignals` (type: `array`):

Leave empty to get all of them. Hiring shifts are the earliest indicator of a competitor's strategy.

## `sources` (type: `array`):

Leave empty to use every source the company exposes. Restricting them makes runs faster and cheaper.

## `maxSignals` (type: `integer`):

Safety cap. You are charged per signal returned.

## `resetBaseline` (type: `boolean`):

Forget everything seen before and take a fresh baseline. The baseline run is never charged.

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

Recommended. Shopify and some stores block datacenter IPs, including Apify's, so a residential proxy avoids gaps in store data.

## Actor input object example

```json
{
  "oneShot": false,
  "companyDomains": [
    "stripe.com",
    "vanta.com"
  ],
  "monitorKey": "default",
  "trackSignals": [],
  "sources": [],
  "maxSignals": 2000,
  "resetBaseline": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

One dataset item per signal.

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

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

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dev_web_col/company-signals"
        }
    }
}
```

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/eaSOhfcGP2AUyPA2g/builds/jDGFt4K9kvWpwCv2q/openapi.json
