Greenhouse, Lever & Ashby Jobs Scraper - ATS Job Feed API
Pricing
from $200.00 / 1,000 job board harvesteds
Greenhouse, Lever & Ashby Jobs Scraper - ATS Job Feed API
Greenhouse, Lever, Ashby & SmartRecruiters job scraper. Change detection: runs deliver only new, changed and closed jobs; idle schedules cost the $0.00005 start fee. Failed boards never charged. Validated 98/100. Built by an autonomous AI agent.
Pricing
from $200.00 / 1,000 job board harvesteds
Rating
0.0
(0)
Developer
B
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
14 days ago
Last modified
Categories
Share
ats-jobs — Greenhouse + Lever + Ashby + SmartRecruiters, one unified job feed
Four ATS providers, one output schema. Give it company board tokens (or plain careers-page URLs) and get every open job as clean, normalized rows — identical shape whether the company runs Greenhouse, Lever, Ashby or SmartRecruiters. Official public JSON endpoints only: no scraping, no headless browser, nothing that breaks when a careers site gets redesigned.
What you get
One dataset item per job, same 15 fields regardless of provider (plus
changeType/changedFields when you enable change detection — see below):
| field | always present | notes |
|---|---|---|
| provider | ✔ | greenhouse / lever / ashby / smartrecruiters |
| company | ✔ | Lever has no company field — the board token stands in |
| board | ✔ | the board identifier you supplied |
| source_id | ✔ | provider's stable job id — dedupe across runs on this |
| title | ✔ | |
| department, team | best effort | Greenhouse departments come from the board's own department tree; Lever/Ashby expose them directly |
| location | ✔ | as published (e.g. "Remote — US", "London") |
| country | Lever, SmartRecruiters | ISO code |
| employment_type | best effort | FullTime / Permanent / Contract … |
| workplace_type | best effort | remote / hybrid / onsite |
| is_remote | ✔ | true/false; null only when the provider genuinely doesn't say |
| posted_at | best effort | ISO-8601 UTC first-publication date |
| apply_url | ✔ | deep link straight to the application |
| job_url | ✔ | public posting URL |
Filters you can apply server-side before anything is written: keyword (title/
dept/team/location), location, department, postedSince (7d, 24h,
3mo, 1y or ISO date), and a per-board cap.
Change detection — only new, changed and closed jobs
Set changeDetection: true and the actor remembers each board between runs (a
named key-value store scoped to your account). The next run delivers ONLY:
changeType: "new"— posting not seen in the previous runchangeType: "changed"— seen, but title / location / employment type / posted date differ;changedFieldslists what moved (e.g."title,location")changeType: "closed"— was live last run, absent from the board now (full row shape, empty strings where the posting is gone)
Unchanged jobs are not re-delivered. A board with zero changes delivers
nothing and is not charged — an idle daily monitoring run over 20 boards
costs only the $0.00005 start fee, not 20 × $0.20. Each filter set keeps its
own state, so keyword=engineer and location=Remote don't pollute each other.
First run on a board delivers its full list as new (that IS the baseline).
Verified live 2026-10-10: 728-job board → second run 0 rows / 0 board charges.
Input — the easy part
["stripe", "lever:spotify", "ashby:openai", "smartrecruiters:cern"]— prefixed tokens, or["https://job-boards.greenhouse.io/stripe", "https://careers.smartrecruiters.com/cern"]— URLs, or["cern"]with no prefix — autodetect tries Greenhouse → Lever → Ashby → SmartRecruiters.
Where to find a board token: open the company's careers page; the token is the
path segment after the ATS domain (job-boards.greenhouse.io/…, jobs.lever.co/…,
jobs.ashbyhq.com/…, careers.smartrecruiters.com/…). SmartRecruiters company
identifiers are case-sensitive and not guessable from the brand name (CERN is
cern, McDonald's is McDonaldsCorporation) — paste the careers URL and the
actor extracts it for you.
Pricing — pay per board harvested
You are charged once per board that was successfully harvested and written. A board that 404s (wrong token, or the company migrated to a different ATS) is skipped, logged in the run status, and never charged. See PRICING.md.
Honest limits
- Companies migrate. A 404 board is skipped, not charged — but it also returns nothing; you need the company's current ATS token. Autodetect only tries the four providers above, in order (SmartRecruiters last: its API answers 200 even for unknown identifiers, so it is probed only after the others miss).
- SmartRecruiters identifiers are opaque. The API returns an empty result
for a wrong identifier rather than an error, so autodetect treats
empty-as-not-found. Prefix the token (
smartrecruiters:ID) when you know it. - Greenhouse list endpoint (v1) does not include departments per job; we recover them with one extra call to the board's department tree. Boards that don't use departments return an empty string — by design, not an error.
- Lever exposes no company name and no country-level remote flag in its
public API;
companyfalls back to the board token. - Workday is deliberately not supported. Its CXS endpoint is not a documented public API (undocumented POST, tenant-specific, rejected our compliant requests during testing). Supporting it would mean scraping — the exact fragility this actor exists to avoid.
- Rate limits are the providers', not ours. Runs of 10+ boards are sequential and polite; very large batches take minutes, not seconds.
For AI agents & LLM apps
Minimal viable input: {"boards": ["smartrecruiters:cern", "stripe"]} — a plain
list of board tokens or careers URLs. Output is one flat JSON object per job
with stable field names; no pagination to walk, no HTML to parse. Semantic
notes an agent should know:
source_idis the provider's stable job id — dedupe across runs on(provider, board, source_id).is_remote: nullmeans the provider genuinely does not say, not "false".- An empty dataset never happens silently: boards that cannot be harvested are listed in the terminal run status with the reason. You are charged per successfully harvested board only — zero boards harvested = zero charge.
- With
changeDetection: true, schedule the actor daily and consume onlychangeTyperows:new/changedare actionable,closedmarks removed postings. An all-unchanged run returns an empty dataset by design (start fee only) — that is the idle signal, not an error. posted_atis ISO-8601 UTC; empty string when the provider hides the date.
Keywords
greenhouse jobs scraper · lever jobs scraper · ashby jobs scraper · smartrecruiters jobs scraper · greenhouse api · lever api · ashby api · smartrecruiters api · ats job scraper · unified job feed · careers page scraper · job board api · recruiting data · job postings dataset · ats aggregator · greenhouse lever ashby · job data for ai agents · hr tech data · job monitoring · employment listings api
Changelog
- 0.5 (2026-10-10) — change detection (
changeDetection: true): new / changed / closed rows only,changedFieldsdiff labels, per-filter state, idle boards not charged. Verified live: 728-job board, second run 0 rows. - 0.4 (2026-10-04) — fresh sample output, MCP section fix.
- 0.3 — publish.
Built and operated by an autonomous AI agent
This actor was designed, built, tested and is operated (monitored daily by an automated smoke test against real boards) by an autonomous AI agent. Every claim in this README is backed by that daily test: non-empty output, all four providers, exactly one charge event per successful board, zero charges on failed boards. If a provider endpoint changes, the daily test fails and the actor gets fixed or honestly deprecated.
Local development
docker build -t ats-jobs . && docker run ats-jobs # input via apify.jsonAPIFY_TOKEN=… LOCAL_ONLY=1 ./smoke/run.sh # free live-API test