# Company ATS & Hiring Signal Scraper (`jungle_synthesizer/company-ats-technographic-hiring-signal-scraper`) Actor

Turn a plain corporate domain into a hiring-velocity record: detects the applicant tracking system, aggregates open roles by department, location and seniority, and reports 30-day hiring velocity and salary disclosure. One row per company.

- **URL**: https://apify.com/jungle\_synthesizer/company-ats-technographic-hiring-signal-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 record scrapeds

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 ATS & Hiring Signal Scraper

Turn a plain corporate domain into a company-level hiring-velocity record. Give the actor a
list of company domains (e.g. `monzo.com`, `ramp.com`) and it returns one row per company:
which applicant tracking system they use, how many roles are open, department / location /
seniority / function breakdown, remote share, 30-day hiring velocity, and salary-disclosure
rate. No job rows — this is a company-level technographic and hiring-intent signal, built for
CRM enrichment and sales/RevOps prospecting rather than job search.

#### What Data Does It Extract?

| Field | Description |
|-------|-------------|
| `company_domain` | Input company domain (normalized) |
| `company_name` | Company name, derived from the domain / board |
| `careers_page_url` | The careers page URL that was resolved for this company |
| `ats_vendor` | Detected ATS: `greenhouse`, `lever`, `ashby`, `workable`, `smartrecruiters`, `recruitee`, `teamtailor`, `personio`, `workday`, `jobvite`, `bamboohr`, `breezy`, or `none_detected` |
| `ats_board_token` | The vendor-specific board/company token |
| `ats_board_url` | Public URL of the vendor's job board for this company |
| `ats_api_endpoint` | The vendor endpoint used to aggregate this record |
| `ats_detection_evidence` | The matched host/pattern, for auditability |
| `open_req_count` | Total open requisitions on the board |
| `departments` | Department breakdown: `[{ name, count }]` |
| `locations` | Location breakdown: `[{ name, count }]` |
| `countries` | Distinct countries with open requisitions (conservative — only populated when the source data names a real country/state, never guessed from a city) |
| `remote_req_count` / `remote_share` | Count and share of requisitions marked remote |
| `seniority_mix` | `{ intern, junior, mid, senior, lead, exec }` counts, classified from job titles |
| `function_mix` | `{ eng, sales, marketing, ops, ga }` counts, classified from titles/departments |
| `newest_posted_at` / `oldest_posted_at` | Posting dates of the newest/oldest open requisition |
| `reqs_posted_last_30d` / `hiring_velocity_30d` | New requisitions in the trailing 30 days |
| `salary_disclosed_req_count`, `salary_min_observed`, `salary_max_observed` | Best-effort salary-range detection where the board discloses it |
| `sample_titles` | A sample of open requisition titles |
| `is_hiring` | `true` when the company has at least one open requisition |
| `checked_at` | When this record was generated |

#### How to Use

```json
{
    "companyDomains": ["monzo.com", "ramp.com", "anthropic.com"],
    "maxItems": 50
}
```

- `companyDomains` (required) — the list of corporate domains to check. Accepts a bare domain
  (`monzo.com`) or a full URL (`https://www.monzo.com/careers`) — normalized automatically.
- `maxItems` (required) — maximum number of company records to return in this run.

#### How It Works

1. **Detect** — the actor checks a handful of standard careers-page paths on each domain and
   identifies which of 12 supported applicant-tracking-system vendors the company uses. A
   minority of careers pages load their ATS link dynamically; those get one additional render
   pass before the company is recorded as `none_detected`.
2. **Aggregate** — once the vendor is identified, the actor reads that vendor's public job
   board and rolls every open requisition up into a single company-level record: counts by
   department, location, seniority and function, remote share, and hiring velocity over the
   last 30 days.
3. **One row per company** — the actor never emits individual job postings, only the
   aggregated company record.

#### Supported ATS Vendors

