Hiring Pulse
Pricing
from $4.00 / 1,000 company snapshots
Hiring Pulse
Monitors company ATS job boards over time and emits hiring-signal deltas: net role growth, new senior hires, first sales hire, function-mix shifts.
Pricing
from $4.00 / 1,000 company snapshots
Rating
0.0
(0)
Developer
Elliot Rose
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
hiring-pulse
Company hiring-signal monitor. Give it a list of company domains; it finds each company's applicant-tracking-system (ATS) job board, snapshots the currently open roles, and diffs that snapshot against the previous run (stored in a named key-value store so scheduled runs stay stateful). It sells the change — net growth, new senior hires, a first sales hire, function-mix shifts — not the job list itself.
Input
| Field | Type | Default | Description |
|---|---|---|---|
domains | string[] | — (required) | Company website domains, e.g. "acme.com". No protocol/path. |
atsOverrides | array | [] | [{domain, ats, token}] — skip discovery for a domain by declaring its ATS and board token directly. |
emitJobs | boolean | false | Also push one dataset row per currently open job. |
onlyChanged | boolean | false | After a company's first snapshot, skip pushing its signal row when nothing changed (delta 0, no new/closed roles). |
stateStoreName | string | "hiring-pulse-state" | Named key-value store used to persist ATS discovery cache (ats:{domain}) and job snapshots (snap:{domain}). |
maxConcurrency | integer | 5 | Max domains processed concurrently. |
Output
One signal row per domain per run in the default dataset, e.g.:
{"domain": "acme.com","ats": "greenhouse","token": "acme","open_roles": 24,"prev_open_roles": 19,"delta": 5,"new_roles": [{ "id": "4006", "title": "Director of Sales", "department": "Sales","location": "Remote", "remote": true,"url": "https://boards.greenhouse.io/acme/jobs/4006","posted_at": "2026-08-10T15:00:00-05:00", "seniority": "lead","function": "sales" }],"closed_roles": [],"new_titles": ["Director of Sales", "Senior Backend Engineer"],"senior_hires": [ /* Job objects with seniority in lead/exec/senior */ ],"first_sales_hire": true,"function_counts": { "engineering": 12, "sales": 3, "design": 2, "other": 7 },"function_deltas": { "engineering": 2, "sales": 1 },"remote_share": 0.58,"score": 27,"first_snapshot": false,"snapshot_at": "2026-08-29T09:00:00+00:00","prev_snapshot_at": "2026-08-15T09:00:00+00:00","urls": {"board_url": "https://boards.greenhouse.io/acme","career_page": "https://acme.com/careers"}}
With emitJobs: true, one additional row per currently open job is pushed
(the Job object plus domain/ats).
Companies whose ATS could not be identified still get a row, with
"ats": null, "open_roles": null, and "first_snapshot": true (see
Limitations).
Pricing events
Pay-per-event; wrap every charge in try/except so local runs (no PPE config) never crash.
| Event | Price | When |
|---|---|---|
company-snapshot | $0.004 | Once per pushed signal row. |
signal-event | $0.02 | Per changed role (new + closed), only after the first snapshot — i.e. you're charged for detected changes, not for the baseline. |
job-row | $0.0005 | Per pushed job row, only when emitJobs: true. |
MCP tools
This Actor is designed to back two MCP tools for agent/LLM callers:
get_hiring_signals(domain)— returns the latest signal row (and, if requested, recent history) for one company, backed by thesnap:{domain}and dataset rows this Actor produces.find_companies_hiring(role, stage)— surfaces companies whose latest signal shows growth in a given function (role, e.g. "engineering", "sales") and/or afirst_sales_hire/senior_hirespattern matching an early go-to-marketstage. Implement as a query over accumulatedcompany-snapshotrows across runs of this Actor.
Limitations
- Unknown/custom ATS: companies that don't use Greenhouse, Lever,
Ashby, SmartRecruiters, or Workable (or host a heavily customized/JS-only
careers page we can't parse without a browser) return
"ats": null. UseatsOverridesif you already know a company's board token, or extendsrc/ats.pywith a new adapter. - Discovery is a two-step heuristic (crawl known careers-page paths for a board link, then probe each ATS API with the domain's second-level label as a guessed token) — it can miss boards on non-obvious paths or under a token that doesn't match the domain name.
remoteisnull(notfalse) whenever the source location text has no clear remote/on-site signal — we never guess.- No Playwright/browser rendering: careers pages that only render job listings via client-side JS (no server-rendered link/iframe to the ATS) won't be discovered by the crawl step, only by the probe-by-token fallback.
- Seniority/function classification is keyword-based (see
src/classify.py) and works from the title/department strings alone — it will occasionally miscategorize unconventional title formats.