Job Postings Monitor: New & Closed Roles, Hiring Signals
Pricing
Pay per event
Job Postings Monitor: New & Closed Roles, Hiring Signals
Watch company job boards on Greenhouse, Lever and Ashby and get only what changed since your last run: new roles, closed roles, retitled or moved roles, plus open roles by department. $3 per 1,000 job changes plus $0.003 per board.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Changefeeds Tools
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
- What you get: for each company job board on Greenhouse, Lever or Ashby, only the roles that changed since your last run:
added,removed, orchanged(new title, department or location, with the old values), plus one summary row per board with open roles, the change in open roles, and roles by department. - Built for: sales prospecting and account intel (who is hiring for what, and where), recruiting-market tracking, and competitor watching. It reads only each company's official public job-board API: job metadata, never people. No API keys or logins.
- Price: $3 per 1,000 job changes plus $0.003 per board checked. Missing or failing boards are free, and starting a watch of 100 companies costs $0.30.
Sample output
We ran this actor on GitLab (Greenhouse), Palantir (Lever) and Ramp (Ashby) on 2026-09-29 and again on 2026-10-23. The second run's board rows:
| board | open_roles | open_roles_delta | added | removed | changed |
|---|---|---|---|---|---|
| greenhouse:gitlab | 231 | +32 | 110 | 78 | 15 |
| lever:palantir | 307 | −13 | 26 | 39 | 0 |
| ashby:ramp | 171 | +15 | 38 | 23 | 15 |
344 job rows came with them. A few:
| change_type | board | title | location | was |
|---|---|---|---|---|
| added | ashby:ramp | Business Lead | New York, NY (HQ) | |
| added | lever:palantir | Software Engineer, New Grad - Query Engines | London, United Kingdom | |
| changed | greenhouse:gitlab | Manager/Senior Manager, Solution Architects - San Francisco | Remote, US | title: Manager, Solutions Architects - San Francisco |
| changed | greenhouse:gitlab | Engineering Manager, SSCS: Supply Chain | Bangalore, India; Remote, Australia; Remote, Canada; Remote, Israel; Remote, United States | location: Bangalore, India |
| removed | lever:palantir | Information Security Engineer | Seattle, WA |
The first row in full:
{"type": "job","board": "ashby:ramp","ats": "ashby","company": "ramp","change_type": "added","previous": null,"id": "0378cc97-de79-42f9-8401-d301c678f4d7","title": "Business Lead","department": "Finance","team": "Strategic Finance","location": "New York, NY (HQ)","remote": false,"employment_type": "FullTime","url": "https://jobs.ashbyhq.com/ramp/0378cc97-de79-42f9-8401-d301c678f4d7","published_at": "2026-10-12T13:48:36.560+00:00","compensation_summary": "$160K – $275K • Offers Equity","description": null,"checked_at": "2026-10-23T03:50:33.260Z"}
A changed row has the same shape with the old title, department and location
in previous. A removed row carries the last-seen title, department and
location, with url: null (the posting is gone).
Your first run is a baseline. It records every open role and returns one
summary row per board (is_baseline: true, open roles, roles by department),
without the roles themselves. Job changes start from the second run of the same
list. Turn on Return all current jobs on the first run if you also want
every open role as a row (charged as job rows).
How to run in 30 seconds
- Click Try for free. The input already holds
greenhouse:gitlab,lever:palantirandashby:ramp. - Click Start. Our first run of that input took 20 seconds and cost $0.009 (3 boards): 3 board rows with 231, 307 and 171 open roles and their departments.
- Run it again tomorrow: the rows are the roles that were added, removed or changed. Then save it as a task and add a daily or weekly schedule.
To watch your own companies, paste their job-board URLs
(https://boards.greenhouse.io/<token>, https://jobs.lever.co/<site>,
https://jobs.ashbyhq.com/<org>) or shorthands (greenhouse:<token>,
lever:<site>, ashby:<org>).
Pricing
- $0.003 per board checked (fetched successfully and compared). The board summary row is included.
- $0.003 per job change returned ($3 per 1,000):
added,removedorchangedrows, andbaselinerows only if you turn that option on. - Free: boards that are not found, invalid or fail to load.
- What it really costs depends on how fast the companies hire. The three boards above (709 open roles) produced 344 changes in 24 days, so that comparison run cost 3 × $0.003 + 344 × $0.003 = $1.04; watched daily, they would cost at least about $1.60 a month (daily runs also catch roles that open and close between two checks). Companies with a few dozen roles change far less; companies the size of GitLab change more.
- Starting a watch of 100 companies costs 100 × $0.003 = $0.30 (roles are recorded, not returned). With Return all current jobs on the first run on, the three boards above would cost $0.009 + 709 × $0.003 = $2.14 once.
- Set a maximum total charge and the actor returns only the rows that fit,
saves state for what it returned, stops fetching further boards, and says so
in
OUTPUT(stopped_reason: "max_total_charge_reached"). It never charges for a row it did not deliver, and delivered rows are remembered, so the next run does not bill them again. (If a run is killed between delivering a board's rows and saving that board's state, the next run reports those changes again.)
FAQ
How do I get new roles in Slack or a CRM? Save your board list as a task,
add a schedule, and attach an
Apify integration (Slack,
HubSpot via Zapier or Make, Google Sheets) to the task's "run succeeded" event.
Each run's dataset holds the board rows and only the changed roles. Or set
Webhook URL and the run POSTs its OUTPUT summary there.
Why did my first run return only 3 rows? That is the baseline: one summary row per board. Changes start from the second run.
I edited my board list and everything is baseline again. The default snapshot key comes from the board list. Set Snapshot key to a fixed name to keep history when you add or remove boards.
What about Workday, SmartRecruiters and other ATSes? This monitor covers Greenhouse, Lever and Ashby. For a one-time export of every open job on 11 ATS platforms, Workday included, use our Greenhouse, Lever & Workday Jobs Scraper.
How do I find a company's board token? Open the company's careers page and
follow a job link: the token is the part after boards.greenhouse.io/,
jobs.lever.co/ or jobs.ashbyhq.com/.
Limits
- Job-board metadata only. It never visits profiles or applications, and it cannot see jobs a company withholds from its public board.
changedmeans title, department or location. A changed description, salary band or published date alone does not emit a row (Greenhouse'supdated_atmoves on unrelated edits, so it is deliberately not watched).- Removals come only from a complete fetch. A board is one request to its
official API, so a successful fetch covers the whole board; an error never
produces
removedrows. A board that had roles and comes back empty is fetched again after 5 s before every role is reported removed. - Lever boards often have no department, as with Palantir above
(
(no department)inby_department). published_atis Greenhouse'sfirst_published(falling back toupdated_at), Lever'screatedAt, Ashby'spublishedAt. A role can beaddedwith an oldpublished_at, for example when a company re-lists an older posting.- At most 10,000 open jobs per board. A larger board gets a free
errorrow rather than partial tracking. A board that lists a posting without an id (or the same id twice) also gets a freeerrorrow for that run. - Ashby postings marked unlisted are ignored, as on the public board.
- A retired board comes back
not_found(free) until you remove it. - Polite: at most 2 boards fetched at a time, at least 1 s between requests to the same board, HTTP 429 honoured (Retry-After up to 60 s, at most 3 retries; a longer wait skips that board for this run), a descriptive User-Agent, 20 s timeouts.
- One run at a time per snapshot key. A run that starts while another run with the same key is still going fails immediately, before fetching or charging anything. A crashed run blocks its key for at most 30 minutes. (The lock is best effort: two runs started within the same couple of seconds can, rarely, both proceed; their saved history is merged, not overwritten.)
- If saved history can't be read, the board is skipped with a free
errorrow rather than re-sent as a paid baseline. If it can't be saved after 3 attempts, the run is marked failed and names the boards, because the next run would report those jobs again.
How the change feed works
- State lives in the named key-value store
hiringwatch-snapshotsin your account, one record per board and snapshot key: the last checked time, the open-role count and, per job id, its title, department and location with a SHA-256 hash of the three. - Each run fetches the whole board and diffs job ids against the snapshot: new
ids are
added, missing ids areremoved, and a known id whose hash changed ischanged(old values inprevious). - Failed or missing boards never touch their snapshot, so the next run compares with the last good state.
- A snapshot save applies only that run's own changes to what is stored, so a slower overlapping run cannot restore a job a newer run already replaced.
- A run with no job changes still returns one board row per board
(
added: 0, removed: 0, changed: 0), so a quiet run is never mistaken for a broken one.
Input reference
| Field | Default | Notes |
|---|---|---|
boards | required | Board URLs or shorthands: greenhouse:<token>, https://boards.greenhouse.io/<token>, https://job-boards.greenhouse.io/<token>, lever:<site>, https://jobs.lever.co/<site>, ashby:<org>, https://jobs.ashbyhq.com/<org>. Up to 1,000 per run. Invalid entries get an error row; the run continues. |
includeBaselineJobs | false | Off: a board's first run records its roles and returns only the board row. On: the first run also returns every open role as a charged baseline row. |
includeDescriptions | false | Also return each job's description (Greenhouse, Lever and Ashby). Makes rows bigger. Description-only edits are never reported as changes. |
snapshotKey | derived | Which saved state to compare against. By default derived from the sorted board list. Set it to keep history when you edit the list. Distinct keys always get distinct storage records (sanitised and suffixed with a hash of the original), so watch/a and watch?a never share history. |
webhookUrl | none | Receives the run summary as a JSON POST. |
Output reference
board rows (type: "board"): board, ats, token; status: ok,
not_found, error or invalid; open_roles, open_roles_delta (null on
the baseline); added, removed, changed, baseline counts;
by_department; is_baseline, previous_checked_at, checked_at.
job rows (type: "job"): change_type (baseline, added, removed,
changed), previous, id, title, department, team, location,
remote, employment_type, url, published_at, compensation_summary
(Ashby), description (only with includeDescriptions), checked_at.
The key-value store record OUTPUT holds totals (changes,
job_rows_returned, first_run, charged_events, charge_limit_reached,
stopped_reason) and a per-board summary.