ATS Jobs Scraper: Greenhouse, Lever, Ashby
Pricing
from $1.00 / 1,000 job saveds
ATS Jobs Scraper: Greenhouse, Lever, Ashby
Job postings from the public Greenhouse, Lever and Ashby boards of companies you list. One format, full text, salary, filters, only-new alerts. $0.001/job.
Pricing
from $1.00 / 1,000 job saveds
Rating
0.0
(0)
Developer
Kaizoku Data
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
33 minutes ago
Last modified
Categories
Share
ATS Jobs: Greenhouse, Lever and Ashby (public job boards)
Get job postings from the public job boards of the companies you list, on Greenhouse, Lever and Ashby, in one clean format: title, department, team, locations, remote flag, employment type, published salary range where the company shows one, full description (HTML and plain text), and vendor-hosted apply and posting links.
Price: $0.001 per job, with the full description included.
Public job postings only. The Actor reads only the three vendors' public, unauthenticated job-board JSON endpoints, the same data each company already shows on its own careers page. No logins, no candidate or applicant data, no internal postings. You tell it which companies to read. It never searches for, crawls or discovers companies or boards.
What you can do with it
- Watch the companies you care about. Daily alert for new roles at 5 to 200 target employers (customers, competitors, investors' portfolio), with Only new jobs on.
- Hiring-trend and salary research across several companies and three ATS platforms in one dataset.
- Feed your own internal tools (CRM, Slack, sheets, recruiting research) with consistent fields, whatever ATS the company uses.
Input
| Field | What it does |
|---|---|
| Companies | Required. A list of board URLs you paste, or vendor:name. See below. |
| Keywords | Keep jobs whose title or description contains any of these words (not case sensitive). |
| Locations | Keep jobs whose location text contains any of these, e.g. Berlin, Germany, Remote. |
| Departments / teams | Keep jobs whose department or team contains any of these. |
| Remote jobs only | Lever and Ashby say whether a job is remote. Greenhouse does not, so on Greenhouse a job counts as remote only when its location or title says "remote". |
| Posted in the last N days (1 or more) | Uses the vendor's date. Jobs without a date are left out when this is set. |
| Max jobs per company / Max jobs in total | Hard limits (default total 20, up to 10,000). Companies are read in the order you list them. |
| Include description | HTML plus plain text (on by default). |
| Only new jobs | Skips jobs you were already delivered, remembered per company for 120 days. |
| Only-new memory name | Use different names for separate histories. |
| Mode | scrape (normal) or selfTest (monitoring; delivers and charges nothing). |
Naming companies
Each entry is either a board URL you copy from the company's careers page, or vendor:name:
| Vendor | URL forms | Short form |
|---|---|---|
| Greenhouse | boards.greenhouse.io/<name>, job-boards.greenhouse.io/<name> | greenhouse:stripe |
| Lever | jobs.lever.co/<name>, jobs.eu.lever.co/<name> (EU) | lever:spotify, lever-eu:<name> |
| Ashby | jobs.ashbyhq.com/<name> | ashby:linear |
The Actor only reads the vendor and board name out of what you typed. Greenhouse boards hosted on job-boards.eu.greenhouse.io are rejected: Greenhouse's public Job Board API is served only from boards-api.greenhouse.io (checked 2026-10-18; no EU API host exists). A company's own domain (for example careers.example.com) cannot be read: open it, copy the boards.greenhouse.io/..., jobs.lever.co/... or jobs.ashbyhq.com/... address, or write vendor:name. For a bare lever:name it tries Lever's global host first and Lever's EU host only if the global one says the board does not exist.
Entries that cannot be understood, and boards that do not exist (HTTP 404), are listed in the run summary and cost nothing. If no board could be read at all (every entry 404, failed or invalid), the run fails and names the boards, so a typo is never mistaken for "no jobs". If lever:name and lever-eu:name turn out to be the same board, it is read and delivered once.
Example, a daily alert:
{"companies": ["greenhouse:stripe", "https://jobs.lever.co/spotify", "ashby:linear"],"keywords": ["data engineer", "analytics"],"remoteOnly": true,"maxItems": 200,"onlyNew": true}
The default input is three stable public boards, one per vendor (greenhouse:duolingo, ashby:linear, lever:spotify), with 20 jobs in total. Boards are read in order and later ones are only fetched if the earlier ones give fewer than 20 jobs, so it is normally one request and finishes in seconds, no keys or accounts needed.
Output
One item per job, the same fields for all three vendors:
{"vendor": "ashby","companySlug": "ramp","company": "ramp","jobId": "8e1c0b7f-0000-4000-8000-000000000000","title": "Senior Software Engineer","department": "Engineering","team": "Platform","location": "New York City","locations": ["New York City", "Remote (US)"],"remote": false,"workplaceType": "hybrid","employmentType": "FullTime","compensation": { "min": 211400, "max": 290600, "currency": "USD", "interval": "year", "summary": "$211.4K - $290.6K" },"publishedAt": "2026-09-01T14:00:00.000Z","updatedAt": null,"applyUrl": "https://jobs.ashbyhq.com/ramp/8e1c0b7f-.../application","jobUrl": "https://jobs.ashbyhq.com/ramp/8e1c0b7f-...","description": "<p>…</p>","descriptionText": "…","source": "Ashby public job board","retrievedAt": "2026-10-18T13:38:52.452Z"}
Per-vendor notes (from our 2026-10-18 recording of 7 boards, 768 jobs):
| Greenhouse | Lever | Ashby | |
|---|---|---|---|
| Company name | Yes (company_name) | No: company repeats the board name | No: same |
| Department / team | Department only, team is null | Both (about 90% filled) | Both (100%) |
| Remote / workplace type | remote is true only if the location or title says "remote", else null. workplaceType is null | workplaceType and remote where the company sets it (about 20% of jobs); otherwise remote is null | Always |
| Employment type | Not provided (null) | commitment, e.g. Permanent (about 85%) | Always, e.g. FullTime |
| Salary range | Only when the company publishes pay ranges (pay_input_ranges) | Only when the posting has a salaryRange | Shown when the company enables pay display (78% on our sample) |
| Dates | publishedAt (first published) and updatedAt | publishedAt is Lever's creation date; no updated date | publishedAt; no updated date |
| Links | jobUrl and applyUrl are both the posting page the board publishes (which may be on the company's own domain) | Lever-hosted posting and apply pages | Ashby-hosted posting and apply pages |
compensationis a published salary range only, ornull. Most postings have none.remote: nullmeans "unknown", not "no".- Links are passed through exactly as the vendor published them.
- Every run also saves a
RUN_SUMMARYrecord: per-company counts, boards not found, invalid entries, failures, requests and why the run stopped.
Export as JSON, CSV, Excel or XML, or read it through the Apify API.
Pricing
Pay per event:
- $0.001 per job saved to the dataset.
- Apify's standard tiny start fee per run.
Examples: one company with 100 open roles, $0.10. 20 companies, about 1,500 roles in total, $1.50 the first time; with Only new jobs a daily re-run typically returns a few new roles and costs cents. Companies you list that don't exist, invalid entries and jobs filtered out are free. Cap any run with Apify's Max total charge; the Actor stops at the cap and remembers what it delivered.
Vendor terms and how the Actor behaves
We read each vendor's public API docs, terms and robots.txt before building this (copies and verdicts are in the Actor's repository, docs/terms/VERDICT.md):
- Greenhouse: the Job Board API docs state "Job Board data is publicly available, so authentication is not required for any GET endpoints."
- Lever: the Postings API docs state "all job postings in the
publishedstate are publicly viewable. These jobs may be scraped by third parties." robots.txt asks for a 1-second crawl delay; the Actor keeps more than 1 second between Lever requests. - Ashby: the public job-posting API is documented for companies' own careers pages and Ashby's terms say nothing about third-party reading of public postings, so we treat it as permitted but not explicitly licensed. If Ashby asks us to stop, we will.
The Actor makes one request per company, sequentially, with a polite pause, backs off on 429 and 5xx errors (honouring Retry-After, but giving up on a company after about 60 s of waiting and reporting it as failed), never follows redirects off the vendor hosts, and never tries to get around a block or CAPTCHA. You remain responsible for how you use the data and for respecting each company's and vendor's terms; job postings are the employers' content. We are not affiliated with Greenhouse, Lever or Ashby.
Privacy
Job postings only, never applicant or candidate data. Recruiters sometimes put their email or phone number in a posting, so the Actor removes email addresses and phone numbers from titles, descriptions and pay text (you will see [email removed] or [phone removed]; generic addresses such as an accommodations mailbox are removed too). It reads no recruiter or hiring-manager fields, so no such names are output. If you spot personal data we missed, tell us on the Issues tab and we will fix it.
Reliability
- Reads the vendors' JSON endpoints, not web pages, so careers-site redesigns don't break it.
- A daily self-test fetches three fixed public boards, one per vendor, and checks the output format against a recorded baseline. Each vendor has a spare board. It fails on real changes (a field removed or renamed, fewer valid rows, a lower fill rate) or when at least two of the three vendors cannot be read; one vendor's transient error or a removed board is only recorded as a notice, as is a new optional field. We fix breakages fast.
- Only new jobs saves its memory at least every 5 jobs. If a run is killed hard (for example an out-of-memory crash), up to 4 jobs delivered just before that may be delivered, and charged, again next run. Normal aborts and migrations save everything. Only jobs that were actually delivered and charged are remembered.
- None of the three endpoints paginates: one response holds the whole board. Greenhouse descriptions are always requested (
content=true), even if you switch descriptions off, because without them the API also drops departments and offices. A very large board (hundreds of jobs with long descriptions) is a few MB, which the default 256 MB handles. - Timing: about 1.1 s per Lever company and 0.5 s per other company. 100 companies take a couple of minutes; raise the run timeout for hundreds.
FAQ
Can it find which companies use Greenhouse, Lever or Ashby? No, by design. You list the companies. It does not search, crawl or guess board names.
Why was my company not found? The board name is wrong, the company uses another ATS, or the board is private/closed. Check the careers page link. Not-found boards are listed in RUN_SUMMARY.notFound and are free; if none of your boards can be read, the run fails.
Why are there fewer jobs than on the careers page? Only public, listed postings are returned; internal and unlisted ones (Ashby isListed: false) are excluded.
Does Max jobs count filtered-out jobs? No. Only delivered jobs count.
Can it apply to jobs or read applicants? No. Read-only, public postings.
Why did my run stop early? The jobs ran out, a limit was reached, or Max total charge was hit. RUN_SUMMARY.stoppedBy says which.
Something's wrong? Open an issue on the Actor's Issues tab. We aim to reply within 2 working days.