ATS New Jobs Monitor
Pricing
from $1.50 / 1,000 job results
ATS New Jobs Monitor
Monitor Greenhouse, Lever, Ashby, Workable, and SmartRecruiters boards and output only NEW and REMOVED job postings since the previous run.
Pricing
from $1.50 / 1,000 job results
Rating
0.0
(0)
Developer
Yingjie Liu
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
What does ATS New Jobs Monitor do?
ATS New Jobs Monitor watches public job boards on Greenhouse, Lever, Ashby, Workable, and SmartRecruiters and writes only the jobs that appeared or disappeared since the previous run. It talks to each ATS's public JSON API — no browser, no proxy, and no unofficial HTML scraping.
Give it company names, careers URLs, board URLs, or board tokens. The Actor auto-detects the ATS, normalizes every posting into one schema, diffs against a snapshot stored in a named Key-Value Store, and can ping a webhook or Slack with a change summary.
This is a hiring-signal feed, not a full-text job search engine. It does not scrape LinkedIn, Indeed, or Workday.
Why monitor ATS job boards?
Company career sites are the source of truth for new roles. Aggregators lag, duplicate, and mix stale listings. Hitting the ATS JSON endpoint directly is faster, cheaper, and stable enough to schedule every hour.
Typical uses:
- Sales lead hiring signals — a burst of Account Executive or Solutions Engineer roles often means a team is ramping quota. Alert your SDRs the same day a role goes live.
- Job seeker new-job alerts — watch a short list of target companies and get only the NEW postings, not the whole board every time.
- Recruiting competitive intel — see which departments competitors are growing, and which roles they just closed (REMOVED).
- RevOps / GTM research — fold hiring changes into a CRM or spreadsheet via the Apify API, Zapier, Make, or n8n.
Platform extras you get for free by running this as an Apify Actor: scheduling, dataset export (JSON/CSV/Excel), webhooks, and a spend cap via ACTOR_MAX_TOTAL_CHARGE_USD.
What data can ATS New Jobs Monitor extract?
| Field | Type | Description |
|---|---|---|
changeType | string | NEW, REMOVED, or EXISTING |
company | string | Company display name |
ats | string | greenhouse, lever, ashby, workable, or smartrecruiters |
title | string | Job title |
department / team | string | Org fields when the ATS publishes them |
location | string | Primary location |
isRemote | boolean | Remote flag or location text that looks remote |
employmentType | string | Full-time, contract, intern, … |
salary | object | min, max, currency when the board publishes pay |
postedAt / updatedAt | string | ISO-8601 timestamps |
url | string | Public posting URL |
descriptionText | string | Optional plain text (off by default) |
firstSeenAt | string | When this monitor first saw the job |
jobId | string | ATS identifier used for diffing |
You can download the dataset as JSON, HTML, CSV, or Excel from the run's Output tab.
How to monitor new jobs on Greenhouse, Lever, and Ashby
- Open the Actor in Apify Console and click Try for free. The default input already fetches a small live Greenhouse board (Airtable) so the first run is non-empty.
- Add your own companies. A name (
stripe), a board URL (https://jobs.lever.co/palantir), or a token (notion) all work. - For a scheduled NEW/REMOVED monitor, set a stable Monitor ID and leave Output mode on
changesOnly. Empty Monitor ID is a stateless demo: every run outputs current jobs (all), capped at 25. - Optionally set keyword, location, department, or remote-only filters.
- (Optional) Paste a Slack incoming webhook or a generic webhook URL.
- Click Start. Schedule the same input (with Monitor ID) hourly or daily so the snapshot stays current.
- Read NEW/REMOVED rows in the dataset, or consume them from the API.
Locally:
npm installnpx apify-cli run --purge --input-file .actor/sample-input.json
The sample input uses live public boards: Greenhouse stripe, Lever palantir, Ashby notion, Workable huggingface, and SmartRecruiters DeliveryHero. Netflix is no longer on Lever (api.lever.co/v0/postings/netflix returns 404). OpenAI's Ashby board (openai) is live but large (~14 MB JSON); notion is the lighter Ashby example.
How much will it cost to monitor job postings?
Pricing is pay-per-event. Configure the same event names in Apify Console when you publish:
| Event | When it fires | Price |
|---|---|---|
actor-start | Once at the beginning of every run | $0.005 |
company-detection | When the Actor has to probe which ATS a company uses | $0.002 |
job-result | Each job row pushed to the dataset | $0.0015 |
Examples:
- Default / empty input (Store auto-test): Airtable Greenhouse, ≤25 jobs → about
$0.005 + 4 × $0.0015 ≈ $0.011 - 10 companies with known board URLs, 25 NEW jobs →
$0.005 + 25 × $0.0015 = $0.0425 - Named monitor, no changes →
$0.005(empty dataset — this is why Store tests leave Monitor ID empty) - First run with emit all as NEW on 400 open roles →
$0.005 + 400 × $0.0015 = $0.605
Skip company-detection charges by setting ats (or passing a jobs.lever.co / boards.greenhouse.io / jobs.ashbyhq.com URL). Leave Include job description text off unless you need it — descriptions do not change the event price, but they make runs heavier.
Users can cap spend with max total charge in Console (ACTOR_MAX_TOTAL_CHARGE_USD). The Actor stops pushing results and saves a consistent snapshot when the limit is reached, so the next run resumes instead of skipping jobs silently.
Apify platform compute is billed separately. Runs are JSON API calls, so compute is typically a few seconds to a couple of minutes.
Input
See the Input tab for the full form. The important fields:
- Companies —
identifier(required), optionalname,ats, andtoken. Default/prefill is Airtable's Greenhouse board so{}and Store auto-tests still produce rows. - Monitor ID — leave empty for one-shot / Store tests (stateless
all, max 25 jobs). Set a stable ID for scheduledchangesOnlydiffs. - Snapshot Key-Value Store name — named store that survives across runs. Default
ats-new-jobs-monitor-snapshots. - Output mode —
changesOnlyis the scheduled-monitor default (NEW + REMOVED only). Empty Monitor ID always behaves asall. - First run behavior — emit everything as NEW, or baseline with no dataset items. Only applies when Monitor ID is set.
- Max jobs —
0= no cap on named monitors. Stateless runs cap at 25 unless you set a positive value. - Filters — include/exclude keywords, locations, departments, remote only.
- Webhooks — generic JSON POST and/or Slack incoming webhook.
Unknown companies are logged and skipped. One bad token will not fail the run.
Output
Each dataset item looks like this:
{"jobId": "8023928","company": "Stripe","ats": "greenhouse","title": "Account Executive, Bridge","department": "Sales","team": null,"location": "London","isRemote": false,"employmentType": null,"salary": null,"postedAt": "2026-07-30T10:59:38.000Z","updatedAt": "2026-08-04T11:02:31.000Z","url": "https://stripe.com/jobs/search?gh_jid=8023928","descriptionText": null,"changeType": "NEW","firstSeenAt": "2026-10-20T13:00:00.000Z","boardToken": "stripe","monitorId": "sales-signals"}
A run summary is saved to the default key-value store as OUTPUT (counts, detected boards, and per-company errors).
Supported ATS endpoints
Public, unauthenticated JSON only:
| ATS | Endpoint |
|---|---|
| Greenhouse | https://boards-api.greenhouse.io/v1/boards/{token}/jobs |
| Lever | https://api.lever.co/v0/postings/{token}?mode=json |
| Ashby | https://api.ashbyhq.com/posting-api/job-board/{token}?includeCompensation=true |
| Workable | https://apply.workable.com/api/v1/widget/accounts/{token} |
| SmartRecruiters | https://api.smartrecruiters.com/v1/companies/{id}/postings |
No Playwright, no Apify Proxy by default. If a vendor starts blocking datacenter IPs, add a proxy later — it is not required today.
How to publish this Actor
- Create an Apify account and run
npx apify-cli login(or setAPIFY_TOKEN). - From this directory:
npx apify-cli push. - In Apify Console → Actor → Publication → Monetization, choose Pay per event.
- Create events that match
.actor/pay_per_event.json:actor-start($0.005),job-result($0.0015, primary),company-detection($0.002). - Do not also enable the synthetic
apify-actor-startevent — this Actor chargesactor-startin code. Using both would double-bill starts. - Set a README, categories, and a store listing, then publish.
Local monetization test:
$ACTOR_TEST_PAY_PER_EVENT=true npx apify-cli run --input-file .actor/sample-input.json
FAQ
How does incremental mode work?
Set a Monitor ID. Each ID stores the last filtered job set in a named Key-Value Store. The next run diffs ats + boardToken + jobId. Jobs only in the new set are NEW; jobs only in the snapshot are REMOVED. Changing filters changes what is stored, so NEW/REMOVED will follow the filtered view.
If Monitor ID is empty, the run is stateless: no snapshot, outputMode=all, and a 25-job cap. Apify Store auto-tests use this path so the default dataset stays non-empty every day.
What happens on the first run?
Emit all current jobs as NEW (default) fills the dataset so you can verify the watch list. Baseline silently writes the snapshot and outputs nothing; the following run reports true changes only. An immediate second run against an unchanged Greenhouse / Lever / Ashby / Workable board should push zero items in changesOnly mode. Large SmartRecruiters boards can add or drop postings between two calls a few seconds apart; those rows are real NEW/REMOVED events.
Why was my company skipped?
The identifier did not match a live public board. Check the run log and the OUTPUT record. Common cases: the company uses Workday (out of scope), the Lever/Greenhouse slug changed, or SmartRecruiters needs the exact company.identifier (case can matter).
Does this scrape employee personal data?
No. It only reads roles a company has chosen to publish on its job board. Treat job descriptions as potentially containing personal data if you enable includeDescription, and comply with GDPR/CCPA for your use case.
How do I run unit tests?
$npm test
Tests cover ATS URL detection, job normalization, snapshot diffing, filters, and default-input (stateless) resolution. They do not call live APIs.
Where should I send feedback?
Use the Actor Issues tab on Apify. For API integration examples, open the API tab on the Actor page.