Greenhouse, Lever & Ashby Job Scraper API
Pricing
from $1.00 / 1,000 job listeds
Greenhouse, Lever & Ashby Job Scraper API
Job scraper for Greenhouse, Lever and Ashby using their official public APIs. One schema, filtered and de-duplicated, no browser.
Pricing
from $1.00 / 1,000 job listeds
Rating
0.0
(0)
Developer
Tidyfetch
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
25 days ago
Last modified
Categories
Share
Greenhouse, Lever & Ashby Job Scraper (ATS Jobs API)
Get filtered, de-duplicated jobs from the official public job-board APIs of three applicant tracking systems (ATS), in one schema: the same JSON the companies' own career pages read. $1 per 1,000 delivered jobs plus $0.005 per run; platform usage is included. Jobs removed by your filters or by de-duplication are not charged. You bring the company board ids.
No Indeed, no LinkedIn, no browser, no proxies: one HTTP request per board, normalized, de-duplicated, filtered.
| ATS | Public API used | Company id you pass |
|---|---|---|
| Greenhouse | boards-api.greenhouse.io/v1/boards/{board_token}/jobs?content=true | board token, e.g. airbnb from boards.greenhouse.io/airbnb |
| Lever | api.lever.co/v0/postings/{site}?mode=json | site name, e.g. leverdemo from jobs.lever.co/leverdemo |
| Ashby | api.ashbyhq.com/posting-api/job-board/{jobBoardName} | job board name, e.g. ashby from jobs.ashbyhq.com/ashby |
Use it to monitor competitors' hiring, build a niche job board, feed a lead-generation pipeline (which companies are hiring for what), or track when a role you care about opens.
SmartRecruiters was supported until 2026-09-26 and has been removed: SmartRecruiters' API policy limits its public Posting API to customers' own career sites, and its API's robots.txt disallows other crawlers. Inputs with "ats": "smartrecruiters" now fail with an explanation.
This Actor is not affiliated with Greenhouse, Lever or Ashby. It uses their public job-board endpoints; that a posting is publicly readable does not by itself give permission to republish it, so check how you may reuse the data (see Limits).
Input
{"companies": [{ "ats": "greenhouse", "id": "airbnb" },{ "ats": "lever", "id": "leverdemo" },{ "ats": "ashby", "id": "ashby" },{ "ats": "auto", "id": "figma" }],"postedAfter": "2026-09-01","titleKeywords": ["engineer", "developer"],"locationKeywords": ["remote", "berlin"],"remoteOnly": false,"maxJobsPerCompany": 500,"includeDescription": true}
| Field | Type | Default | Meaning |
|---|---|---|---|
companies | array of { ats, id } | required | ats is greenhouse, lever, ashby or auto. With auto the Actor tries the three APIs in that order and uses the first one that knows the id. |
postedAfter | ISO date | – | Keep jobs first published on or after this date. Jobs whose ATS does not expose a publish date are kept. |
titleKeywords | string[] | – | Keep a job if its title contains any keyword (case-insensitive). |
locationKeywords | string[] | – | Keep a job if its location contains any keyword (case-insensitive). |
remoteOnly | boolean | false | Keep only jobs flagged remote by the ATS or whose title/location says "remote". |
maxJobsPerCompany | integer | 500 | Stop after this many jobs were output for a company (counted after filters). The Console form starts at 20 so a first test run stays small. |
includeDescription | boolean | true | Add descriptionText. With false, Greenhouse boards are fetched without job content, which also leaves department empty for Greenhouse jobs. |
Output
One dataset row per job:
{"id": "8184174","ats": "greenhouse","company": "Airbnb","companyId": "airbnb","title": "Account Manager","department": "Business Development","location": "London, United Kingdom","remote": false,"url": "https://careers.airbnb.com/positions/8184174?gh_jid=8184174","postedAt": "2026-09-09T08:35:19.000Z","updatedAt": "2026-09-24T22:49:00.000Z","descriptionText": "Airbnb was born in 2007 when two hosts welcomed three guests ...","salary": null,"source": "https://boards-api.greenhouse.io/v1/boards/airbnb/jobs?content=true"}
When the ATS publishes a salary range (Lever, Ashby), salary looks like { "min": 110000, "max": 185000, "currency": "EUR", "interval": "1 YEAR", "text": "€110K - €185K" }.
remoteis an estimate: the ATS flag when there is one (LeverworkplaceType, AshbyisRemote, Greenhouse "Workplace Type" metadata), otherwise a text match on location/title.salaryis present only when the ATS exposes it (LeversalaryRange, Ashby compensation).nullotherwise.descriptionTextis plain text converted from the HTML description. Email addresses and phone numbers inside it are masked ([email hidden],[phone hidden]). Phone masking is rule-based (international, parenthesised and national formats; a bare 7-digit number such as555-1234is masked only after a cue like "call" or "tel"); dates, version numbers and numeric ranges are left alone.updatedAtis only available from Greenhouse.- Duplicates are removed across all companies in the run, by URL (ignoring
utm_*,gh_srcandlever-*tracking parameters) and byats:id. - Jobs are written before their
Job listedcharge is requested, and these steps are serialized so parallel boards cannot race past your maximum cost. If a charge request itself fails, the written jobs are kept and the failure is recorded inSUMMARY, so the row count and the charged-event count can differ in that case. - A run summary (per-company counts, errors, charged events) is stored in the key-value store as
SUMMARY. Unknown board ids are reported there and in the log; they do not fail the run.
Pricing (pay per event)
| Event | Price |
|---|---|
| Run started | $0.005 per run |
| Job listed | $0.001 per job written to the dataset |
1,000 jobs cost about $1.005; 20 jobs cost $0.025. The run fee applies to every run, even one that returns no jobs. Jobs removed by filters or de-duplication are not charged. Set a maximum cost per run in Apify Console; the Actor stops cleanly when the limit is reached.
Limits and good to know
- You supply the company ids. There is no built-in company directory yet; find the token in the company's career-page URL (see table above).
- Ashby jobs with
isListed: falseare skipped. Only published postings are ever visible on any of the three APIs. - The Actor makes at most 4 concurrent requests, waits at least 1 s between Lever requests (Lever's
robots.txtasks forCrawl-delay: 1), and retries429/5xxresponses with exponential backoff. It reads data only (GET); it never applies to jobs. - Rate limits of the three APIs are not documented; very large boards (thousands of postings) work but take longer.
- Workday, Workable, iCIMS, Personio, BambooHR, SmartRecruiters and other ATSs are not supported in this version.
- Data comes from the employers' public job boards. The Actor does not access candidate records or recruiter profiles. It applies pattern-based email and phone masking to
descriptionTextonly; names and unusual contact formats may remain, so review the output before you redistribute it. - The job texts belong to the employers. The three public APIs are documented for companies' own career pages; as of 2026-09-26 we found no published terms on third-party aggregation either way; if you republish the data, link to the original posting and follow the employer's terms.
Disclosure
This Actor was designed and written by an AI coding agent (Claude) under human direction and review; a human maintainer reviews issues and the replies to them. Report problems through the Issues tab.