ATS Jobs Scraper: Workday, Greenhouse, Lever & 4 More
Pricing
Pay per usage
ATS Jobs Scraper: Workday, Greenhouse, Lever & 4 More
Open jobs from company career pages on Workday, Greenhouse, Lever, Ashby, Workable, Recruitee and Personio, hiring signals per company (new roles, departments, spikes) and new-only monitoring for schedules. Public endpoints, no login, no proxy.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Tinlark
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
27 minutes ago
Last modified
Categories
Share
ATS Jobs Scraper: Workday, Greenhouse, Lever, Ashby, Workable, Recruitee and Personio
Get every open job from company career pages that run on Workday, Greenhouse, Lever, Ashby, Workable, Recruitee or Personio, as clean, uniform records. Switch to signals mode for one hiring summary per company, or to new-only mode to receive only the jobs that appeared since your last run.
The Actor reads the public job-board endpoints that these applicant-tracking systems (ATS) provide for company career sites. It needs no login, no browser and no proxy.
Use cases
- Workday jobs scraper, Greenhouse jobs API, Lever postings, Ashby, Workable, Recruitee and Personio in one Actor. Give it board names, job-board or career-site URLs or company domains and get the same fields for all seven vendors.
- Hiring signals for sales and recruiting teams. One row per company: open roles, roles by department, new roles in the last 7 and 30 days, roles that closed, seniority mix and a hiring-spike flag.
- Daily monitoring. Schedule the Actor with a State name and use
new-onlymode. It returns just the jobs that are new since the last run, so a daily schedule stays cheap. - Filter at the source. Keywords, departments, locations, remote only, posted within N days.
- Find a company's job board from its domain. Enter
notion.soand the Actor looks for a linked board of any of the seven vendors on the company's home and careers pages, where the site's robots.txt allows it.
Who it is for
Recruiters and sourcers tracking competitors' openings, sales and RevOps teams who use hiring as a buying signal, job-board and newsletter builders, and analysts who study hiring trends.
Input
| Field | What it does |
|---|---|
companies (required) | Board name (stripe), vendor and board name (lever:palantir), job-board or career-site URL (https://jobs.ashbyhq.com/ramp) or company domain (notion.so). See the table below for each vendor. |
mode | jobs (default), signals or new-only. |
atsFilter | Limit to some of greenhouse, lever, ashby, workable, recruitee, personio, workday. Empty means all seven. |
keywords, excludeKeywords | Matched against title, department and team, not case sensitive. |
departments, locations | Text that the department/team or any location must contain. |
remoteOnly | Keep remote jobs only. |
postedWithinDays | Keep jobs first published within N days. |
includeDescription | Add the job description as plain text (larger output). |
maxJobsPerCompany | Newest jobs first. Default 25. |
maxItems | Stop after this many billable rows. Default 1000. |
stateKey | A name such as daily-sales-hiring. Saves what was seen so later runs can report new and closed jobs. Required for new-only. |
emitExistingOnFirstRun | In new-only mode, return all current jobs on the first run instead of just recording them. |
includeClosed | With a stateKey, add a free row (status: "closed") for each job that disappeared. |
How to name a company on each vendor
| Vendor | Board name or vendor:board | URL you can paste |
|---|---|---|
| Greenhouse | greenhouse:stripe | https://boards.greenhouse.io/stripe |
| Lever | lever:palantir | https://jobs.lever.co/palantir |
| Ashby | ashby:ramp | https://jobs.ashbyhq.com/ramp |
| Workable | workable:huggingface (the name in apply.workable.com/<name>) | https://apply.workable.com/huggingface/ |
| Recruitee | recruitee:bunq (the name in <name>.recruitee.com) | https://bunq.recruitee.com |
| Personio | personio:matrix42 (the name in <name>.jobs.personio.de) | https://matrix42.jobs.personio.de |
| Workday | workday:nvidia.wd5/NVIDIAExternalCareerSite (tenant, data-centre number and career-site name) | https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite |
A bare name such as stripe is tried on Greenhouse, Lever, Ashby, Workable, Recruitee and Personio in that order, and the first board that lists jobs is used. Workday needs the career-site name too, so use the URL or workday: form. Custom careers domains that sit in front of Recruitee or Workable are not recognised from the URL; use recruitee:name or workable:name.
Example input
{"companies": ["stripe", "lever:palantir", "https://jobs.ashbyhq.com/ramp", "workable:huggingface", "recruitee:bunq","personio:matrix42", "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite", "notion.so"],"mode": "jobs","keywords": ["account executive", "sales"],"postedWithinDays": 30,"maxJobsPerCompany": 25}
Example: watch for new jobs every day
{"companies": ["ramp", "notion", "vercel"],"mode": "new-only","stateKey": "gtm-watchlist","departments": ["Sales", "Marketing"]}
The first run records the jobs that are open today and returns nothing, so you are not charged for the backlog. Every later run returns only jobs that were not there before. Use a different stateKey for each watch list.
Output
Results go to the default dataset. Download them as JSON, CSV, Excel or XML, or read them through the API. The Jobs, Company signals and Problems views show the main fields.
Job row (real output, trimmed)
{"recordType": "job","atsVendor": "ashby","company": "Ramp","boardToken": "ramp","jobId": "0d731586-3626-48fb-9dc5-3061ae5fd240","title": "Customer Experience Associate - London","department": "Customer Experience","team": "CX Frontline","locations": ["London"],"isRemote": false,"workplaceType": "hybrid","employmentType": "full-time","seniority": "junior","salaryMin": 39000,"salaryMax": 43000,"salaryCurrency": "GBP","salaryInterval": "year","postedAt": "2026-10-01T18:38:56Z","jobUrl": "https://jobs.ashbyhq.com/ramp/0d731586-3626-48fb-9dc5-3061ae5fd240","applyUrl": "https://jobs.ashbyhq.com/ramp/0d731586-3626-48fb-9dc5-3061ae5fd240/application","sourceUrl": "https://api.ashbyhq.com/posting-api/job-board/ramp","status": "open"}
Company signal row (real output, trimmed)
{"recordType": "signal","company": "Notion","domain": "notion.so","atsVendor": "ashby","openRoles": 134,"rolesByDepartment": { "Sales": 44, "Engineering": 16, "Outcomes Architect": 14, "People": 11 },"seniorRoles": 47,"remoteRoles": 0,"newLast7d": 10,"newLast30d": 29,"closedLast30d": null,"hiringSpike": false,"latestTitles": ["Software Engineer, Mobile Core (Android)", "Forward Deployed Architect", "Product Manager"]}
Field notes
postedAtis the vendor's first-published date (Greenhousefirst_published, LevercreatedAt, AshbypublishedAt, Workablepublished_on, Recruiteepublished_at, PersoniocreatedAt), in UTC. Workable gives a date only (midnight UTC). Workday's list only says "Posted Today", "Posted 5 Days Ago" or "Posted 30+ Days Ago":postedAtis then the day (midnight UTC), and empty for "30+". WithincludeDescriptionthe Actor also reads each returned Workday job's page and sets the exact start date.- Salary fields are filled only when the employer publishes a pay range on the posting (Greenhouse pay transparency, Lever
salaryRange, Ashby compensation, Recruitee salary). Most postings have none. Workable, Personio and Workday publish no structured salary in these feeds. Greenhouse postings with several regional ranges report the widest range in the first currency, and the full list is insalaryRanges. companycomes from the vendor for Greenhouse, Workable and Recruitee. Lever, Ashby, Personio and Workday do not name the company, so it is derived from the board name (rampbecomesRamp).seniorityis a heuristic based on the title only (executive,director,staff+,senior,manager,junior,intern,unspecified).isRemoteuses the vendor's workplace type where it exists (Lever, Ashby, Workable, Recruitee) and the word "remote" in the location or title for Greenhouse, Personio and Workday (withincludeDescription, Workday's own remote type is used too).- Workable lists a job once per location; the Actor merges them into one job with all locations. Locations the employer hides on its job page (usual for remote roles) are not returned.
- Workday has no department or employment type in its list, and shows "5 Locations" instead of names.
departmentstays empty (sorolesByDepartmentin signals mode is "Unspecified" for Workday and thedepartmentsfilter finds nothing);employmentType, all locations and the description come withincludeDescription. Filter Workday jobs withkeywordson the title. - Personio feeds often contain no description text at all;
descriptionTextis then empty.departmentis the department set in Personio. closedLast30dandopenRolesChangeSinceLastRunarenulluntil you use astateKeyand the Actor has run at least twice.openRolesChangeSinceLastRuncompares all open roles on the board with the previous run, whatever your filters are;openRolescounts the roles that match your filters.hiringSpikeistruewhen at least 3 roles were posted in the last 7 days and that is at least twice the weekly average of the 23 days before.- Rows with
recordType: "error"are free and list entries that could not be resolved to a board, with the reason. - A run summary (rows, errors, requests, duration) is saved under the
SUMMARYkey of the run's key-value store.
Pricing
Free during launch (until 31 October 2026). You pay only Apify's own platform usage for your runs.
Measured platform usage: about $0.003 to $0.005 per 1,000 job rows on our measurements (a run of 22 boards on all seven vendors with 7,756 jobs cost $0.026 in platform usage and took under 2 minutes; a run of 19 Greenhouse, Lever and Ashby boards with 5,859 jobs cost $0.03 and took 6 seconds). On the Apify free plan that usage is covered by your monthly credit.
From 1 November 2026: pay per event. Planned prices, shown here so you can budget:
| Event | Price | When it is charged |
|---|---|---|
| Job row | $1.50 per 1,000 ($0.0015 each) | Each job row in jobs and new-only modes |
| Company signal row | $5.00 per 1,000 ($0.005 each) | Each company row in signals mode |
| Board detected from a domain | $3.00 per 1,000 ($0.003 each) | Each company domain that was matched to a board. Not charged when no board is found, and not charged for board names or URLs. |
Not charged: error rows, closed-job rows, the baseline run of new-only mode, and a company signal row when no role matches your filters (openRoles is 0). Volume discounts apply on higher Apify plans (see the event prices shown on this page once they are active). Cost examples at the planned prices:
- 10 companies, 25 jobs each: 250 jobs, $0.375.
- 200 company signals: $1.00.
- A daily
new-onlywatch of 50 companies that posts 30 new jobs a day: about $0.045 a day.
Set Maximum cost per run in the run options to cap spending once pricing is active; the Actor stops cleanly when the cap is reached.
Limits and honest notes
- Seven vendors. SmartRecruiters is left out on purpose: its robots.txt disallows automated access to its posting API. BambooHR, Breezy HR, iCIMS, Taleo, Oracle Recruiting, SuccessFactors and others are not supported.
- Workday: up to 2,000 jobs per career site per run. Workday lists 20 jobs per request, read at one request a second, so a 2,000-job career site takes about 2 minutes (a plain jobs run with no filters stops after
maxJobsPerCompanyjobs and is much faster). Larger career sites are cut at 2,000 and the run summary says so. Some large employers run protected career sites that do not answer these requests; those come back as an error row. Career sites onmyworkdaysite.comare not supported. - Only companies on those vendors. The Actor cannot discover companies by itself. You supply boards, career-site URLs or domains.
- Domain lookup is best effort. It finds boards that are linked from the home page or a few standard careers URLs. In a test of 15 well-known company domains it found a board for 9. For the others, enter the board name or URL. Pages that load their links with JavaScript are not read.
- Bare board names are tried on Greenhouse, Lever, Ashby, Workable, Recruitee, then Personio. The first board that lists jobs is used. If two companies use the same name on different vendors, enter
vendor:nameor the URL. - Public jobs only. Only postings the employer publishes on its public job board are returned. Internal, unlisted and closed postings are not.
- Closed jobs need a
stateKey. The vendors do not publish closed jobs, so the Actor can only report them by comparing with its own earlier run. If a board suddenly returns zero jobs while it had five or more before, the Actor treats it as a vendor outage and does not mark them closed. - Pace. Greenhouse is read at no more than 4 requests a second, Lever at 1 request a second (its published crawl delay), Ashby and Workable at 2 a second, and Recruitee, Personio and Workday (each company has its own host) at 1 a second. Large lists of boards on one vendor therefore take proportionally longer. Failed requests are retried with backoff (HTTP 429, 5xx, network errors).
- The
new-onlymode keeps each board's state in a named key-value store calledats-state-<your stateKey>in your account.
Data source, terms and your responsibility
All data comes from the public job-board endpoints of each vendor, which exist so that companies' own career sites and third parties can list the postings:
- Greenhouse Job Board API (
boards-api.greenhouse.io): the vendor documents that job board data is public and needs no authentication for GET requests. - Lever Postings API (
api.lever.co): the vendor documents that postings in the published state are publicly viewable. Its robots.txt asks for a crawl delay of 1 second, which the Actor follows. - Ashby public job posting API (
api.ashbyhq.com/posting-api). - Workable job widget API (
apply.workable.com/api/v1/widget/accounts/<name>), the public JSON behind Workable's embeddable jobs widget. - Recruitee Careers Site API (
<name>.recruitee.com/api/offers/), documented by Recruitee as open without authentication. - Personio XML job feed (
<name>.jobs.personio.de/xml), the feed Personio documents for job boards. - Workday career-site search (
<tenant>.wd<N>.myworkdayjobs.com/wday/cxs/...), the JSON that every Workday career page loads for its own job list.
For Workable, Recruitee, Personio and Workday the Actor reads the robots.txt of each company's host before every board and skips it if the file disallows the endpoint (Personio answers Disallow: / for names that do not exist, which shows up as "not found"). Workday's website terms cover Workday's own sites; the career sites belong to each employer, so check the employer's terms for how you use the data.
The Actor identifies itself with a TinlarkBot User-Agent. For company domains it reads the home page and a few standard careers URLs only where the site's robots.txt allows. Job postings are the employers' own advertisements and contain no personal data about applicants; the Actor does not read applicant or recruiter data. Job content belongs to the employers: check their terms and the laws that apply to you (for example on unsolicited contact or on republishing postings) before you reuse the data. Each row carries jobUrl, applyUrl and sourceUrl so you can attribute and link back.
This Actor is not affiliated with Workday, Greenhouse, Lever, Ashby, Workable, Recruitee or Personio.
FAQ
Does it need a proxy or a login? No. The endpoints are public and the Actor is light: it uses plain HTTP requests.
How fresh is the data? Each run reads the live board. The data is as fresh as the employer's board.
How big can a run be? A cloud run with 22 boards on all seven vendors returned 7,756 jobs in 111 seconds, most of it the paged Workday career sites (5,469 jobs). Boards on the other vendors take about a second each. Memory use stays low (about 150 MB at peak), the default is 512 MB.
Why did my company return an error row? Typical reasons: the board name is spelled differently from the company name, the company uses another ATS, or a domain's careers page does not link to a supported board. The error field says which. Paste the job-board URL to be sure.
Can I get the job descriptions? Yes, turn on includeDescription. You get plain text.
Can I schedule it? Yes. Use Apify Schedules with a fixed stateKey and new-only mode for a daily feed of new jobs, or signals mode weekly to track hiring trends.
How do I use it from code or an AI agent? Call it through the Apify API or any Apify client library, or through Apify's MCP server. The input and output schemas are defined, so the fields are self-describing.
Disclaimers and legality: can I use this data? The Actor reads only what employers publish on their own public job boards, through the endpoints the vendors provide for that purpose, and it follows robots.txt and the vendors' stated crawl delays. It does not log in, read applicant data or get around blocks. The postings belong to the employers and are returned as published. You are responsible for how you use them, including the laws on unsolicited contact and on republishing content that apply to you. Tinlark is not affiliated with any of these vendors, and this is not legal advice.
Support
Something wrong or missing? Open an issue on this Actor's Issues tab with your input (the board name or URL) and what you expected.