Hiring Signals Tracker: Job Openings by Company
Pricing
from $4.00 / 1,000 company report delivereds
Hiring Signals Tracker: Job Openings by Company
Hiring signals tracker for company job boards on Greenhouse, Lever and Ashby: per company, the count of job openings, open roles by department and location, new job postings, roles opened and closed since the last run, and your role rules. A job board monitor: schedule it to track company hiring.
Pricing
from $4.00 / 1,000 company report delivereds
Rating
0.0
(0)
Developer
Edge
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
Hiring signals tracker for company job boards on Greenhouse, Lever and Ashby: per company, the count of job openings, open roles by department and location, new job postings, roles opened and closed since the last run, and your role rules. A job board monitor: schedule it to track company hiring. Try it: run the prefilled input (GitLab on Greenhouse, Palantir on Lever, Linear on Ashby) and open the Hiring signals by company table.
What it does
Give it the job boards of the companies you follow; it returns one report per company. Each report counts open roles by department and location, applies your own role rules, and says how many roles opened and closed since the last run. It reads the public job board endpoints of Greenhouse, Lever and Ashby. It honours robots.txt and its Crawl-delay on every host it reads: when a host states a Crawl-delay, the Actor waits at least that long between two requests to that host (a value over 30 seconds is honoured as 30 seconds and noted in the run summary).
Who uses it
- Sales teams who treat new openings in a department as a buying signal ("three new data engineering roles at this account").
- Investors and analysts who watch hiring at a list of companies week by week.
- Recruiters who track where competitors are hiring.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
boards | list | required | Board addresses such as https://boards.greenhouse.io/<board>, https://jobs.lever.co/<board>, https://jobs.ashbyhq.com/<board>, or objects {"platform": "lever", "slug": "<board>"} |
rules | list of objects | empty | {"name": "sales", "titleKeywords": ["account executive"], "departments": ["Sales"]}: counts the open roles whose title contains a keyword as a whole word (letters and digits of any alphabet belong to a word, so rations does not match Opérations) and, when departments are given, whose department or team is one of them |
deltaMode | true or false | true | Compares with the last run that read the same board |
Output
One record per company board. A board that cannot be read gives one record with status set to not_found, blocked or error.
Before it reads a board, the Actor reads the robots.txt of the board's host, once per host per run. When that robots.txt does not allow this Actor, the board gives one blocked record with error set to robots_disallow. When that robots.txt cannot be read (a server error, a "too many requests" answer, a timeout, a network failure, a redirect to another site or more than five redirects), the board gives one error record with error set to robots_unreadable. A redirect of robots.txt inside the same site is followed. When a host name does not resolve, the board gives one error record with error set to name_not_resolved. In both cases nothing is read from the board, nothing is charged and nothing is remembered. A robots.txt that answers with another 4xx code, such as 404, counts as no rules.
When the departments list of a Greenhouse board cannot be read (a request that still fails after three retries, or a robots.txt that disallows it), the board gives one error record with error set to departments_unreadable instead of a report with every role under unknown: not charged and not remembered.
Board names are read in lower case, so boards.greenhouse.io/GitLab and boards.greenhouse.io/gitlab are one board, read and charged once. Every record keeps the board as you gave it in board_input.
Sample record (SYNTHETIC: example.com data, not a real company):
{"id": "greenhouse:examplecorp","platform": "greenhouse","company_slug": "examplecorp","open_roles": 42,"new_roles_since_last_run": 3,"closed_roles_since_last_run": 1,"first_run": false,"by_department": {"Engineering": 20, "Sales": 12, "Support": 10},"by_location": [{"location": "Remote, Europe", "count": 18}, {"location": "Berlin", "count": 14}, {"location": "London", "count": 10}],"rule_matches": [{"name": "data", "count": 4, "examples": [{"title": "Senior Data Engineer", "job_url": "https://jobs.example.com/examplecorp/101"}]}],"new_role_examples": [{"title": "Senior Data Engineer", "job_url": "https://jobs.example.com/examplecorp/101"}],"closed_role_examples": [{"title": "Office Manager", "job_url": null}],"source_url": "https://api.example.com/v1/boards/examplecorp/jobs","fetched_at": "2026-10-07T18:00:00Z","status": "ok","error": null,"error_detail": null}
Sample record (REAL: the board ashby:linear of the prefilled input, read 2026-10-08T01:55:11Z on a first run with no memory, so the new and closed fields are null):
{"id": "ashby:linear","platform": "ashby","company_slug": "linear","open_roles": 31,"new_roles_since_last_run": null,"closed_roles_since_last_run": null,"first_run": true,"by_department": {"GTM": 16, "Operations": 2, "Product": 13},"by_location": [{"count": 16, "location": "North America"}, {"count": 8, "location": "Europe"}, {"count": 3, "location": "North America; Europe"}, {"count": 2, "location": "London"}, {"count": 2, "location": "Singapore"}],"rule_matches": [{"count": 12, "examples": [{"job_url": "https://jobs.ashbyhq.com/linear/d3bc1ced-3ce4-4086-a050-555055dbb1ff", "title": "Senior / Staff Fullstack Engineer"}, {"job_url": "https://jobs.ashbyhq.com/linear/cd5ae036-0223-427a-b038-ba16ef9dcb32", "title": "Senior / Staff Fullstack Engineer"}, {"job_url": "https://jobs.ashbyhq.com/linear/069c4628-88d7-4e4d-b393-c996fc7f3076", "title": "Senior / Staff Product Engineer"}], "name": "engineering"}, {"count": 3, "examples": [{"job_url": "https://jobs.ashbyhq.com/linear/c21af93e-210f-4969-8eaa-90fb16a5b720", "title": "Account Executive, Startups"}, {"job_url": "https://jobs.ashbyhq.com/linear/cb8e77a6-4316-45c6-ac8d-7ade980cd65e", "title": "Account Executive, Growth"}, {"job_url": "https://jobs.ashbyhq.com/linear/6dd5500a-4bd4-4f57-ba09-7b07acefecf4", "title": "Account Executive, Enterprise"}], "name": "sales"}],"new_role_examples": null,"closed_role_examples": null,"source_url": "https://api.ashbyhq.com/posting-api/job-board/linear?includeCompensation=true","fetched_at": "2026-10-08T01:55:11Z","status": "ok","error": null,"error_detail": null}
Field rules: on the first run for a board, first_run is true and new_roles_since_last_run and closed_roles_since_last_run are empty (null), not zero, because there is nothing to compare with. by_department uses the department a board gives, or the team when the board has no departments, or unknown. by_location lists the five most frequent location texts. Rule examples are real open roles of that board, up to three. Closed roles keep only the title the Actor remembered.
What a run costs
The price is $4.00 per 1,000 company reports, plus the platform's start fee of $0.00005 per run (charged once, because the Actor runs with at most 1 GB of memory). A run over 100 boards costs $0.40005. Boards that fail are not charged.
Limits and what it will not do
- Three platforms in this version: Greenhouse, Lever, Ashby. Other addresses give an
unsupported_boardrecord. - SmartRecruiters boards are not read. The robots.txt of its API host (
api.smartrecruiters.com, read 2026-10-08) allows one other agent and disallows all others, so a SmartRecruiters address gives oneblockedrecord witherrorset torobots_disallow, not charged. - The comparison is per board: adding a board to the list does not reset the others, and a board seen for the first time starts with empty new and closed counts. Two schedules that read the same board share one comparison point, so each sees the changes since whichever of them ran last. Turning
deltaModeoff neither reads nor writes the memory. - The memory keeps, per open role, its id, title, department and the day it was first seen, in the named key-value store
hiring-signals-stateof your account. No posting text is kept. - Up to 100 pages per board; at most 2 requests per second per platform; GET requests only.
- Each board has a time budget of 300 seconds, its robots.txt included. A board that is not read in full within it gives one
errorrecord witherrorset totime_budget_exceeded: what was read is dropped, not charged and not remembered, and the next board starts with its own budget. - It reads public job board endpoints only: no login, no cookies, no proxies, no browser. A block is reported as
blocked, never worked around. - It identifies itself as
edge-hiring-signals/0.2in every request. A site owner can block it in robots.txt withUser-agent: edge-hiring-signalsandDisallow: /. It never pretends to be a browser. - It reports on roles, never on people.
Source and terms
- Greenhouse Job Board API: https://docs.greenhouse.io/job-board.html ("authentication is not required for any GET endpoints").
- Lever Postings API: https://github.com/lever/postings-api
- Ashby public job posting API: https://developers.ashbyhq.com/docs/public-job-posting-api
- This Actor is not affiliated with Greenhouse, Lever, Ashby or SmartRecruiters. The postings belong to the companies that publish them.
Questions and answers
Why are new and closed empty on my first run? There is no earlier run to compare with. From the second run on they are numbers, zero included.
What counts as a new role? A role id the board did not list at the last run that read it. A role that is taken down and posted again under a new id counts as closed and new.
Can I count roles in one department only? Yes: add a rule with departments and no keywords, or both to narrow it.
How do I reset the comparison? Delete the key-value store hiring-signals-state in your account, or the record of one board in it.
Does it read the job descriptions? No. Titles, departments, teams, locations and links are enough for the counts.