# Hiring Signal Leads: Companies Hiring with Decision Makers (`datagleaner/hiring-signal-leads`) Actor

Find companies hiring sales reps, SDRs, marketers, customer success or ops staff, with decision-maker emails and LinkedIn. Hiring signals from new job postings on Greenhouse, Lever and Ashby, one row per company: roles, job links, founders, CEO, head of sales. $0.03 per company with a contact.

- **URL**: https://apify.com/datagleaner/hiring-signal-leads.md
- **Developed by:** [Data Gleaner](https://apify.com/datagleaner) (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 $21.00 / 1,000 company with decision-maker contacts

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/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

## Hiring Signal Leads: companies hiring sales reps, with decision-maker emails and LinkedIn

**Find companies that are hiring sales, marketing, customer success or operations people this week, and the people who decide what they buy.** The Actor reads new job postings on the public career sites of about 8,000 companies on Greenhouse, Lever and Ashby, keeps the companies that opened the roles you care about in the last N days (7 by default), and joins each one to its **decision makers**: founders, CEO, President, VPs and heads of sales or marketing, with job title, **LinkedIn profile** and **published email**, read from the company's own website.

You get **one row per company**:

- **The hiring signal:** "Hiring 4 sales roles posted in the last 7 days", the number of matching roles, their titles, departments, locations, remote or not, posting dates and job links
- **Decision makers:** name, title, seniority, LinkedIn URL and email where the company publishes them, the best contact for the signal first (CEO or founder, then the head of the function that is hiring)
- **Company contacts:** website, general and sales email addresses on the company's own domain, phone numbers, LinkedIn company page
- **Where it came from:** the careers page, the ATS (greenhouse, lever or ashby) and how the website was found

A company that is hiring account executives, SDRs or a first marketer is a company that is growing, has budget and is about to change how it sells. That makes **hiring intent** one of the best buying signals for anyone selling to sales and marketing teams: sales tools, recruiting and staffing, agencies, training, payroll and HR software, outsourced SDR services. This Actor turns it into a lead list you can export to CSV, Google Sheets or your CRM, or run on a daily schedule.

### Use cases

- **Outbound for B2B SaaS:** reach companies the week they start building a sales team, with the founder's or CEO's LinkedIn in the same row.
- **Recruiting and staffing agencies:** a daily list of companies hiring sales, marketing or customer success roles, with the hiring manager's boss to pitch.
- **Agencies and consultants:** companies hiring their first marketer or head of growth often buy help first.
- **Account-based marketing:** watch your own target account list and get a row only when one of them opens a matching role.
- **Market research:** which companies and regions are hiring go-to-market people right now.

### How it works

1. **Hiring signal.** The Actor checks the public job APIs of Greenhouse, Lever and Ashby career boards (a bundled list of about 8,000 companies, or only the companies you give it), keeps jobs whose title matches your role categories or keywords and that were posted or updated in the last N days, and applies your location, country, remote and department filters. Titles that only look like a match are dropped ("Salesforce Developer", "Revenue Accounting", "IT Support").
2. **Company website.** It finds the company's own domain from the job links, the ATS's company profile, links in the job descriptions, or a guessed domain that is only kept when its home page names the company or links back to the same careers board.
3. **Decision makers.** It reads the company's home page and up to 4 team, about, leadership or Impressum pages, and keeps the founders, C-level, VPs and directors it names, with the LinkedIn profile and email published next to them.

Everything runs inside this one Actor with plain HTTP requests: no browser, no login, no third-party data provider, and no other Actor runs in your account.

### Pricing

Pay per company returned. Apify platform usage is included in the price.

| Event | Price | When |
|---|---|---|
| `company-with-contact` | **$0.03** per company | At least one decision maker (founder, C-level, VP or director) with an **email or a LinkedIn link** was found |
| `company-signal` | **$0.002** per company | The hiring signal and company data, but no decision maker with an email or LinkedIn link |

Apify subscribers on the Silver plan pay 15% less and Gold 30% less on both events.

**Worked example.** The default search for 50 companies across all four role categories returned 8 companies with a decision-maker contact and 42 with the signal only: 8 x $0.03 + 42 x $0.002 = **$0.32** for the run. Turn on **Only companies with a decision-maker contact** to receive and pay for contact rows only: 20 such companies cost $0.60, and the companies left out cost nothing.

You can cap any run with Apify's maximum cost per run; the Actor stops cleanly when it is reached.

### Input example

```json
{
  "roleCategories": ["sales"],
  "postedWithinDays": 7,
  "countries": ["US", "GB"],
  "maxCompanies": 100,
  "onlyCompaniesWithContacts": true
}
```

Main options:

| Field | What it does |
|---|---|
| `roleCategories` | `sales` (account executives, SDRs, BDRs, business development, partnerships, account managers), `marketing` (marketing, growth, demand gen, content, brand), `customerSuccess` (customer success, onboarding, implementation, support), `operations` (RevOps, sales or business operations, enablement, chief of staff) |
| `titleKeywords` | Your own words, for example `founding ae`, `head of sales`. Added to the categories, or used alone when no category is chosen |
| `postedWithinDays` | Freshness of the signal, 7 by default; 1 for a daily schedule |
| `locations`, `countries`, `remoteOnly`, `departments`, `excludeTitleKeywords` | Narrow the jobs that count |
| `companies` | Watch only these companies: career-page URLs, `greenhouse:acme`, or a company name or website |
| `maxCompanies` | Stop after this many companies (default 50) |
| `onlyCompaniesWithContacts` | Return and bill only companies with a decision-maker email or LinkedIn |
| `maxOpenJobs` | Skip employers with more open jobs than this (default 300) to focus on startups and mid-market companies; 0 keeps every size |
| `onlyNewSinceLastRun`, `stateKey` | For schedules: a company comes back only when it opens a new matching role |

With an empty input the Actor runs a small built-in example (at most 5 companies hiring sales roles this week).

### Output example

One row (lists shortened):

```json
{
  "companyName": "Halter",
  "domain": "halterhq.com",
  "website": "https://halterhq.com",
  "domainSource": "ats-profile",
  "ats": "ashby",
  "careersUrl": "https://jobs.ashbyhq.com/halter",
  "signal": "Hiring 12 sales, marketing, operations and customer success roles posted in the last 7 days",
  "openRolesCount": 12,
  "roleCategories": ["sales", "marketing", "operations", "customerSuccess"],
  "jobTitles": ["Territory Manager (North Canterbury)", "Senior Content Specialist", "Territory Manager (Pennsylvania)"],
  "latestPostedAt": "2026-10-18T20:38:04+00:00",
  "remoteRolesCount": 8,
  "hasDecisionMakerContact": true,
  "topContactName": "Craig Piggott",
  "topContactTitle": "CEO & Founder",
  "topContactLinkedinUrl": "https://www.linkedin.com/in/craig-piggott-9ab437aa",
  "topContactEmail": null,
  "decisionMakersCount": 5,
  "decisionMakers": [
    {"name": "Craig Piggott", "title": "CEO & Founder", "seniority": "founder",
     "linkedinUrl": "https://www.linkedin.com/in/craig-piggott-9ab437aa", "email": null,
     "sourceUrl": "https://www.halterhq.com/about"},
    {"name": "Andrew Fraser", "title": "President", "seniority": "c-level",
     "linkedinUrl": "https://www.linkedin.com/in/andrew-fraser-nz", "email": null,
     "sourceUrl": "https://www.halterhq.com/about"}
  ],
  "companyEmails": [],
  "companyPhones": [],
  "companyLinkedinUrl": null,
  "jobs": [
    {"title": "Territory Manager (North Canterbury)", "category": "sales", "department": "Sales & Account Management",
     "location": "Canterbury", "workArrangement": "remote", "postedAt": "2026-10-18T20:38:04+00:00",
     "jobUrl": "https://jobs.ashbyhq.com/halter/45479102-2f91-42cf-9dca-74b96521d00a", "salaryText": null}
  ],
  "websiteStatus": "ok",
  "billedEvent": "company-with-contact",
  "postedWithinDays": 7,
  "input": "bundled-board-search",
  "scrapedAt": "2026-10-21T04:36:51+00:00"
}
```

The **Hiring companies** view in the Console shows the signal and the top contact as a flat table; the **Decision makers** and **Jobs** views show the full lists.

### Measured results

Runs on the Apify platform, 2026-10-21, default settings:

| Run | Boards checked | Companies | With decision-maker contact | Time |
|---|---|---|---|---|
| Sales roles, 10 companies | 23 | 10 | 3 | 64 s |
| All four categories, 50 companies | 76 | 50 | 8 | 207 s |
| Sales roles, contacts only | 292 | 11 (119 without a contact left out, free) | 11 | 563 s |

- The company website was found for 47 of 50 companies.
- About 1 in 6 hiring companies publishes a decision maker with a LinkedIn link or email on its own site; many more name their founders or leadership without links, and those names are still in the row.
- With **Only companies with a decision-maker contact** on, expect roughly one contact company every 50 seconds; give such runs a longer timeout.

### Run it every day

Create a task with your filters, set `postedWithinDays` to 1 or 2, turn on `onlyNewSinceLastRun`, and schedule it daily. Each run then returns only companies that opened a new matching role since the previous run, so you never pay twice for the same signal. Send the dataset to Google Sheets, HubSpot, Slack or a webhook with Apify integrations, or call the Actor from n8n, Make, Zapier or the API:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("datagleaner/hiring-signal-leads").call(run_input={
    "roleCategories": ["sales", "marketing"],
    "postedWithinDays": 7,
    "countries": ["US"],
    "maxCompanies": 50,
})
for company in client.dataset(run.default_dataset_id).iterate_items():
    print(company["companyName"], company["signal"], company["topContactName"], company["topContactLinkedinUrl"])
```

### Limits

- Covers companies whose careers page runs on **Greenhouse, Lever or Ashby**: about 8,000 in the bundled list, mostly tech, SaaS, fintech, health and venture-backed companies, plus any board you add in `companies`. Jobs posted only on job boards or on other ATSs are not seen.
- Decision makers come only from what the company publishes on its own website. No LinkedIn scraping, no email guessing and no SMTP checks: an email is returned only when the site shows it.
- Very large employers are skipped by default (`maxOpenJobs` 300); set 0 to include them.
- A job's date is the ATS's own posted or updated date; jobs with no date are kept.

### FAQ

**Is this a LinkedIn scraper?** No. Jobs come from the companies' public career-site APIs, and people from the companies' own websites. LinkedIn URLs are the ones the company links from its team or about page.

**Why do some companies have no contact?** Many sites list no team, or name people without links. Those rows cost $0.002, or nothing if you turn on `onlyCompaniesWithContacts`.

**Can I watch my own list of companies?** Yes. Put career-page URLs, `greenhouse:slug`, `lever:slug`, `ashby:slug`, or company names or websites in `companies`. Add `searchAllCompanies` to search the bundled list as well.

**How fresh is the data?** Live: every run reads the career boards and websites at run time.

**Can an AI agent use it?** Yes. It is available through Apify's MCP server and API; a prompt like "find US companies hiring SDRs this week with the CEO's LinkedIn" maps to `roleCategories: ["sales"]`, `countries: ["US"]`, `postedWithinDays: 7`.

### Related Data Gleaner Actors

- [ATS Jobs Search API](https://apify.com/datagleaner/career-jobs-scraper): every job from Greenhouse, Lever, Ashby, Workday and more, one row per job. Use it when you need the postings themselves rather than the companies behind them.
- [Company Leadership & Team Page Scraper](https://apify.com/datagleaner/team-page-contacts): decision makers for your own list of company domains.
- [Company Contact Details & Website Email Finder](https://apify.com/datagleaner/website-contact-details-scraper): emails, phones and socials from any list of websites.

### Responsible use

The Actor reads only public pages: career-site job APIs and the companies' own websites, respecting robots.txt by default. Names, titles, LinkedIn links and emails are returned only where the company published them. You are responsible for how you use personal data, including GDPR, CAN-SPAM and similar laws where your recipients live: keep outreach relevant to the person's business role, identify yourself, and honour opt-outs.

# Actor input Schema

## `roleCategories` (type: `array`):

Which newly opened roles count as a buying signal. sales = account executives, SDRs, BDRs, business development, partnerships, account managers; marketing = marketing, growth, demand gen, content, brand; customerSuccess = customer success, onboarding, implementation, support; operations = RevOps, sales or business operations, enablement, chief of staff. Leave empty and set Job title keywords to use only your own words.

## `titleKeywords` (type: `array`):

Your own words a job title must contain (case-insensitive), for example 'account executive', 'sdr', 'head of sales'. They are added to the role categories above; with no category chosen, only these words count.

## `postedWithinDays` (type: `integer`):

How fresh the signal must be: only jobs posted or updated in the last N days count. 7 is a weekly lead list; 1 suits a daily schedule.

## `locations` (type: `array`):

Keep only jobs whose location contains one of these texts, for example London, New York, Remote. Leave empty for anywhere.

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

Keep only jobs located in these countries, as two-letter codes or names, for example US, GB, Germany. Jobs whose country cannot be worked out are left out when this is set.

## `remoteOnly` (type: `boolean`):

Count only jobs the company marks as remote.

## `departments` (type: `array`):

Optional: keep only jobs whose department or team contains one of these texts, for example Sales, Go To Market.

## `excludeTitleKeywords` (type: `array`):

Drop jobs whose title contains any of these words, for example intern, engineer, recruiter.

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

Check only these companies instead of the bundled list: career-page URLs (https://boards.greenhouse.io/acme, https://jobs.lever.co/acme, https://jobs.ashbyhq.com/acme), 'greenhouse:acme', or a company name or website (the Actor tries the obvious Greenhouse, Lever and Ashby boards). Leave empty to search the bundled list of about 8,000 companies.

## `searchAllCompanies` (type: `boolean`):

When Companies to watch is set, also search the bundled list of about 8,000 Greenhouse, Lever and Ashby boards. With no companies given, the bundled list is always searched.

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

Stop after this many hiring companies are returned. Each one is billed once (see Pricing).

## `onlyCompaniesWithContacts` (type: `boolean`):

Return only companies where a founder, CEO, VP or director with an email or LinkedIn link was found on the company's website. Others are left out and not billed; the run keeps searching until Max companies is reached.

## `maxDecisionMakers` (type: `integer`):

How many founders, C-level, VPs and directors to return per company, the best contact for the signal first (CEO or founder, then the head of the hiring function).

## `maxJobsPerCompany` (type: `integer`):

How many matching jobs to list in each row (newest first). openRolesCount always counts all of them.

## `maxOpenJobs` (type: `integer`):

Leave out very large employers (by their total open jobs when the bundled list was built) to focus on startups and mid-market companies. 0 keeps every size.

## `ats` (type: `array`):

Only search boards on these applicant tracking systems. Leave empty for Greenhouse, Lever and Ashby.

## `onlyNewSinceLastRun` (type: `boolean`):

For scheduled runs: skip jobs an earlier run with the same state key already delivered, so a company comes back only when it opens a new matching role. The list is kept in the named key-value store 'hiring-signal-leads-state' on your account.

## `stateKey` (type: `string`):

Name of the delivered-jobs list for the option above. Use one key per schedule.

## `maxPagesPerWebsite` (type: `integer`):

Team, about, leadership and Impressum pages read on each company's own site, after its home page.

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

How many career boards and company websites are read at the same time.

## `requestDelaySeconds` (type: `number`):

Base pause between requests to the ATS endpoints.

## `respectRobotsTxt` (type: `boolean`):

Skip company-website pages that robots.txt disallows.

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

Optional. The ATS endpoints and most company sites answer Apify's datacenter IPs without a proxy.

## Actor input object example

```json
{
  "roleCategories": [
    "sales"
  ],
  "postedWithinDays": 7,
  "remoteOnly": false,
  "searchAllCompanies": false,
  "maxCompanies": 10,
  "onlyCompaniesWithContacts": false,
  "maxDecisionMakers": 5,
  "maxJobsPerCompany": 10,
  "maxOpenJobs": 300,
  "onlyNewSinceLastRun": false,
  "stateKey": "default",
  "maxPagesPerWebsite": 4,
  "maxConcurrency": 10,
  "requestDelaySeconds": 0.2,
  "respectRobotsTxt": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `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 = {
    "roleCategories": [
        "sales"
    ],
    "maxCompanies": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datagleaner/hiring-signal-leads").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 = {
    "roleCategories": ["sales"],
    "maxCompanies": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("datagleaner/hiring-signal-leads").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 '{
  "roleCategories": [
    "sales"
  ],
  "maxCompanies": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call datagleaner/hiring-signal-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datagleaner/hiring-signal-leads"
        }
    }
}
```

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/hV9rW6jh3ui5dckrw/builds/QfPFdnn3jWgZgwhOv/openapi.json
