Greenhouse Hiring Signal Monitor
Under maintenancePricing
Pay per usage
Greenhouse Hiring Signal Monitor
Under maintenanceTracks hiring expansion, contraction, and job changes across public Greenhouse job boards.
What does Greenhouse Hiring Signal Monitor do?
Greenhouse Hiring Signal Monitor tracks hiring changes across companies that use Greenhouse job boards. It records a trusted baseline, compares later successful runs, and reports hiring expansion or contraction plus new, closed, updated, and reopened roles.
The Actor reads the public Greenhouse Job Board API directly. It does not render pages or parse job descriptions. On Apify, you can schedule repeated runs, call the Actor through the API, export Dataset records, connect integrations, and monitor run health.
Why use Greenhouse Hiring Signal Monitor?
The Actor is designed for repeated, evidence-based monitoring by:
- B2B sales teams looking for timely account signals
- recruiting agencies and headhunters tracking role demand
- competitive intelligence teams comparing hiring direction
- investors and researchers observing public workforce signals
It reports deterministic changes in public job postings. It does not claim to measure headcount, financial performance, or future company performance.
How to monitor Greenhouse hiring changes
- Open the Actor's Input tab.
- Add one or more Greenhouse board tokens or job board URLs.
- Run the Actor once to create a baseline.
- Schedule or manually run it again later.
- Review
company_summary,job_change, anderrorrecords in the Dataset. - Read the run-wide totals from the
OUTPUTrecord.
The first successful run never labels all existing jobs as NEW. It creates a baseline and displays: Baseline created. Run the Actor again later to detect hiring changes.
Input
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
companies | array of strings | Yes | — | Greenhouse board tokens or common Greenhouse job board URLs |
includeCurrentJobs | boolean | No | false | Also emit every currently open job as a current_job record |
Tokens and URLs that resolve to the same board are de-duplicated within a run.
{"companies": ["company-a","https://job-boards.greenhouse.io/company-b"],"includeCurrentJobs": false}
Output
Each successfully processed company emits its company_summary first, followed by any job_change records. When includeCurrentJobs is enabled, current jobs follow the changes. Failed companies emit a structured error record without stopping other companies.
{"record_type": "company_summary","company": "company-a","board_token": "company-a","baseline_created": false,"previous_job_count": 40,"current_job_count": 46,"net_change": 6,"change_percent": 15.0,"new_jobs": 7,"closed_jobs": 1,"updated_jobs": 2,"reopened_jobs": 0,"hiring_signal": "EXPANDING","run_at": "2026-01-15T12:00:00Z"}
{"record_type": "job_change","company": "company-a","board_token": "company-a","job_id": "123456","change_type": "UPDATED","title": "Senior Platform Engineer","department": "Engineering","location": "Remote - US","changed_fields": ["location"],"detected_at": "2026-01-15T12:00:00Z"}
You can download the Dataset in formats such as JSON, HTML, CSV, or Excel.
Output data table
| Record / field | Meaning |
|---|---|
company_summary | Counts, department movement, and hiring signal for one successful company fetch |
job_change | A NEW, CLOSED, UPDATED, or REOPENED job event |
current_job | Optional normalized open job, including first and last seen timestamps |
error | Safe company-level failure details |
department_changes | Current, new, and closed job counts grouped by department; missing departments use Unknown |
OUTPUT | Run totals, timestamps, success/failure counts, and compact company summaries |
Job changes use the stable Greenhouse job ID: NEW means an ID has never appeared in this state scope, CLOSED means a previously open ID is absent, UPDATED means only its title, department, or location changed, and REOPENED means a previously closed ID appeared again. Description-only edits do not create UPDATED records.
Hiring signals
Signals use the net job-count growth rate relative to the previous successful run:
| Rule | Signal |
|---|---|
| First successful run | BASELINE |
| Growth greater than 30% | STRONG_EXPANSION |
| Growth greater than 10% and at most 30% | EXPANDING |
| Growth from -10% through 10% | STABLE |
| Growth from -30% up to but not including -10% | CONTRACTING |
| Growth below -30% | STRONG_CONTRACTION |
When the previous count is zero, a positive current count is STRONG_EXPANSION; zero to zero is STABLE. change_percent is null when the previous count is zero.
How repeated monitoring works
The Actor stores each board's state in the named Apify Key-Value Store greenhouse-hiring-signal-monitor-v1-state. A named store is required because every Actor run receives a different default Key-Value Store. current_jobs represents the last successful open snapshot. known_jobs retains closed history, allowing a previously closed job ID to be classified as REOPENED. The run-wide OUTPUT summary remains in each run's default Key-Value Store.
State belongs to the Apify account that starts the run, so different Apify users do not share monitoring history. Within one account, direct Actor runs share one state scope. Runs of the same saved Actor Task share another task-specific scope, while different Tasks are isolated from each other. Each scope uses a separate deterministic key per normalized board token.
State is updated only after Greenhouse returns a successful HTTP response with valid JSON and a consistent job count. Timeouts, rate limits, HTTP errors, invalid JSON, and malformed responses do not replace the last valid state, so a failed fetch cannot close every previously open role.
For each company, complete Dataset records are written before the new state is committed in one Key-Value Store operation. If the final state write fails, the run reports an error and a later run can repeat the same change records instead of silently losing them.
For one state scope and board token, runs should not overlap. Apify Key-Value Store records use last-write-wins semantics, so two concurrent runs that read the same old snapshot can overwrite each other in completion order. Use one non-overlapping schedule per Task (or serialize direct runs) for the same board.
Pricing and cost estimation
This is a lightweight HTTP Actor: it normally makes one Greenhouse API request per unique company. Cost depends on the number of companies, run frequency, and Apify platform plan. Start with a small company list and inspect actual run usage before increasing schedule frequency. Apify's free tier may be sufficient for small validation runs; current platform limits and prices are controlled by Apify.
Tips
- Run at a consistent interval, such as daily or weekly, so changes are comparable.
- Keep
includeCurrentJobsdisabled when you only need changes and summaries. - Avoid overlapping runs for the same company and state scope.
- Treat board tokens as company identifiers; a company may operate more than one Greenhouse board.
- Investigate repeated
errorrecords before drawing conclusions from missing data.
Limitations, privacy, and support
- V1 supports Greenhouse only. It does not support Lever, Ashby, Workday, LinkedIn, notifications, dashboards, or AI analysis.
UPDATEDcompares only title, department, and location. Description edits are intentionally ignored.- Greenhouse controls public API availability and job board contents.
- Deleting or renaming the Actor's
greenhouse-hiring-signal-monitor-v1-stateKey-Value Store resets all baselines. - Concurrent runs for the same board and state scope are not locked; the last completed state write wins.
- The Actor reads public job board data and does not submit applications or collect candidate data.
- Public job postings are hiring signals, not proof of hiring, layoffs, or company performance.
Use this Actor responsibly and follow applicable laws, Greenhouse terms, and the target company's policies. For reproducible bugs or feature requests, open an issue in the GitHub repository.