ATS Jobs Scraper: Greenhouse, Lever, Workable +4
Pricing
from $1.20 / 1,000 jobs
ATS Jobs Scraper: Greenhouse, Lever, Workable +4
Jobs from Greenhouse, Lever, Workable, Recruitee, Personio, Breezy HR and Teamtailor in one format. Paste careers URLs or names. Keyword and remote filters.
Pricing
from $1.20 / 1,000 jobs
Rating
0.0
(0)
Developer
shawn slam
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
14 hours ago
Last modified
Categories
Share
Jobs from Greenhouse, Lever, Workable, Recruitee, Personio, Breezy HR and Teamtailor boards in one run. Paste careers URLs or just company names. $1.50 per 1,000 jobs.
One normalised schema for 7 ATS platforms, so you can watch a whole competitor list or target-account list without caring which ATS each company uses.
Quick start
- Press Start. The form is already filled with this example input, so the first run returns real rows in under a minute:
{"companies": ["https://job-boards.greenhouse.io/stripe","https://jobs.lever.co/palantir","huggingface","bunq"],"maxJobsPerCompany": 5}
- Swap in your own values, or call the Actor through the Apify API, Make, Zapier, n8n or the Python/JS clients with the same JSON.
- Download the results as JSON, CSV or Excel from the Output tab, or schedule the run to repeat.
Output fields
Every row has: platform, company, companyName, jobId, title, department, team, location, locations, country, workplaceType, isRemote, employmentType, seniority, salary, postedAt, updatedAt, url, applyUrl, boardUrl, scrapedAt, plus platform extras (e.g. requisitionId and customFields on Greenhouse, industry and education on Workable) and the description when you turn it on.
The full guide below is also published as "ATS Job Scraper: How to Pull Jobs from Greenhouse, Lever and 5 More ATS in One Format".
Which ATS platforms have a public jobs API?
Most ATS vendors publish each customer's open jobs as a public, unauthenticated feed, because that is what powers the embedded careers page. The ones this Actor reads:
| ATS | Public feed the Actor reads | Typical careers URL |
|---|---|---|
| Greenhouse | boards-api.greenhouse.io/v1/boards/{name}/jobs (also EU) | job-boards.greenhouse.io/{name} |
| Lever | api.lever.co/v0/postings/{name}?mode=json (also api.eu.lever.co) | jobs.lever.co/{name} |
| Workable | Workable's public job widget feed | apply.workable.com/{name} |
| Recruitee | {name}.recruitee.com/api/offers/ | {name}.recruitee.com |
| Personio | {name}.jobs.personio.de/xml (and .com) | {name}.jobs.personio.de |
| Breezy HR | {name}.breezy.hr/json | {name}.breezy.hr |
| Teamtailor | the career site's jobs.rss feed | {name}.teamtailor.com or a custom domain |
Not supported: Workday, Ashby, iCIMS, SmartRecruiters, BambooHR, SuccessFactors and Taleo. If your list is mostly enterprise companies on Workday, this is not the right tool, and we would rather tell you up front.
All of these feeds are public. You do not need an API key, and you are reading the same data every visitor to the careers page sees.
Why one schema matters
Here is what the same idea, "when was this job posted", looks like across the feeds: Greenhouse has first_published, Lever has createdAt in epoch milliseconds, Workable has published_on, Recruitee has published_at, Personio has createdAt inside XML, and Teamtailor has an RSS pubDate. Remote work is a boolean on some platforms, a workplaceType string on others, and only a word in the location text on Greenhouse. Salary is structured on Lever and Recruitee, free text on Breezy and missing on Greenhouse and Workable.
The Actor maps all of that into one row format:
platform, company, companyName, jobId, title, department, team, location, locations, country, workplaceType, isRemote, employmentType, seniority, salary, postedAt, updatedAt, url, applyUrl, boardUrl, scrapedAt and, when you turn it on, description. Platform extras such as requisitionId, customFields (Greenhouse), or industry and education (Workable) are kept as extra columns.
How to scrape jobs from multiple ATS, step by step
Step 1: Add companies in any form
Open ATS Jobs Scraper and press Try for free (a free Apify account is enough). In Companies, paste one per line. Three forms work, and you can mix them:
- A careers or job URL from any supported ATS, e.g.
https://jobs.lever.co/palantirorhttps://job-boards.greenhouse.io/stripe. This is the fastest and never ambiguous. platform:name, e.g.lever:palantir,workable:huggingface,recruitee:bunq.- A bare company name, e.g.
huggingface. The Actor then checks Greenhouse, Lever, Recruitee, Personio, Breezy HR, Workable and Teamtailor in that order and uses the first board that has open roles.
Auto-detection is handy for a long list of names but can pick the wrong board when two companies share a name on different platforms. For anything important, use URLs.
Step 2: Filter
Filters are applied before saving, and jobs your filters drop are free:
- Title keywords (any match, case-insensitive) and Exclude title keywords
- Location keywords: matched against location, all locations, country and workplace type
- Department keywords: matched against department and team
- Remote only
- Posted within days: e.g. 1 for a daily "new roles" feed
Step 3: Limits and description
- Max jobs per company caps each board. With Newest first on (the default), you get the newest N matches.
- Max results caps the whole run. The run stops cleanly at the cap and you are never billed past it.
- Include description adds the job text, cleaned of HTML and with emails and phone numbers removed.
Step 4: Run, check the summary, export
Press Start. Each board is one or two requests, so runs are quick. Auto-detected names take longer because they may probe several platforms. Then:
- Export from the Output tab (CSV, Excel, JSON) or via the dataset API.
- Open the
RUN_SUMMARYrecord in the key-value store. For every board it lists the platform, how many roles were open, how many matched your filters and how many were saved. Names that could not be found on any supported platform are listed with a reason, and are free.
Step 5: Schedule and connect
Save the input as a Task, add a daily Schedule with Posted within days = 1, and connect the dataset to Google Sheets, Slack, HubSpot or Salesforce through Make, Zapier or n8n. From code:
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("mrslm_data/ats-jobs").call(run_input={"companies": ["https://jobs.lever.co/palantir", "workable:huggingface", "recruitee:bunq", "stripe"],"titleKeywords": ["engineer", "developer"],"postedWithinDays": 14,})for job in client.dataset(run["defaultDatasetId"]).iterate_items():print(job["platform"], job["companyName"], job["title"], job["workplaceType"], job["postedAt"])
Real example 1: four companies on four different ATS
The Actor's default input:
{"companies": ["https://job-boards.greenhouse.io/stripe","https://jobs.lever.co/palantir","huggingface","bunq"],"maxJobsPerCompany": 5}
Result: 20 jobs in 8.4 seconds, 5 from each platform, with 20 job charges ($0.03). huggingface and bunq were bare names and were detected as Workable and Recruitee. The run summary showed 716 open roles at Stripe, 306 at Palantir, 21 at bunq and 6 at Hugging Face.
| platform | companyName | title | location | workplaceType | employmentType | seniority | postedAt |
|---|---|---|---|---|---|---|---|
| Greenhouse | Stripe | Head of AMER Startups (AI Sales) | San Francisco | 2026-10-28 | |||
| Lever | palantir | Deployment Strategist - Germany Forward Deployed | Washington, D.C. | hybrid | full-time | 2026-10-23 | |
| Recruitee | bunq | Support Experience Lead | Sofia, Sofia (stolitsa), Bulgaria | hybrid | fulltime-fixed-term | mid_level | 2026-10-27 |
| Recruitee | bunq | Product Owner - Credit | Amsterdam, Noord-Holland, Netherlands | hybrid | fulltime-permanent | experienced | 2026-10-23 |
| Workable | Hugging Face | Senior Machine Learning Engineer, Voice Agents - EMEA Remote | Paris, Île-de-France, France | remote | full-time | Mid-Senior level | 2026-09-02 |
Two rows from different platforms, same columns:
{"platform": "Lever","company": "palantir","companyName": "palantir","jobId": "6940fc9a-b79c-4935-a90f-1c6a02e54fb1","title": "Deployment Strategist - Germany Forward Deployed","team": "Echo","location": "Washington, D.C.","country": "US","workplaceType": "hybrid","isRemote": false,"employmentType": "full-time","postedAt": "2026-10-23T13:35:03.402Z","url": "https://jobs.lever.co/palantir/6940fc9a-b79c-4935-a90f-1c6a02e54fb1","applyUrl": "https://jobs.lever.co/palantir/6940fc9a-b79c-4935-a90f-1c6a02e54fb1/apply","boardUrl": "https://jobs.lever.co/palantir"}
{"platform": "Workable","company": "huggingface","companyName": "Hugging Face","jobId": "DB4D7C0EC8","title": "Senior Open-Source Python Engineer, ML Developer Tools - EMEA Remote","department": "Product","location": "France","country": "France","workplaceType": "remote","isRemote": true,"employmentType": "full-time","seniority": "Mid-Senior level","postedAt": "2026-09-21T00:00:00.000Z","url": "https://apply.workable.com/j/DB4D7C0EC8","industry": "Computer Software","education": "Master's Degree","boardUrl": "https://apply.workable.com/huggingface/"}
Note that Lever's public feed does not include a display name, so companyName is the board slug (palantir).
Real example 2: engineering roles only
{"companies": ["lever:palantir", "huggingface", "bunq", "https://job-boards.greenhouse.io/stripe"],"titleKeywords": ["engineer", "developer"],"maxJobsPerCompany": 3}
Result: 10 jobs, 10 charges. From the run summary: Stripe 716 open, 173 matched; Palantir 303 open, 188 matched; Hugging Face 6 open, 5 matched; bunq 21 open, 1 matched (an iOS Developer in Amsterdam). Only the 3 newest matches per company, 10 in total, were saved and billed. The jobs that were filtered out cost nothing.
What people use multi-ATS job data for
- Target-account hiring signals for sales. Keep a list of 300 target accounts, whatever ATS each one uses, and get a daily feed of new roles in the departments you sell to.
- Recruiting and staffing agencies. Track open roles across your client and prospect list in one sheet instead of 300 browser tabs.
- Investors, analysts and competitive intelligence. Measure hiring by team, country and seniority across a portfolio or a competitor set, and spot new offices and hiring freezes.
- Niche job boards and newsletters. Aggregate roles from a curated set of startups, with descriptions and apply links, in a single format.
- Labor-market research. Clean, deduplicated postings with consistent fields for analysis.
ATS job scraper vs. building it yourself
Doing it by hand means one script per ATS: seven URL patterns, two EU variants, JSON, XML and RSS parsers, seven date formats, remote and salary logic for each, company-name detection, deduplication, rate limits and retries. You also have to fix it when a vendor changes a field. That is weeks of work for a careful developer, and some ongoing maintenance.
A single-platform tool is cheaper if all your companies use the same ATS. If your list is all Greenhouse, our Greenhouse Jobs Scraper costs $1.00 per 1,000 jobs instead of $1.50.
This Actor is the best fit when your list is mixed, which most real lists are. You pay $1.50 per 1,000 jobs saved, with filtered-out jobs and unknown companies free. For example, a daily new-roles feed over 300 companies that yields 2,000 new jobs a month costs about $3 a month.
Pricing
- $1.50 per 1,000 jobs saved (Apify Silver plan $1.35, Gold $1.20), plus $0.00005 per run.
- You pay only for jobs saved after your filters. Companies that are not found, and jobs your filters drop, are free.
- Examples: the default run (20 jobs) costs $0.03. A full export of Palantir's roughly 300 Lever postings costs about $0.45.
FAQ
Is there a Lever jobs API? Yes: api.lever.co/v0/postings/{company}?mode=json is public and needs no key (EU boards use api.eu.lever.co). The Actor reads it and maps it into the same format as the other six platforms.
Do I need API keys for any of these platforms? No. Every supported feed is the public one behind the company's careers page.
Does it support Workday, Ashby, iCIMS or BambooHR? No. Supported platforms are Greenhouse, Lever, Workable, Recruitee, Personio, Breezy HR and Teamtailor. Companies on other systems are reported as not found and cost nothing.
How does auto-detection work? For a bare name, the Actor tries Greenhouse, Lever, Recruitee, Personio, Breezy HR, Workable and Teamtailor in that order and uses the first board that has open roles. A careers URL or platform:name skips detection.
Does it include salaries? When the platform publishes them. Lever, Recruitee and Personio can carry structured ranges (min, max, currency, period), and Breezy HR free text. Greenhouse and Workable public feeds have no salary field, so check the description.
Where does the data come from? From each company's public job board feed on its ATS: the same list of open roles the company shows on its careers page.
Does it include recruiter or applicant data? No. Only the public job ad. Email addresses and phone numbers in descriptions are removed.
How fresh is it? Live. Each run reads the boards at that moment, so closed jobs disappear and new ones appear.
Is it legal?
This Actor only reads pages and feeds that the website itself publishes to every visitor without a login. It obeys each site's robots.txt, keeps a polite request rate, and never tries to get past logins, paywalls, captchas or bot checks. It does not collect personal data such as emails, phone numbers or names of private individuals. You are responsible for how you use the data: follow the source site's terms, copyright and the privacy laws that apply to you (GDPR, CCPA, etc.). This tool is independent and not affiliated with or endorsed by the platforms it reads.