# ATS Hiring Intent - Buying Signals (Greenhouse + 4 ATSes) (`constructive_calm/ats-hiring-intent-scraper`) Actor

Aggregates jobs across Greenhouse, Lever, Ashby, SmartRecruiters, and Workday with auto ATS detection from a domain. Gemini classifier emits per-company buying signals (expanding-sales, evaluating-CRM, platform-build-out). Monitor mode tracks 100s of companies weekly via KV deltas.

- **URL**: https://apify.com/constructive\_calm/ats-hiring-intent-scraper.md
- **Developed by:** [Omar Eldeeb](https://apify.com/constructive_calm) (community)
- **Categories:** SEO tools, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $8.00 / 1,000 enriched job fetcheds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

### What does ATS Hiring Intent do?

ATS Hiring Intent aggregates **open job postings across five major applicant tracking systems — Greenhouse, Lever, Ashby, SmartRecruiters, and Workday** — into one normalized feed and turns the raw job data into **per-company buying signals** ready for a sales / RevOps pipeline.

Give it a list of company domains. It auto-detects each company's ATS, pulls every open role, normalizes function and seniority across platforms, and (in `signals` mode) runs each role through Gemini 2.5 Flash to extract intent tags (`expanding-sales`, `evaluating-CRM`, `series-B-build`, `platform-build-out`, …) and infer the specific vendors / tech stack the company is buying or building on. One composite **CompanySignal** per refresh tells your reps which prospects just lit up — `Stripe is expanding-sales (8/8 AE roles posted, AI-customer focus, vendor hypothesis: OpenAI, Anthropic, NVIDIA)`.

**Zero anti-bot. Zero proxies needed by default. No login.** Every data source is an official public ATS endpoint. Replaces $99-$15K/seat tools (Apollo, ZoomInfo, Bombora, Cognism) on the hiring-signal job-to-be-done.

### Why use ATS Hiring Intent?

- **B2B sales / SDRs** — find every prospect actively hiring for a role that signals they're buying *your* product. Hiring 5 DevOps + 2 Platform Engineers = evaluating IaC + observability tooling. Hiring a VP Sales + 3 AEs = expanding GTM motion. Apollo only counts headcount; this actor explains *what they're buying*.
- **RevOps & GTM intelligence** — score your ICP list weekly, build prospect lists from buying-intent tags, replace your stale $1-5K/mo intent-data line item.
- **Recruiters & talent intelligence** — track hiring velocity at competitors, see which functions/seniorities they're loading up on.
- **VC / corporate development** — detect Series A → C ramp signals, exec hires, geographic expansion. Headcount-delta tracking with KV-checkpointed monitoring.
- **Founders doing competitive intel** — type a competitor's domain, see every open role, every detected vendor, every team they're scaling.
- **AI / data teams** — a clean 30+ field unified ATS schema across 5 platforms with deterministic taxonomy normalization. Drop straight into a vector store or BI tool.

### How to use

1. Pick a **mode**:
   - `discover` — given domains, detect which ATS each one uses (cheap onboarding pass).
   - `jobs` — fetch normalized jobs only, no AI.
   - `signals` — jobs + Gemini intent tags + per-company composite signal (the value tier).
   - `monitor` — same as `signals` but only emits *deltas* vs. the previous run. Best with a daily/weekly schedule.
2. Provide either **`companyDomains`** (list of domains — auto-detected) or **`atsTargets`** (direct ATS slugs like `greenhouse:stripe`, `lever:palantir`, `ashby:linear`, `smartrecruiters:visa`, `workday:nvidia.wd5/NVIDIAExternalCareerSite`).
3. Optionally filter by `keywordFilter`, `functionFilter` (engineering / sales / …), `seniorityFilter`, `locationFilter`, `remoteOnly`, `postedWithinDays`.
4. Run. Results land in the default dataset with a `type` field discriminator: `job`, `company_signal`, `ats_discovery`, or `change_event`.
5. Export as **JSON, CSV, or Excel** from the Apify Console — or pull via API / webhook.
6. Want weekly intent updates? Set mode to `monitor` and schedule the actor. Subsequent runs only emit new/changed/closed roles + the latest composite signal.

**Free trial:** the first **10 chargeable events** of each run are on the house — enough to validate output shape and signal quality on a single small run before committing budget.

### Input examples

**1. Discover which ATS your top 5 prospects use.**

```json
{
    "mode": "discover",
    "companyDomains": ["stripe.com", "linear.app", "notion.so", "vercel.com", "anthropic.com"]
}
````

**2. Pull every open engineering role at 3 companies, no AI.**

```json
{
    "mode": "jobs",
    "companyDomains": ["stripe.com", "anthropic.com", "linear.app"],
    "functionFilter": ["engineering"],
    "seniorityFilter": ["senior", "lead", "principal"],
    "maxJobsPerCompany": 100
}
```

**3. Generate weekly buying signals across a 50-company prospect list.**

```json
{
    "mode": "signals",
    "companyDomains": [
        "stripe.com", "notion.so", "linear.app", "vercel.com", "anthropic.com"
    ],
    "maxJobsPerCompany": 50,
    "intentBatchSize": 20,
    "postedWithinDays": 30
}
```

**4. Monitor 200 companies — emit deltas only on the second-and-subsequent run.** (Schedule daily.)

```json
{
    "mode": "monitor",
    "companyDomains": ["acme.com", "..."],
    "maxJobsPerCompany": 100,
    "remoteOnly": false
}
```

**5. Skip auto-detection — pass direct ATS targets.**

```json
{
    "mode": "signals",
    "atsTargets": [
        "greenhouse:stripe",
        "lever:palantir",
        "ashby:linear",
        "smartrecruiters:visa",
        "workday:nvidia.wd5/NVIDIAExternalCareerSite"
    ]
}
```

### Output

Each row has a `type` discriminator. Sample enriched **job** record:

```json
{
    "type": "job",
    "sourceId": "d3bc1ced-3ce4-4086-a050-555055dbb1ff",
    "company": "Linear",
    "domain": "linear.app",
    "atsPlatform": "ashby",
    "atsSlug": "Linear",
    "title": "Senior / Staff Fullstack Engineer",
    "function": "engineering",
    "seniority": "senior",
    "department": "Product",
    "team": "Engineering",
    "location": "Europe",
    "isRemote": true,
    "employmentType": "FullTime",
    "postedDate": "2026-04-21T20:13:45.158+00:00",
    "applyUrl": "https://jobs.ashbyhq.com/linear/d3bc1ced-3ce4-4086-a050-555055dbb1ff/application",
    "intentTags": ["platform-build-out", "going-international"],
    "vendorSignals": ["TypeScript", "React", "GraphQL", "PostgreSQL", "Redis", "Kubernetes"],
    "intentSummary": "This role indicates a focus on expanding the core product platform and international growth.",
    "enrichmentLevel": "enriched"
}
```

Sample **company\_signal** record:

```json
{
    "type": "company_signal",
    "company": "Stripe",
    "atsPlatform": "greenhouse",
    "atsSlug": "stripe",
    "signal": "expanding-sales",
    "confidence": 1.0,
    "evidence": "8/8 open roles match this signal. Examples: Account Executive AI Sales, Account Executive AI Startups, Account Executive Commercial.",
    "vendorHypothesis": ["Stripe", "OpenAI", "Anthropic", "NVIDIA", "Shopify"],
    "openRolesCount": 8,
    "newRolesLast30d": 8,
    "topFunctions": [{ "function": "sales", "count": 8 }],
    "secondarySignals": [
        { "signal": "series-B-build", "confidence": 0.66, "evidence": "3/8 roles tagged." }
    ]
}
```

#### Data fields (selected)

| Field | Type | Notes |
|---|---|---|
| `type` | enum | `job` | `company_signal` | `ats_discovery` | `change_event` |
| `company` | string | Display name pulled from board metadata when available |
| `atsPlatform` | enum | `greenhouse` | `lever` | `ashby` | `smartrecruiters` | `workday` |
| `function` | enum | Normalized: `engineering`, `sales`, `marketing`, `product`, `data`, `design`, `operations`, `support`, `finance`, `hr`, `legal`, `other` |
| `seniority` | enum | `intern` | `junior` | `mid` | `senior` | `lead` | `principal` | `director` | `vp` | `cxo` | `unknown` |
| `intentTags` | array | 22-tag fixed taxonomy — see input schema for the full list |
| `vendorSignals` | array | Specific vendor / tech names mentioned in the JD |
| `intentSummary` | string | One-line plain-English takeaway from Gemini |
| `salaryMin` / `salaryMax` / `salaryCurrency` | numbers + ISO code | When the ATS exposes pay bands (Greenhouse + Ashby do) |
| `applyUrl` | string | Direct link to the application page |
| `signal` (on `company_signal`) | enum | The dominant intent tag, or `general-hiring` / `shrinking` / `stable` |
| `vendorHypothesis` | array | Top 8 vendors aggregated across the company's open roles |
| `changeType` (on `change_event`) | enum | `role-opened` | `role-closed` | `role-updated` | `salary-changed` |

### How much does it cost?

| Event | Price | Fires when |
|---|---|---|
| `apify-actor-start` | $0.0001 | Once per run (per GB of memory) |
| `basic-job-fetched` | **$0.0015** | A normalized job is emitted (modes: `jobs`) |
| `enriched-job-fetched` | **$0.008** | A Gemini-enriched job is emitted (modes: `signals`, `monitor`) |
| `company-signal-event` | **$0.05** | Composite buying signal per company (modes: `signals`, `monitor`) |
| `change-event` | **$0.02** | Role opened / closed / updated vs. previous run (modes: `monitor`, or any mode with `incrementalMode`) |
| `ats-discovered` | **$0.005** | Domain → ATS detection record (mode: `discover`) |

**First 10 chargeable events of every run are free** (built-in trial counter — see the run log).

#### Typical run costs

| Scenario | Volume | Cost |
|---|---|---|
| Discover ATS for 50 prospects | 50 discoveries | $0.25 |
| Pull 50 roles each from 10 companies | 500 basic jobs | ~$0.75 |
| Weekly signals run, 50 companies × 40 roles | 2,000 enriched + 50 signals | ~$18.50 |
| Daily monitor, 200 companies × 30 roles, ~3 deltas/co/day | 600 changes + 200 signals/day | ~$22/day |

**Comparison:** Apollo Pro $99/seat/mo (no signals), ZoomInfo + Bombora $3-5K/mo, Clay Growth $1.5-2.5K/mo, Cognism + intent ~$2K/mo. The 50-company weekly run above costs ~$80/mo — same job-to-be-done, ~5-25× cheaper than every comparable.

### Tips & advanced options

- **`monitor` mode is built for scheduling.** Set up an Apify schedule (daily or weekly), feed in your prospect list, and only pay for deltas + the latest composite signal. The first run charges full freight (everything is "new"); subsequent runs are deltas-only.
- **Workday note** — Workday tenants live at `tenant.wd{N}.myworkdayjobs.com` where N is 1-12. Use `workday:tenant.wdN/SiteSegment` form. Find the `wdN` from any URL on their careers page. Some Workday tenants throttle aggressive scraping — switch to `RESIDENTIAL` proxy if you see 403s.
- **Auto-detection covers ~25K-30K companies** out of the box (all Greenhouse, Lever, Ashby, SmartRecruiters customers + most Workday F500). For non-detectable domains, pass a direct `atsTargets` entry and the actor skips resolution.
- **Filter aggressively to control budget.** `functionFilter`, `seniorityFilter`, `locationFilter`, `remoteOnly`, `postedWithinDays` all run *before* Gemini enrichment, so you only pay enrichment cost on the roles that matter.
- **`intentBatchSize` = 20** is the cost-vs-latency sweet spot. Larger batches cost less per job but increase end-to-end latency.
- **Vendor signals are tools/tech mentioned in JDs**, not necessarily companies the prospect is buying. A role mentioning "Salesforce" usually means they use Salesforce — sometimes it means they sell to Salesforce customers. Cross-check with `intentSummary` for context.
- **Cross-ATS dedup** — if the same company is somehow listed twice (rare), dedup by `(atsPlatform, atsSlug)` downstream.

### Legal & ToS

- Every ATS endpoint used by this actor is publicly published and intended for third-party career-site / aggregator use. No login or API key required.
- Greenhouse Job Board API, Lever Postings API, Ashby Public Job Posting API, and SmartRecruiters Posting API are all explicitly documented as public — see [developers.greenhouse.io/job-board](https://developers.greenhouse.io/job-board.html), [github.com/lever/postings-api](https://github.com/lever/postings-api), [developers.ashbyhq.com/docs/public-job-posting-api](https://developers.ashbyhq.com/docs/public-job-posting-api), [developers.smartrecruiters.com/docs/posting-api](https://developers.smartrecruiters.com/docs/posting-api).
- Workday CXS endpoints serve the same data as the public-facing careers page; we paginate at default 20-per-page with gentle 150ms pacing.
- The actor is intended for sales intelligence, recruiting research, and market analysis. Do not use the data to discriminate, harass, or auto-apply at scale.
- Job descriptions are © the posting employer. We store and re-emit them verbatim for analysis. Do not republish full JDs as your own content.

### FAQ & support

**Q: Which ATSes are supported in v1?**
A: Greenhouse, Lever, Ashby, SmartRecruiters, Workday. BambooHR, Recruitee, Teamtailor, Personio in v1.1.

**Q: What's the difference between `signals` and `monitor`?**
A: `signals` runs the full pipeline every time. `monitor` does the same but auto-enables incremental mode — on subsequent runs you only see *new / changed / closed* roles, plus the refreshed company-signal record. Use `monitor` for scheduled subscriptions.

**Q: Why didn't my domain auto-detect?**
A: ~10-15% of companies use custom careers pages that don't link to a known ATS host. Pass an `atsTargets` entry directly. Also try the `discover` mode in isolation — it tells you what was found and what failed.

**Q: Can I get LinkedIn / Indeed jobs?**
A: No. This actor *only* scrapes companies' own ATS career pages. LinkedIn aggregations are heavily anti-botted and not worth the proxy cost. The data here is fresher anyway — it's the source ATS, not a 2nd-hand index.

**Q: Will the intent classifier hallucinate tags?**
A: The classifier is constrained to a fixed 22-tag taxonomy and instructed to return `["unknown"]` if uncertain. We've validated against ~100 real postings; false-positive rate is < 5%. If you see noise, lower the `intentBatchSize` to 5-8 (smaller context = sharper inference).

**Q: How do I report bugs?**
A: Open an issue on the actor's Apify page. Include the input JSON and the offending record's `sourceId` + `applyUrl`.

***

*Built with TypeScript on the Apify SDK. Zero proxies, zero anti-bot, native fetch. No headless browser, no CAPTCHA.*

# Actor input Schema

## `mode` (type: `string`):

What to do. 'discover' = given a list of company domains, detect which ATS each one uses and emit a discovery record (cheapest mode, used for prospect-list onboarding). 'jobs' = fetch normalized job postings only (no AI). 'signals' = jobs + Gemini-powered intent tags + per-company composite buying signals (premium). 'monitor' = same as 'signals' but auto-enables incremental mode and only emits changes vs. previous run (subscription use case).

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

List of company domains to track (e.g. 'stripe.com', 'notion.so'). The actor auto-detects which ATS each company uses (Greenhouse / Lever / Ashby / SmartRecruiters / Workday) and pulls all open roles. Best mode for prospect-list / sales-intel use cases.

## `atsTargets` (type: `array`):

Skip auto-detection by passing direct ATS targets in the form 'platform:slug'. Examples: 'greenhouse:stripe', 'lever:netflix', 'ashby:linear', 'smartrecruiters:visa', 'workday:nvidia.wd5.myworkdayjobs.com/External'. For Workday, include the full domain + tenant + site path. Faster than companyDomains because no resolution step.

## `keywordFilter` (type: `string`):

Free-text filter applied client-side after fetching. Matches against title + description. Example: 'platform engineer' or 'salesforce admin'. Leave blank for all roles.

## `functionFilter` (type: `array`):

Limit results to specific business functions. Multiple = OR-combined.

## `seniorityFilter` (type: `array`):

Limit results to specific seniority bands (normalized across ATSes). Multiple = OR-combined.

## `locationFilter` (type: `array`):

Free-text location substrings (e.g. 'United States', 'Remote', 'EMEA', 'San Francisco'). Multiple = OR-combined. Matches case-insensitive against the job's location string.

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

If true, drop any role whose normalized location/workplaceType doesn't indicate remote.

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

Drop roles older than this many days. 0 = no date filter. Defaults to 90 days.

## `enableIntent` (type: `boolean`):

Required for 'signals' and 'monitor' modes. When enabled, each job is run through Gemini 2.5 Flash to extract intent tags (e.g. 'expanding-sales', 'evaluating-CRM', 'series-B-build') and infer vendor/tech-stack signals (e.g. 'Salesforce', 'Snowflake', 'Kubernetes'). Adds $0.008 per enriched job. Auto-enabled in 'signals' and 'monitor' modes.

## `emitCompanySignals` (type: `boolean`):

After all jobs for a company are pulled, emit one composite buying-signal record per company (e.g. 'platform-engineering-build-out' with confidence + vendor hypothesis). Adds $0.05 per company. Requires enableIntent. Auto-enabled in 'signals' and 'monitor' modes.

## `intentBatchSize` (type: `integer`):

How many jobs to send to Gemini per request. Larger = cheaper per job but slower. Default 20 is the sweet spot.

## `incrementalMode` (type: `boolean`):

If enabled, the actor saves a fingerprint of each emitted job and, on the next run with the same input, only emits roles that are new, changed, or removed. Auto-enabled in 'monitor' mode. Use for scheduled daily/weekly runs.

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

Cap on jobs emitted per company. Big tech can have 5,000+ open roles — set this to control budget. 0 = no cap.

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

Hard cap on total dataset rows. Pagination + per-company collection stops once reached.

## `concurrency` (type: `integer`):

Parallel HTTP requests across companies. ATS APIs are fast and bot-friendly; default 8 is conservative.

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

ATS endpoints have no anti-bot. Leave empty unless you have a network policy. Workday tenants occasionally rate-limit aggressive scraping — switch to RESIDENTIAL if you see many 403s/429s.

## Actor input object example

```json
{
  "mode": "jobs",
  "companyDomains": [
    "linear.app",
    "vercel.com"
  ],
  "atsTargets": [],
  "keywordFilter": "",
  "functionFilter": [],
  "seniorityFilter": [],
  "locationFilter": [],
  "remoteOnly": false,
  "postedWithinDays": 90,
  "enableIntent": false,
  "emitCompanySignals": false,
  "intentBatchSize": 20,
  "incrementalMode": false,
  "maxJobsPerCompany": 10,
  "maxItems": 30,
  "concurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing jobs (basic + enriched), per-company signals, ATS discovery records, and (in monitor mode) change deltas — discriminated by the 'type' field.

# 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": [
        "linear.app",
        "vercel.com"
    ],
    "maxJobsPerCompany": 10,
    "maxItems": 30,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("constructive_calm/ats-hiring-intent-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 = {
    "companyDomains": [
        "linear.app",
        "vercel.com",
    ],
    "maxJobsPerCompany": 10,
    "maxItems": 30,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("constructive_calm/ats-hiring-intent-scraper").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 '{
  "companyDomains": [
    "linear.app",
    "vercel.com"
  ],
  "maxJobsPerCompany": 10,
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call constructive_calm/ats-hiring-intent-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=constructive_calm/ats-hiring-intent-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "ATS Hiring Intent - Buying Signals (Greenhouse + 4 ATSes)",
        "description": "Aggregates jobs across Greenhouse, Lever, Ashby, SmartRecruiters, and Workday with auto ATS detection from a domain. Gemini classifier emits per-company buying signals (expanding-sales, evaluating-CRM, platform-build-out). Monitor mode tracks 100s of companies weekly via KV deltas.",
        "version": "1.0",
        "x-build-id": "dqimAiH4jmAkJdhnx"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/constructive_calm~ats-hiring-intent-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-constructive_calm-ats-hiring-intent-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/constructive_calm~ats-hiring-intent-scraper/runs": {
            "post": {
                "operationId": "runs-sync-constructive_calm-ats-hiring-intent-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/constructive_calm~ats-hiring-intent-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-constructive_calm-ats-hiring-intent-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Scraping mode",
                        "enum": [
                            "discover",
                            "jobs",
                            "signals",
                            "monitor"
                        ],
                        "type": "string",
                        "description": "What to do. 'discover' = given a list of company domains, detect which ATS each one uses and emit a discovery record (cheapest mode, used for prospect-list onboarding). 'jobs' = fetch normalized job postings only (no AI). 'signals' = jobs + Gemini-powered intent tags + per-company composite buying signals (premium). 'monitor' = same as 'signals' but auto-enables incremental mode and only emits changes vs. previous run (subscription use case).",
                        "default": "jobs"
                    },
                    "companyDomains": {
                        "title": "Company domains",
                        "type": "array",
                        "description": "List of company domains to track (e.g. 'stripe.com', 'notion.so'). The actor auto-detects which ATS each company uses (Greenhouse / Lever / Ashby / SmartRecruiters / Workday) and pulls all open roles. Best mode for prospect-list / sales-intel use cases.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "atsTargets": {
                        "title": "Direct ATS targets (advanced)",
                        "type": "array",
                        "description": "Skip auto-detection by passing direct ATS targets in the form 'platform:slug'. Examples: 'greenhouse:stripe', 'lever:netflix', 'ashby:linear', 'smartrecruiters:visa', 'workday:nvidia.wd5.myworkdayjobs.com/External'. For Workday, include the full domain + tenant + site path. Faster than companyDomains because no resolution step.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywordFilter": {
                        "title": "Keyword filter (job title or description)",
                        "type": "string",
                        "description": "Free-text filter applied client-side after fetching. Matches against title + description. Example: 'platform engineer' or 'salesforce admin'. Leave blank for all roles.",
                        "default": ""
                    },
                    "functionFilter": {
                        "title": "Function filter",
                        "type": "array",
                        "description": "Limit results to specific business functions. Multiple = OR-combined.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "engineering",
                                "sales",
                                "marketing",
                                "operations",
                                "product",
                                "design",
                                "data",
                                "finance",
                                "hr",
                                "legal",
                                "support",
                                "other"
                            ],
                            "enumTitles": [
                                "Engineering",
                                "Sales",
                                "Marketing",
                                "Operations",
                                "Product",
                                "Design",
                                "Data / Analytics",
                                "Finance",
                                "HR / Recruiting",
                                "Legal",
                                "Customer Support",
                                "Other"
                            ]
                        },
                        "default": []
                    },
                    "seniorityFilter": {
                        "title": "Seniority filter",
                        "type": "array",
                        "description": "Limit results to specific seniority bands (normalized across ATSes). Multiple = OR-combined.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "intern",
                                "junior",
                                "mid",
                                "senior",
                                "lead",
                                "principal",
                                "director",
                                "vp",
                                "cxo"
                            ],
                            "enumTitles": [
                                "Intern",
                                "Junior / IC1",
                                "Mid / IC2",
                                "Senior / IC3",
                                "Lead / IC4",
                                "Principal / IC5+",
                                "Director",
                                "VP",
                                "C-suite"
                            ]
                        },
                        "default": []
                    },
                    "locationFilter": {
                        "title": "Location filter",
                        "type": "array",
                        "description": "Free-text location substrings (e.g. 'United States', 'Remote', 'EMEA', 'San Francisco'). Multiple = OR-combined. Matches case-insensitive against the job's location string.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "remoteOnly": {
                        "title": "Remote roles only",
                        "type": "boolean",
                        "description": "If true, drop any role whose normalized location/workplaceType doesn't indicate remote.",
                        "default": false
                    },
                    "postedWithinDays": {
                        "title": "Posted within N days",
                        "minimum": 0,
                        "maximum": 365,
                        "type": "integer",
                        "description": "Drop roles older than this many days. 0 = no date filter. Defaults to 90 days.",
                        "default": 90
                    },
                    "enableIntent": {
                        "title": "Enable Gemini intent enrichment (signals mode)",
                        "type": "boolean",
                        "description": "Required for 'signals' and 'monitor' modes. When enabled, each job is run through Gemini 2.5 Flash to extract intent tags (e.g. 'expanding-sales', 'evaluating-CRM', 'series-B-build') and infer vendor/tech-stack signals (e.g. 'Salesforce', 'Snowflake', 'Kubernetes'). Adds $0.008 per enriched job. Auto-enabled in 'signals' and 'monitor' modes.",
                        "default": false
                    },
                    "emitCompanySignals": {
                        "title": "Emit per-company composite signals",
                        "type": "boolean",
                        "description": "After all jobs for a company are pulled, emit one composite buying-signal record per company (e.g. 'platform-engineering-build-out' with confidence + vendor hypothesis). Adds $0.05 per company. Requires enableIntent. Auto-enabled in 'signals' and 'monitor' modes.",
                        "default": false
                    },
                    "intentBatchSize": {
                        "title": "Intent batch size",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "How many jobs to send to Gemini per request. Larger = cheaper per job but slower. Default 20 is the sweet spot.",
                        "default": 20
                    },
                    "incrementalMode": {
                        "title": "Incremental mode (deltas only)",
                        "type": "boolean",
                        "description": "If enabled, the actor saves a fingerprint of each emitted job and, on the next run with the same input, only emits roles that are new, changed, or removed. Auto-enabled in 'monitor' mode. Use for scheduled daily/weekly runs.",
                        "default": false
                    },
                    "maxJobsPerCompany": {
                        "title": "Max jobs per company",
                        "minimum": 0,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Cap on jobs emitted per company. Big tech can have 5,000+ open roles — set this to control budget. 0 = no cap.",
                        "default": 200
                    },
                    "maxItems": {
                        "title": "Max items (global cap)",
                        "minimum": 1,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Hard cap on total dataset rows. Pagination + per-company collection stops once reached.",
                        "default": 1000
                    },
                    "concurrency": {
                        "title": "Concurrent ATS fetches",
                        "minimum": 1,
                        "maximum": 25,
                        "type": "integer",
                        "description": "Parallel HTTP requests across companies. ATS APIs are fast and bot-friendly; default 8 is conservative.",
                        "default": 8
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "ATS endpoints have no anti-bot. Leave empty unless you have a network policy. Workday tenants occasionally rate-limit aggressive scraping — switch to RESIDENTIAL if you see many 403s/429s.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
