# Hiring-Signal & Job-Postings Intel - ATS, Surge, Tech Stack (`seibs.co/hiring-signal-intel`) Actor

Live job-postings intel from public ATS endpoints (Greenhouse, Lever, Ashby, Workday & more). Normalized postings plus a hiring-signal engine: net-new roles, role-count deltas, dept expansion, surge flags, and JD tech-stack detection. For B2B sales, recruiting, and alt-data. Public data only.

- **URL**: https://apify.com/seibs.co/hiring-signal-intel.md
- **Developed by:** [Seibs.co](https://apify.com/seibs.co) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 job-posting records

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

## Hiring-Signal & Job-Postings Intel

> **TL;DR for sales-intelligence, RevOps, recruiting, and alt-data teams:** Pulls live job postings straight off companies' public ATS feeds (Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, Workable, Workday), normalizes them into one clean schema, and layers a hiring-signal engine on top - net-new roles, role-count deltas, department expansion, and a **hiring-surge flag** per company, plus tech-stack detection parsed from each job description. Job postings are the richest *intent* signal in B2B (a surge in "ServiceTitan administrator" reqs = a home-services firm scaling). Indeed killed its public API in 2023 and LinkedIn Jobs is auth-walled, so there is no unified public job-market API - this actor uses the open-but-unmarketed ATS endpoints instead. Logged-out, public-data only. Free Apify plan covers exploration runs on your $5 platform credit.

### Run it in 30 seconds

```python
## Via the Apify Python SDK
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("seibs.co/hiring-signal-intel").call(run_input={
    "mode": "hiring_signals",
    "companies": ["stripe", "ramp", "notion"],
    "include_tech_stack": True
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
````

Or via curl:

```bash
curl -X POST "https://api.apify.com/v2/acts/seibs.co~hiring-signal-intel/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"mode": "hiring_signals", "companies": ["stripe", "ramp", "notion"], "include_tech_stack": true}'
```

Or click "Try for free" on this page if you prefer the no-code UI.

### What you get

Each run produces:

- A clean dataset, filterable in the Apify console and downloadable as CSV or JSON
- An OUTPUT.html dashboard preview of your top records
- A sample-output preview at [`.actor/sample-output.json`](./.actor/sample-output.json)

Per-archetype custom artifacts shipped with this actor:

- `hiring.csv` - every posting with company, role, department, seniority, remote flag, comp, tech stack, apply URL
- `hiring-followup.html` - per-company hiring-signal worksheet (which surge to route to which AE)

### Live example output

Real, unmodified output from runs against live company boards (no login required to view):

- **Hiring-surge showcase** (`hiring_signals` over Stripe, Ramp, Mistral, Notion, GitLab - spanning Greenhouse, Lever, and Ashby): every company surging with net-new roles flagged against its trailing baseline. [View the JSON](https://api.apify.com/v2/datasets/6L9KEArxLFWECqFyC/items?clean=true)
- **Clean job-postings feed** (`company_jobs`, same companies): normalized postings with department, seniority, remote flag, comp where exposed, and detected tech stack. [View the JSON](https://api.apify.com/v2/datasets/wp9UX6AIqxuzsfP2B/items?clean=true)

### What does Hiring-Signal Intel do?

It hits the public ATS JSON endpoints that companies expose for their own careers pages - the same feeds that power their public job boards - and normalizes every open role into one schema: `company`, `title`, `department` (+ a normalized function bucket), `location`, `remote_flag`, `seniority`, `comp_min/max` (where the ATS exposes pay-transparency ranges), `posted_at`, `apply_url`, and `ats_source`. Then it computes the **hiring-signal layer**: how many roles are net-new since the last run, which departments are expanding, and whether the company crossed a hiring-surge threshold. Finally it parses each job description for **named software** (`Salesforce`, `ServiceTitan`, `Snowflake`, `Procore`, ...) - the tech-stack buying signal B2B sellers key off.

### Responsible use / data scope

This actor is a **public-data tool**. It reads only logged-out, publicly-served ATS endpoints (a company's own careers feed) - no accounts, no cookies, no paywalls, no login walls. It minimizes PII: records carry role / department / location, not personal data, and recruiter names are never stored. You are responsible for lawful use of the outputs (GDPR / CCPA apply to personal data even when public). We deliberately scope to public job postings and government/open sources rather than auth-walled platforms.

### AI / RAG / Agent

A turn-key intent feed for sales-AI agents, RevOps copilots, and recruiting bots. Postings arrive pre-normalized with `seniority`, `department_normalized`, `remote_flag`, and `tech_stack` so an agent can filter on "Sales roles mentioning Salesforce at companies hiring 3+ net-new this week" without parsing raw HTML. Compatible with **LangChain**, **LlamaIndex**, **Pinecone**, **Weaviate**, **Chroma**, and any **MCP**-aware agent runtime (see the sibling `mcp-hiring-signal-intel` actor for direct tool-call wiring with agentic payments).

### Features

- **7 public ATS connectors** - Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, Workable, Workday. No auth, no anti-bot.
- **Auto-resolve** - pass a bare company slug and the actor tries each ATS in order until it finds the board. Or pass explicit `ats_boards`, or a careers-page URL to sniff.
- **Normalized schema** - one shape across all sources, with `seniority` and `department_normalized` inferred.
- **Hiring-signal engine** - net-new roles, removed roles, role-count delta (absolute + %), department expansion, new departments, and a `hiring_surge_flag` vs a trailing baseline persisted between runs.
- **Tech-stack detection** - 45+ named software products parsed from each JD (CRM, ERP, data/cloud, vertical ops, languages).
- **Comp extraction** - pay-transparency ranges where the ATS exposes them (Lever `salaryRange`, Ashby `compensation`, Greenhouse pay metadata).
- **Monitor mode** - run under an Apify Schedule and get only the change-delta (new / changed / removed) plus an optional Slack digest.
- **Cost-control** - per-run budget guard + demo-mode soft-fail so runs finish SUCCEEDED.

### Use cases

- **B2B sales intelligence** - a hiring surge = budget + a team being built; route surging companies to the AE who owns them. This is the live-data engine behind the [b2b-sales-triggers](https://apify.com/seibs.co/b2b-sales-triggers) actor.
- **Tech-stack targeting** - find every company hiring for "Procore" / "Salesforce admin" / "Snowflake" and sell the adjacent / displacement product.
- **Recruiting & staffing** - a live req feed across a watchlist of target companies, deduped by `job_id`.
- **Headcount / alt-data research** - track open-role counts and department mix over time as a growth proxy.
- **Vertical lead-gen** - a posting is a buying signal for every vertical lead-finder in the portfolio.

### Modes

| Mode | What it returns |
|---|---|
| `company_jobs` | Every current open role for the given companies/boards. |
| `hiring_signals` | Postings **plus** a per-company hiring-signal rollup (net-new roles, role-count delta, department expansion, surge flag) vs a trailing baseline. |
| `new_roles` | Only the postings that are net-new since the last run (a clean delta feed), plus the rollup. |

### Resolving companies (three ways)

1. **`companies`** - bare slugs, auto-resolved across ATS providers: `["stripe", "ramp"]`. The slug is the company id in its careers URL (e.g. `stripe` in `boards.greenhouse.io/stripe`).
2. **`ats_boards`** - explicit when you know the ATS: `[{"ats": "greenhouse", "slug": "stripe"}]`. Workday needs `{"ats": "workday", "host": "company.wd1.myworkdayjobs.com", "tenant": "company", "site": "External", "slug": "company"}`.
3. **`careers_urls`** - paste a company careers page; the actor sniffs the embedded ATS board: `["https://www.example.com/careers"]`.

### Input

See [`.actor/input_schema.json`](./.actor/input_schema.json) for the full form. Key fields:

```json
{
    "mode": "hiring_signals",
    "companies": ["stripe", "ramp", "notion"],
    "departments": ["Sales", "Engineering"],
    "keywords": ["salesforce", "revenue operations"],
    "include_tech_stack": true,
    "remote_only": false,
    "max_results_per_company": 200
}
```

No API key or login is required - ATS endpoints are public.

### Output

One `hiring_signal` record per company (in signal modes) followed by one `posting` record per open role.

```json
{
    "record_type": "hiring_signal",
    "company": "Ramp",
    "ats_source": "greenhouse",
    "current_open_roles": 71,
    "baseline_open_roles": 58,
    "net_new_role_count": 13,
    "role_count_delta_pct": 0.2241,
    "department_expansion": [{"department": "Sales", "from": 14, "to": 22, "delta": 8}],
    "hiring_surge_flag": true,
    "surge_reason": "13 net-new roles since last run (>= 3)"
}
```

```json
{
    "record_type": "posting",
    "company": "Ramp",
    "title": "Revenue Operations Manager",
    "department_normalized": "Sales",
    "seniority": "manager",
    "location": "New York, NY",
    "remote_flag": false,
    "comp_min": 145000,
    "comp_max": 185000,
    "comp_currency": "USD",
    "tech_stack": ["Salesforce", "Looker", "Outreach"],
    "apply_url": "https://boards.greenhouse.io/ramp/jobs/7412931"
}
```

Failed board lookups still emit a `fetch_error` record with a `reason` for completeness audit.

### Pricing

Pay-per-event:

| Event | Price | When charged |
|---|---|---|
| `posting_record` | $0.002 ($2/1k) | Per normalized open role returned (the public ATS base layer, priced at the competitive market band). |
| `tech_stack_signal` | $0.007 | When `include_tech_stack=true` and >= 1 named tool is detected in a JD. |
| `hiring_surge_flag` | $0.012 | Once per company that crosses the surge threshold vs its baseline (the premium B2B trigger). |
| `scheduled_delta_run` | $0.050 | Once per scheduled monitor-mode run. |

A run that returns nothing costs nothing. A typical 3-company `hiring_signals` run (~50 roles each) with tech detection costs roughly $0.30 - $0.70 depending on how many roles each company has open and how many mention named software.

### FAQ

**Q: Is this legal?**
A: This actor reads only logged-out, public ATS endpoints - the same data a company serves on its own public careers page. No login, no cookies, no paywall. It minimizes PII (no personal/candidate data, no recruiter names). You remain responsible for lawful use of the outputs (GDPR/CCPA apply to personal data even when public). See the "Responsible use / data scope" note above.

**Q: How is this different from an Indeed or LinkedIn jobs scraper?**
A: Those hit auth-walled, anti-bot platforms (Indeed deprecated its public API in 2023; LinkedIn requires login). This actor uses companies' own public ATS feeds - no auth, no anti-bot - and adds the intelligence layer: hiring-surge detection, department-expansion deltas, and JD tech-stack parsing that a raw scraper doesn't give you.

**Q: How do I find a company's ATS slug?**
A: Look at its careers URL. `boards.greenhouse.io/<slug>`, `jobs.lever.co/<slug>`, `jobs.ashbyhq.com/<slug>`, `jobs.smartrecruiters.com/<slug>`, `<slug>.recruitee.com`, `<slug>.workable.com`. Or just pass the careers-page URL in `careers_urls` and let the actor detect it.

**Q: How does the hiring-surge flag work?**
A: The actor stores a small per-company baseline (job ids + department counts) between runs in a persistent KVStore. On the next run it compares the current open roles against that baseline. A company is flagged when it has >= `surge_abs_threshold` net-new roles (default 3) OR its open-role count grew by >= `surge_pct_threshold` (default 20%). The first run for a company establishes the baseline (`first_run: true`, no surge).

**Q: Why might a run return a fetch\_error?**
A: Usually a renamed/typo'd ATS slug, or a company that uses an ATS this actor doesn't support yet. The run still finishes SUCCEEDED and emits a `fetch_error` record naming the board so you can correct it.

**Q: Can I schedule this?**
A: Yes. Daily or weekly cron on a saved Task gives you a hands-off hiring-surge feed. Pair with monitor mode (below) so you only get the delta.

### Save your input as an Apify Task

Apify Tasks let you save a configured input once and re-run it with one click - the foundation for schedules, monitor mode, and the hiring-surge baseline (the baseline is most useful when the same company list runs on a cadence).

1. Click `Run` with your input configured.
2. Click `Save as task`.
3. Name it (e.g. `target-account hiring surge - weekly`).
4. Reload the task page and click `Start` anytime.

### Run this weekly with Apify Schedules

1. Save your input as a Task (above).
2. Go to https://console.apify.com/schedules and `Create new schedule`.
3. Pick your Task and set a cron expression (weekly Mondays 9am: `0 9 * * 1`).
4. Save. Each run refreshes the baseline and surfaces the week's net-new roles and surging companies.

### Monitor mode (beta)

When this actor runs under an Apify Schedule, monitor mode emits only the change-delta (new / changed / removed postings) instead of the full set, with a digest record at the top. Provide `monitor_webhook_url` and the digest also fires to your Slack channel. Cost: one `scheduled_delta_run` event ($0.05) per scheduled run plus standard PPE on emitted delta records only.

### Related Actors

- [b2b-sales-triggers](https://apify.com/seibs.co/b2b-sales-triggers) - turn a hiring surge into an outbound sales trigger for your AE/SDR team. This actor is its live job-postings engine.
- [sec-edgar-intel](https://apify.com/seibs.co/sec-edgar-intel) - pair hiring surges with Form D raises and 8-K events for a full "this company is scaling" picture.
- [local-leads-without-websites](https://apify.com/seibs.co/local-leads-without-websites) - SMB prospects to layer hiring + intent signals on top of.

### Support

Open an issue via the Apify Store contact link. Include the run ID and input config so the issue is reproducible.

### Changelog

See [CHANGELOG.md](./CHANGELOG.md).

### Found this useful?

If this actor saved you time or money, please leave a quick review on the Apify Store. Reviews help other buyers find work that solves their problem: https://apify.com/seibs.co/hiring-signal-intel#reviews

# Actor input Schema

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

company\_jobs = every current open role for the given companies. hiring\_signals = postings PLUS a per-company hiring-signal rollup (net-new roles, role-count delta, department expansion, surge flag) vs a trailing baseline. new\_roles = only postings that are net-new since the last run (delta feed) plus the rollup.

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

Bare company slugs to auto-resolve across ATS providers (tries Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, Workable in order). The slug is the company id in its careers URL, e.g. 'stripe' from boards.greenhouse.io/stripe or jobs.lever.co/stripe. Hard cap of 50.

## `ats_boards` (type: `array`):

Explicit boards when you already know the ATS. Each item: {"ats": "greenhouse|lever|ashby|smartrecruiters|recruitee|workable", "slug": "<company-slug>"}. For Workday add {"ats": "workday", "host": "company.wd1.myworkdayjobs.com", "tenant": "company", "site": "External", "slug": "company"}. Hard cap of 50.

## `careers_urls` (type: `array`):

Company careers/jobs page URLs. The actor fetches the page and detects an embedded Greenhouse/Lever/Ashby/SmartRecruiters/Recruitee/Workable board, then pulls its postings. Lowest-effort path when you only have a website. Hard cap of 50.

## `keywords` (type: `array`):

Keep only postings whose title, department, or description contains one of these terms (case-insensitive). E.g. \['salesforce admin', 'procore', 'revenue operations']. Leave empty for all roles. Hard cap of 30.

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

Keep only postings in these (normalized) departments: Engineering, Sales, Marketing, Product, Design, Customer Success, Finance, People, Operations, Legal. Leave empty for all.

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

Keep only postings whose location contains one of these substrings (e.g. \['New York', 'Remote', 'London']). Leave empty for all.

## `remote_only` (type: `boolean`):

Keep only postings flagged as remote.

## `include_tech_stack` (type: `boolean`):

Parse each job description for named software (Salesforce, HubSpot, ServiceTitan, Procore, Snowflake, AWS, etc.) - the named-software buying signal. Adds a tech\_stack\_signal PPE charge per posting with >= 1 tool detected.

## `include_full_description` (type: `boolean`):

Embed the full job-description text in each record (records grow larger). When off, a 600-char snippet is included. No extra charge either way.

## `surge_abs_threshold` (type: `integer`):

A company is flagged as surging when it has at least this many net-new roles since the last run. Default 3.

## `surge_pct_threshold` (type: `number`):

A company is also flagged when its open-role count grows by at least this fraction vs the baseline (0.20 = 20%). Default 0.20.

## `max_results_per_company` (type: `integer`):

Hard cap on postings returned per company/board. Default 200.

## `contact_email` (type: `string`):

Optional contact email added to the User-Agent so the ATS providers can reach you. Good-citizen practice; not required.

## `monitor_webhook_url` (type: `string`):

When this actor runs under an Apify Schedule (monitor mode), post the change digest to this Slack-compatible webhook URL.

## `use_apify_proxy` (type: `boolean`):

Route ATS requests through Apify Proxy. DATACENTER is sufficient - public ATS JSON endpoints are not anti-bot protected.

## `apify_proxy_groups` (type: `array`):

Apify Proxy groups. DATACENTER is fine for public ATS endpoints.

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

Parallel board fetches. Default 6.

## Actor input object example

```json
{
  "mode": "hiring_signals",
  "companies": [
    "stripe",
    "ramp",
    "notion"
  ],
  "ats_boards": [],
  "careers_urls": [],
  "keywords": [],
  "departments": [],
  "locations": [],
  "remote_only": false,
  "include_tech_stack": true,
  "include_full_description": false,
  "surge_abs_threshold": 3,
  "surge_pct_threshold": 0.2,
  "max_results_per_company": 50,
  "contact_email": "",
  "monitor_webhook_url": "",
  "use_apify_proxy": true,
  "apify_proxy_groups": [
    "DATACENTER"
  ],
  "concurrency": 6
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Narrow, token-efficient slice of every record. Consumer: LLM agents (Claude, GPT, LangChain tools), MCP hosts, sales dashboards.

## `datasetItemsSignals` (type: `string`):

Per-company surge/delta rollup: net-new roles, role-count delta, department expansion, surge flag. Consumer: B2B sales-trigger pipelines, revenue ops, equity/headcount research.

## `datasetItemsPostings` (type: `string`):

All postings with full normalized fields. Consumer: humans browsing, RAG ingest, ATS/CRM export.

## `datasetItemsMcp` (type: `string`):

First 50 overview records as a clean JSON array. Wrap on the agent side in an MCP tool-call envelope. Consumer: MCP servers, Claude Desktop, Cursor, OpenAI Assistants tool calls.

## `datasetItemsCsv` (type: `string`):

Spreadsheet-friendly export of the overview view. Consumer: sales-ops teams, Excel / Google Sheets users.

# 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 = {
    "mode": "hiring_signals",
    "companies": [
        "stripe",
        "ramp",
        "notion"
    ],
    "max_results_per_company": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("seibs.co/hiring-signal-intel").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 = {
    "mode": "hiring_signals",
    "companies": [
        "stripe",
        "ramp",
        "notion",
    ],
    "max_results_per_company": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("seibs.co/hiring-signal-intel").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 '{
  "mode": "hiring_signals",
  "companies": [
    "stripe",
    "ramp",
    "notion"
  ],
  "max_results_per_company": 50
}' |
apify call seibs.co/hiring-signal-intel --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Hiring-Signal & Job-Postings Intel - ATS, Surge, Tech Stack",
        "description": "Live job-postings intel from public ATS endpoints (Greenhouse, Lever, Ashby, Workday & more). Normalized postings plus a hiring-signal engine: net-new roles, role-count deltas, dept expansion, surge flags, and JD tech-stack detection. For B2B sales, recruiting, and alt-data. Public data only.",
        "version": "0.1",
        "x-build-id": "YD110OhoC7Om1wADM"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/seibs.co~hiring-signal-intel/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-seibs.co-hiring-signal-intel",
                "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/seibs.co~hiring-signal-intel/runs": {
            "post": {
                "operationId": "runs-sync-seibs.co-hiring-signal-intel",
                "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/seibs.co~hiring-signal-intel/run-sync": {
            "post": {
                "operationId": "run-sync-seibs.co-hiring-signal-intel",
                "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": "Mode",
                        "enum": [
                            "company_jobs",
                            "hiring_signals",
                            "new_roles"
                        ],
                        "type": "string",
                        "description": "company_jobs = every current open role for the given companies. hiring_signals = postings PLUS a per-company hiring-signal rollup (net-new roles, role-count delta, department expansion, surge flag) vs a trailing baseline. new_roles = only postings that are net-new since the last run (delta feed) plus the rollup.",
                        "default": "hiring_signals"
                    },
                    "companies": {
                        "title": "Companies (ATS slug, auto-resolved)",
                        "maxItems": 50,
                        "type": "array",
                        "description": "Bare company slugs to auto-resolve across ATS providers (tries Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee, Workable in order). The slug is the company id in its careers URL, e.g. 'stripe' from boards.greenhouse.io/stripe or jobs.lever.co/stripe. Hard cap of 50.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "ats_boards": {
                        "title": "Explicit ATS boards (skip auto-resolve)",
                        "maxItems": 50,
                        "type": "array",
                        "description": "Explicit boards when you already know the ATS. Each item: {\"ats\": \"greenhouse|lever|ashby|smartrecruiters|recruitee|workable\", \"slug\": \"<company-slug>\"}. For Workday add {\"ats\": \"workday\", \"host\": \"company.wd1.myworkdayjobs.com\", \"tenant\": \"company\", \"site\": \"External\", \"slug\": \"company\"}. Hard cap of 50.",
                        "default": []
                    },
                    "careers_urls": {
                        "title": "Careers-page URLs (auto-sniff the ATS)",
                        "maxItems": 50,
                        "type": "array",
                        "description": "Company careers/jobs page URLs. The actor fetches the page and detects an embedded Greenhouse/Lever/Ashby/SmartRecruiters/Recruitee/Workable board, then pulls its postings. Lowest-effort path when you only have a website. Hard cap of 50.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Keyword filter",
                        "maxItems": 30,
                        "type": "array",
                        "description": "Keep only postings whose title, department, or description contains one of these terms (case-insensitive). E.g. ['salesforce admin', 'procore', 'revenue operations']. Leave empty for all roles. Hard cap of 30.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "departments": {
                        "title": "Department filter",
                        "type": "array",
                        "description": "Keep only postings in these (normalized) departments: Engineering, Sales, Marketing, Product, Design, Customer Success, Finance, People, Operations, Legal. Leave empty for all.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "locations": {
                        "title": "Location filter",
                        "type": "array",
                        "description": "Keep only postings whose location contains one of these substrings (e.g. ['New York', 'Remote', 'London']). Leave empty for all.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "remote_only": {
                        "title": "Remote roles only",
                        "type": "boolean",
                        "description": "Keep only postings flagged as remote.",
                        "default": false
                    },
                    "include_tech_stack": {
                        "title": "Detect tech stack in job descriptions",
                        "type": "boolean",
                        "description": "Parse each job description for named software (Salesforce, HubSpot, ServiceTitan, Procore, Snowflake, AWS, etc.) - the named-software buying signal. Adds a tech_stack_signal PPE charge per posting with >= 1 tool detected.",
                        "default": true
                    },
                    "include_full_description": {
                        "title": "Include full job description text",
                        "type": "boolean",
                        "description": "Embed the full job-description text in each record (records grow larger). When off, a 600-char snippet is included. No extra charge either way.",
                        "default": false
                    },
                    "surge_abs_threshold": {
                        "title": "Hiring-surge: net-new roles threshold",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "A company is flagged as surging when it has at least this many net-new roles since the last run. Default 3.",
                        "default": 3
                    },
                    "surge_pct_threshold": {
                        "title": "Hiring-surge: growth-rate threshold",
                        "minimum": 0.01,
                        "maximum": 10,
                        "type": "number",
                        "description": "A company is also flagged when its open-role count grows by at least this fraction vs the baseline (0.20 = 20%). Default 0.20.",
                        "default": 0.2
                    },
                    "max_results_per_company": {
                        "title": "Max postings per company",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Hard cap on postings returned per company/board. Default 200.",
                        "default": 200
                    },
                    "contact_email": {
                        "title": "Contact email (optional, for User-Agent)",
                        "type": "string",
                        "description": "Optional contact email added to the User-Agent so the ATS providers can reach you. Good-citizen practice; not required.",
                        "default": ""
                    },
                    "monitor_webhook_url": {
                        "title": "Monitor webhook URL (Slack / email, optional)",
                        "type": "string",
                        "description": "When this actor runs under an Apify Schedule (monitor mode), post the change digest to this Slack-compatible webhook URL.",
                        "default": ""
                    },
                    "use_apify_proxy": {
                        "title": "Use Apify Proxy",
                        "type": "boolean",
                        "description": "Route ATS requests through Apify Proxy. DATACENTER is sufficient - public ATS JSON endpoints are not anti-bot protected.",
                        "default": true
                    },
                    "apify_proxy_groups": {
                        "title": "Proxy groups",
                        "type": "array",
                        "description": "Apify Proxy groups. DATACENTER is fine for public ATS endpoints.",
                        "default": [
                            "DATACENTER"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "concurrency": {
                        "title": "Max concurrent requests",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Parallel board fetches. Default 6.",
                        "default": 6
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
