ATS Jobs Scraper: Greenhouse, Lever & Ashby
Pricing
from $1.00 / 1,000 jobs
ATS Jobs Scraper: Greenhouse, Lever & Ashby
Scrape open jobs from Greenhouse, Lever and Ashby career boards into one clean schema. Paste board URLs, careers pages or company names and the Actor detects the ATS. Salary ranges where employers publish them, an only-new-jobs mode for scheduled runs, and no recruiter or contact fields.
Pricing
from $1.00 / 1,000 jobs
Rating
0.0
(0)
Developer
Quicksloth
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
See which companies are hiring, for which roles, where, and at what pay. This ATS jobs scraper reads the public Greenhouse, Lever and Ashby job boards of the companies you list (up to 1,000 per run) and returns every open job in one clean schema: title, locations, remote or hybrid, department, dates, the salary range where the employer publishes one, and the apply link. Paste board URLs, careers pages or plain company names; the Actor finds the board, so you do not integrate three different APIs.
Built for sales teams that use hiring as a buying signal, recruiters tracking target employers, internal job alerts, labor-market datasets and AI agents that need a predictable JSON schema. Switch on only new or changed jobs for scheduled runs: after the first run you pay only for postings that are new or changed. The output has no recruiter, hiring-manager or contact fields, and job descriptions are off unless you ask for them.
ATS = applicant tracking system, the software companies use to publish and manage their job openings.
Example output
Three jobs from a test run on 2026-10-10 (GitLab, Spotify and Ramp, title keyword "engineer", descriptions off). Each row is one dataset item, shown here as text; in the dataset a value the board does not provide is null. The full record with all fields is shown under Output.
| Title | Board (ATS) | Location | Workplace | Employment type | Salary |
|---|---|---|---|---|---|
| Senior Software Engineer, Security Factory: Code Security | gitlab (Greenhouse) | Remote, Canada | remote | not given | USD 139,200 to 235,200 |
| AV Engineer - Platform | spotify (Lever) | Stockholm | onsite | Permanent | not published |
| Software Engineering Intern, iOS | ramp (Ashby) | New York, NY (HQ) | hybrid | internship | USD 12,500 per month |
Download the result as JSON, CSV or Excel, or read it through the Apify API. No API key and no proxies needed.
Get jobs from Greenhouse, Lever and Ashby in three steps
- Open the Actor and paste your companies in Companies, one per line: board URLs (
https://jobs.lever.co/spotify),ats:boardnames (ashby:ramp), careers-page URLs or plain company names. - Optional: add title or location keywords, tick Remote jobs only, and set Max jobs in total.
- Click Start. The Overview table of the dataset shows title, company, location, salary, posted date and job page. Download it as JSON, CSV or Excel, or read it through the Apify API.
Pricing
You pay per job saved to the dataset, plus Apify's start charge of $0.00005 for each GB of run memory (one charge, $0.00005, at this Actor's default of 512 MB). Companies that are not found, and jobs removed by your filters, cost nothing. The price per job depends on the Apify Store discount tier of your plan, as in the table below and in the Pricing tab.
| Discount tier | Per job | 1,000 jobs | 10,000 jobs | 100,000 jobs |
|---|---|---|---|---|
| Free | $0.0015 | $1.50 | $15.00 | $150.00 |
| Bronze | $0.0014 | $1.40 | $14.00 | $140.00 |
| Silver | $0.0012 | $1.20 | $12.00 | $120.00 |
| Gold and higher | $0.001 | $1.00 | $10.00 | $100.00 |
Free is the free plan; Bronze is the Starter plan, Silver the Scale plan, and Gold and higher the Business and enterprise plans (Apify plans).
Monitoring example. You follow 200 companies and run the Actor once a day with Only new or changed jobs on. The first run saves all matching jobs. If, say, 100 jobs are new or changed on a given day (your number will differ), that run costs $0.15 or less, plus the start charge, and 30 such days cost $4.50 or less, plus the start charges.
Cost control. In Apify Console you can set a maximum cost for each run; the Actor stops cleanly when it is reached and says so in the status message. Runs started from the Console form are prefilled with a 500-job limit ($0.75 or less, plus the start charge): change or clear it to get more. API and MCP runs have no limit unless you set maxJobs or a maximum cost (the free-plan limit below still applies).
Free plan. Users on the free Apify plan get up to 100 jobs per run, enough to test it on your own list of companies. The run log and status message say when this limit is reached. Paid plans have no such limit.
What can you do with it?
- Sales and business development: find companies opening roles that signal a need for your product (for example several data-engineering jobs), then watch them on every scheduled run with Only new or changed jobs. Use
titleKeywordsto keep just those roles. - Recruiting and talent intelligence: follow the openings, locations and remote policy of target employers and see the new roles on every scheduled run.
- Pay and market research: collect the salary ranges employers publish (
salaryMin,salaryMax,salaryCurrency,salaryInterval). Only part of the postings show pay, and Greenhouse ranges do not state the interval. - Labor-market and hiring-trend analysis: keep the results of each run and compare open roles by department, location or workplace type over time (
scrapedAtmarks the run). - Internal job alerts: send new postings to a spreadsheet, a database or a chat channel with Apify schedules, webhooks and integrations.
- AI agents and data pipelines: one predictable JSON schema, available through the Apify API and, for AI agents, through Apify's MCP server.
Supported ATS and accepted inputs
| ATS | Board URL examples | Prefixed name |
|---|---|---|
| Greenhouse | https://job-boards.greenhouse.io/gitlab, https://boards.greenhouse.io/gitlab, https://boards.greenhouse.io/embed/job_board?for=gitlab | greenhouse:gitlab |
| Lever | https://jobs.lever.co/spotify, https://jobs.eu.lever.co/<company> (EU instance) | lever:spotify, lever-eu:<company> |
| Ashby | https://jobs.ashbyhq.com/ramp | ashby:ramp |
You can also enter:
- A careers page URL (for example
https://www.example.com/careers). The Actor looks for an embedded or linked Greenhouse, Lever or Ashby board on that page. Pages that load the board only with JavaScript from another domain may not be detected; use the board URL in that case. - A plain company name (for example
Notion). The Actor tries the most likely board names on Greenhouse, then Lever, then Ashby. Names are a convenience: two companies can share a name, so use board URLs when you need certainty.
Input examples
Basic: all jobs from three companies
{ "companies": ["https://job-boards.greenhouse.io/gitlab", "https://jobs.lever.co/spotify", "ashby:ramp"] }
Filtered: remote engineering jobs, with descriptions, at most 50 per company
{"companies": ["https://job-boards.greenhouse.io/gitlab", "Linear", "https://jobs.lever.co/spotify"],"titleKeywords": ["engineer", "developer"],"remoteOnly": true,"includeDescription": true,"maxJobsPerCompany": 50}
Scheduled monitoring: only new or changed jobs
{"companies": ["https://job-boards.greenhouse.io/gitlab", "ashby:ramp"],"locationKeywords": ["London", "Berlin", "Remote"],"onlyNewJobs": true,"stateKey": "weekly-europe"}
Input fields
| Field | Type | Default | Description |
|---|---|---|---|
companies | array of strings | (required) | Board URLs, ats:board names, careers-page URLs or company names. Up to 1,000 per run. |
titleKeywords | array of strings | empty | Keep jobs whose title contains any of these words (case-insensitive). |
locationKeywords | array of strings | empty | Keep jobs with a location containing any of these words (case-insensitive). |
remoteOnly | boolean | false | Keep only jobs whose work type is remote. When the ATS gives no work type, its remote flag decides and, without a flag, a location that says "Remote". See the FAQ. |
includeDescription | boolean | false | Add the job description as plain text (emails, phone numbers and names after labels such as "Recruiter:" removed). |
onlyNewJobs | boolean | false | Return only jobs that are new or changed since the previous run with the same filters. |
stateKey | string | empty | Optional name for the "only new jobs" history, so different scheduled tasks keep separate histories. |
maxJobsPerCompany | integer | no limit | Keep at most this many jobs per company (newest first). |
maxJobs | integer | no limit | Stop after this many jobs in total. The Console form is prefilled with 500; clear it for no limit. |
Output
Each job is one dataset item. Fields are always present; a field is null when the ATS does not provide it. This is the first row of the example above, as saved by the run:
{"id": "greenhouse:gitlab:8738179002","ats": "greenhouse","board": "gitlab","companyName": "GitLab","jobId": "8738179002","title": "Senior Software Engineer, Security Factory: Code Security","department": "Sec Engineering","team": null,"locations": ["Remote, Canada", "Remote, United States"],"location": "Remote, Canada","isRemote": true,"workplaceType": "remote","employmentType": null,"postedAt": "2026-10-10T00:31:32.000Z","updatedAt": "2026-10-10T00:31:32.000Z","url": "https://job-boards.greenhouse.io/gitlab/jobs/8738179002","applyUrl": "https://job-boards.greenhouse.io/gitlab/jobs/8738179002","salaryMin": 139200,"salaryMax": 235200,"salaryCurrency": "USD","salaryInterval": null,"salaryText": "USD 139,200 - 235,200 (United States Salary Range)","descriptionText": null,"scrapedAt": "2026-10-10T03:07:35.498Z"}
What each ATS provides
| Field | Greenhouse | Lever | Ashby |
|---|---|---|---|
companyName | yes | no (null) | no (null) |
department / team | department only | both | both |
workplaceType | from the employer's "Workplace Type" field if present, otherwise inferred from the location text ("Remote", "Hybrid") | yes | yes (when the employer fills it in) |
employmentType | only if the employer adds an "Employment Type" field | yes (employer's own label, e.g. "Permanent") | yes (full-time, part-time, contract, internship, temporary) |
postedAt | first published | created | published |
updatedAt | yes | no (null) | no (null) |
| Salary | when the employer enables pay transparency (no interval given) | when the employer publishes a salary range | when the employer shows compensation |
Values are normalized: workplaceType is remote, hybrid or onsite; isRemote follows workplaceType when the ATS gives one (true only for remote), otherwise the ATS's own remote flag and, without a flag, the word "Remote" in a location, and is null when nothing says; salaryInterval is year, month, week, day or hour; dates are ISO 8601 in UTC.
Run summary
Every run also saves a summary in the default key-value store under the key OUTPUT:
{"companies": [{ "input": "https://jobs.lever.co/spotify", "ats": "lever", "board": "spotify", "status": "ok", "jobs": 75, "error": null },{ "input": "Unknown Company", "ats": null, "board": null, "status": "failed", "jobs": 0, "error": "No public Greenhouse, Lever or Ashby board found for \"Unknown Company\" (tried: unknowncompany, unknown-company)." }],"totalJobs": 75,"newJobs": null,"stoppedBecause": null}
status is ok, failed or skipped (the same board as another entry, or not processed after a limit was reached). A company that cannot be found or fails does not stop the run: it is reported here and the other companies continue. The run fails only if every company fails.
Only new jobs (scheduled runs)
Turn on onlyNewJobs and schedule the Actor (for example daily). The first run returns all matching jobs and remembers them. Later runs return only jobs that are new or whose key fields changed (title, location, salary, department, workplace or employment type, URL, or the update date where the ATS provides one). Jobs that were not returned because of a limit stay "unseen" and come back in the next run.
The history is kept in a named key-value store in your account (ats-jobs-seen-state) and is separate for each combination of filters. If you run several scheduled tasks with the same filters, give each one its own stateKey.
Other Quicksloth job scrapers
Two more job scrapers on this profile, each with an only-new-jobs mode for scheduled runs:
- Workday Jobs Scraper: public job postings from the
myworkdayjobs.comcareer sites of the companies you list. - Remote OK Jobs Scraper: remote job postings from Remote OK, filtered by tag and keywords.
Legal and data protection
- The Actor reads the public job-board APIs that Greenhouse, Lever and Ashby document for publishing job postings (Greenhouse Job Board API: "Job Board data is publicly available, so authentication is not required for any GET endpoints"; Lever Postings API; Ashby job posting API) and, only when you enter one, a single careers page. No login, no private data.
- If you enter a careers-page URL, the Actor loads only that page to look for a link or embed of a supported board. It does not crawl the website.
- It keeps to the robots.txt rules of the three APIs (last checked 2026-10-08), including Lever's one-second crawl delay.
- No personal-data fields: the output has no recruiter, hiring-manager or contact fields.
- Descriptions are off by default. When you turn them on, they are free text written by the employer: email addresses, phone numbers in common formats and names after labels such as "Recruiter:", "Hiring Manager:" or "Contact:" are removed, but other mentions of people may remain. Check that you have a legal basis before storing them, and that your use of the employer's text is allowed.
- Greenhouse, Lever and Ashby are trademarks of their respective owners, named here only to say which job boards the Actor can read. Company names on this page belong to their owners. This Actor is not affiliated with or endorsed by Greenhouse, Lever or Ashby.
- You are responsible for how you use the data, including compliance with the laws that apply to you.
FAQ
How do I find a company's board? Open the company's careers page and click a job. If the address contains greenhouse.io, lever.co or ashbyhq.com, copy that URL. Or just paste the careers page URL and let the Actor look for it.
Do I need proxies or a browser? No. The Actor calls the public job-board APIs with plain HTTP requests. The only web page it can load is a careers page you enter, to look for a board link.
Can it find companies for me, or search jobs across all companies? No. It reads the boards of the companies you list; it has no company directory and no search across all employers. Use the title and location keywords to filter the jobs of your companies.
What counts as "changed" in only-new mode? A change in title, locations, department, team, remote or workplace type, employment type, job URL, salary fields, or the update date where the ATS provides one. Changes in the description do not count. A job that was missing from the board during a run and is posted again later is returned as new.
How does the remote filter work? Each ATS has a work-type field that the employer fills in: remote, hybrid or on-site. remoteOnly keeps jobs whose work type is remote. A job labeled hybrid is not kept, even if one of its locations says "Remote" or Ashby's own remote flag is on (Ashby sets that flag on many hybrid jobs that have no remote location). When the employer gives no work type, the ATS's remote flag decides and, without a flag, a location that says "Remote". To keep every job that has "Remote" in a location, use locationKeywords with Remote instead.
How current is the data? Each run reads the live boards. scrapedAt is the time of the run; postedAt and updatedAt are the dates the ATS reports.
Why is companyName empty for Lever and Ashby? Their public APIs do not include it. Use board, or keep your own mapping from input to company.
A company was not found. What can I do? Use the exact board URL from the company's job pages instead of the name. Check the OUTPUT record for the reason. A company that fails does not stop the run.
Are Greenhouse boards on the EU domain supported? Not yet. Boards at job-boards.eu.greenhouse.io are recognized but not supported: that company is reported as failed in the run summary and the other companies continue.
Do you support Workday, SmartRecruiters or other ATS? Not in this Actor, which covers Greenhouse, Lever and Ashby. For Workday career sites use our Workday Jobs Scraper. For other systems, tell us which one you need in the Issues tab.
Support
Found a problem, or need another ATS? Open an issue in the Issues tab of this Actor and include the run ID.
Changelog
- Pricing (2026-10-24): lower prices per job for the Bronze, Silver and Gold discount tiers (see Pricing); the Free tier price is unchanged.
- 0.3 (2026-10-22): Remote jobs only no longer keeps Ashby jobs labeled hybrid: Ashby marks many hybrid jobs as remote, and the work type now decides, as for Greenhouse and Lever (see the FAQ). Descriptions also lose LinkedIn tags with a recruiter's initials, such as "#LI-AB1". The run's status message counts skipped companies separately from the successful ones. Lever boards are read in pages of 25 postings with a longer wait, so a slow answer from Lever no longer stops a board with a timeout. In only-new mode without Remote jobs only, an Ashby hybrid job returned before with
isRemote: trueis returned (and charged) once more, withisRemotenowfalse. - 0.2 (2026-10-09): descriptions remove more phone numbers (national numbers written in one or two blocks, such as UK and Australian numbers, and numbers after labels like "Phone:") and names after "Contact:" or "Name:" at the start of a line.
- 0.1 (2026-10-08): first public release.
- Reads public job boards on Greenhouse, Lever (including the EU instance) and Ashby, from board URLs,
ats:boardnames, careers-page URLs or company names (up to 1,000 per run). - One output schema for all three, with locations, remote and workplace type, dates, apply link and salary fields where the employer publishes them.
- Filters: title keywords, location keywords, remote only, maximum jobs per company and in total.
- Optional job descriptions as plain text, with email addresses, phone numbers and names after labels such as "Recruiter:" removed.
- Only-new-or-changed mode for scheduled runs, with separate histories through
stateKey. - Run summary per company in the
OUTPUTrecord; one failing company does not stop the run. - Pay-per-event pricing: $0.0015 per job saved. Free plan: up to 100 jobs per run.
- Known limits: Greenhouse boards on the EU domain are not supported yet; Lever and Ashby do not provide the company name.
- Reads public job boards on Greenhouse, Lever (including the EU instance) and Ashby, from board URLs,