Job Postings Monitor: New & Closed Roles, Hiring Signals avatar

Job Postings Monitor: New & Closed Roles, Hiring Signals

Pricing

Pay per event

Go to Apify Store
Job Postings Monitor: New & Closed Roles, Hiring Signals

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

Changefeeds Tools

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

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, or changed (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:

boardopen_rolesopen_roles_deltaaddedremovedchanged
greenhouse:gitlab231+321107815
lever:palantir307−1326390
ashby:ramp171+15382315

344 job rows came with them. A few:

change_typeboardtitlelocationwas
addedashby:rampBusiness LeadNew York, NY (HQ)
addedlever:palantirSoftware Engineer, New Grad - Query EnginesLondon, United Kingdom
changedgreenhouse:gitlabManager/Senior Manager, Solution Architects - San FranciscoRemote, UStitle: Manager, Solutions Architects - San Francisco
changedgreenhouse:gitlabEngineering Manager, SSCS: Supply ChainBangalore, India; Remote, Australia; Remote, Canada; Remote, Israel; Remote, United Stateslocation: Bangalore, India
removedlever:palantirInformation Security EngineerSeattle, 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

  1. Click Try for free. The input already holds greenhouse:gitlab, lever:palantir and ashby:ramp.
  2. 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.
  3. 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, removed or changed rows, and baseline rows 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.
  • changed means title, department or location. A changed description, salary band or published date alone does not emit a row (Greenhouse's updated_at moves 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 removed rows. 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) in by_department).
  • published_at is Greenhouse's first_published (falling back to updated_at), Lever's createdAt, Ashby's publishedAt. A role can be added with an old published_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 error row rather than partial tracking. A board that lists a posting without an id (or the same id twice) also gets a free error row 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 error row 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-snapshots in 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 are removed, and a known id whose hash changed is changed (old values in previous).
  • 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

FieldDefaultNotes
boardsrequiredBoard 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.
includeBaselineJobsfalseOff: 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.
includeDescriptionsfalseAlso return each job's description (Greenhouse, Lever and Ashby). Makes rows bigger. Description-only edits are never reported as changes.
snapshotKeyderivedWhich 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.
webhookUrlnoneReceives 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.