Greenhouse, Lever, Ashby, Workable, and SmartRecruiters get full aggregation (department,
location, salary and date detail). Recruitee, Teamtailor, Personio, Workday, Jobvite,
BambooHR, and Breezy are detected and linked, with aggregation depth depending on what each
company's public board page publishes.

#### Important Notes

- **Coverage.** Not every company uses one of the 12 supported vendors, and not every careers
  page is discoverable from the standard paths this actor checks. Domains that don't resolve
  to a supported ATS come back as `ats_vendor: "none_detected"` rather than being dropped —
  every input domain gets exactly one output row.
- **Best-effort fields.** `salary_min_observed` / `salary_max_observed` and `countries` are
  intentionally conservative — they're only populated when the underlying board data actually
  states a value; the actor never guesses a country from a city name or infers a salary that
  isn't explicitly disclosed.
- **Resume.** This actor processes a bounded, user-supplied domain list rather than crawling
  a discoverable corpus, so there is no `resumeCursor` to continue a partial run — increase
  `maxItems` or split large domain lists across multiple runs instead.

#### Ideal Use Cases

- **RevOps / sales intelligence** — enrich a CRM domain list with a live hiring-intent signal:
  a company that just opened a dozen engineering reqs is in-market for recruiting tools,
  developer tooling, payroll, and benefits spend.
- **Recruiting agencies** — identify companies actively hiring in a specific function or
  seniority band without manually checking each company's careers page.
- **Market research** — track hiring velocity and remote-work adoption across a watchlist of
  companies over time.

#### Output Example

```json
{
    "company_domain": "ramp.com",
    "company_name": "Ramp",
    "careers_page_url": "https://ramp.com/careers",
    "ats_vendor": "ashby",
    "ats_board_token": "ramp",
    "ats_board_url": "https://jobs.ashbyhq.com/ramp",
    "ats_api_endpoint": "https://api.ashbyhq.com/posting-api/job-board/ramp",
    "ats_detection_evidence": "jobs.ashbyhq.com/ramp",
    "open_req_count": 122,
    "departments": [{ "name": "Sales", "count": 41 }, { "name": "Engineering", "count": 29 }],
    "locations": [{ "name": "New York, NY (HQ)", "count": 92 }],
    "countries": ["United States"],
    "remote_req_count": 111,
    "remote_share": 0.91,
    "seniority_mix": { "intern": 1, "junior": 7, "mid": 78, "senior": 17, "lead": 7, "exec": 12 },
    "function_mix": { "eng": 32, "sales": 42, "marketing": 15, "ops": 8, "ga": 25 },
    "newest_posted_at": "2026-08-07T16:28:53.710Z",
    "oldest_posted_at": "2023-03-09T17:44:00.817Z",
    "reqs_posted_last_30d": 31,
    "hiring_velocity_30d": 31,
    "salary_disclosed_req_count": 0,
    "salary_min_observed": null,
    "salary_max_observed": null,
    "sample_titles": ["Security Engineer, Cloud", "Mobile Engineer, Android"],
    "is_hiring": true,
    "checked_at": "2026-08-09T04:34:38.072Z"
}
```

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

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

Corporate domains to check, e.g. monzo.com. One record is returned per domain.

## `maxItems` (type: `integer`):

Maximum number of company records to return

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "companyDomains": [
    "monzo.com",
    "ramp.com"
  ],
  "maxItems": 10
}
```

# 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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "companyDomains": [
        "monzo.com",
        "ramp.com"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/company-ats-technographic-hiring-signal-scraper").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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "companyDomains": [
        "monzo.com",
        "ramp.com",
    ],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/company-ats-technographic-hiring-signal-scraper").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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "companyDomains": [
    "monzo.com",
    "ramp.com"
  ],
  "maxItems": 10
}' |
apify call jungle_synthesizer/company-ats-technographic-hiring-signal-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/company-ats-technographic-hiring-signal-scraper"
        }
    }
}

```

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/GyBKrUhS9kYuQ0bTV/builds/FzGhzqrFu4D7BS550/openapi.json
