ATS Job API: Workday Jobs, Greenhouse Jobs, Ashby Jobs
Pricing
from $2.00 / 1,000 job postings
ATS Job API: Workday Jobs, Greenhouse Jobs, Ashby Jobs
Get jobs, job listings and openings from Greenhouse, Ashby, Lever and Workday. A job board scraper alternative: we read each vendor's official public job-board API instead of scraping, so your pipeline survives careers-page changes. One normalized dataset of hiring data. No login, no keys.
Pricing
from $2.00 / 1,000 job postings
Rating
0.0
(0)
Developer
FEI Yang
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
ATS Job Board Aggregator β Greenhouse + Ashby + Lever + Workday
Pull live job postings straight from the official public job-board APIs of the ATS platforms most companies use. Paste a company name, a board slug, or a full careers URL β get one normalized dataset back.
No login. No API keys. No scraping. No browser automation.
If you were about to write a job board scraper for Greenhouse, Ashby, Lever or Workday β this is the same data, read from the vendor's own JSON endpoint instead of the rendered page. Same fields, one input, and no HTML selectors to repair every time a careers page is redesigned.
| Provider | Endpoint used | Verified (2026-10-11) |
|---|---|---|
| Greenhouse | boards-api.greenhouse.io/v1/boards/{slug}/jobs | stripe β 729 jobs, gitlab β 221 |
| Ashby | api.ashbyhq.com/posting-api/job-board/{slug} | openai β 815, ramp β 165 |
| Lever | api.lever.co/v0/postings/{slug}?mode=json | leverdemo β 10 |
| Workday | {host}/wday/cxs/{tenant}/{site}/jobs (POST) | nvidia β 2,000 |
These are the same endpoints those vendors publish so companies can embed their job board on their own website. They return clean JSON, so this Actor does not break when a careers page is redesigned β a failure mode that kills HTML scrapers.
Workday matters if you need enterprise hiring data: it is the ATS behind a large share of the Fortune 500, and a single tenant can carry 2,000+ open roles.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
companies | array | ["stripe","openai","gitlab","ramp"] | Three accepted formats β see below |
keywords | array | [] | Match against title / department / team / location |
excludeKeywords | array | [] | Inverted filter |
locationFilter | string | "" | Case-insensitive substring, e.g. "Berlin" |
remoteOnly | bool | false | Keep remote postings only |
includeDescription | bool | false | Adds up to 20k chars of plain-text description |
maxItems | int | 2000 | Hard cap |
concurrency | int | 4 | Boards fetched in parallel |
requestDelayMs | int | 250 | Polite pause between boards |
The four ways to specify a company
stripe β auto-detects which ATS it usesashby:openai β explicit providerhttps://job-boards.greenhouse.io/gitlab β parsed straight from a careers URLworkday:nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSitehttps://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite
With auto-detect, the Actor tries Greenhouse β Ashby β Lever and keeps the first board that answers. A board that exists but currently has zero openings still counts as a hit β so you can tell "wrong slug" apart from "nothing open right now".
Workday is the one exception: it can't be auto-detected, because the tenant and site are defined by the customer and can't be derived from a company name. Give it either a workday:HOST/SITE target or the company's careers URL β just paste the URL from your browser and the Actor picks out the pieces.
Output
One uniform record per posting, whichever ATS it came from:
{"provider": "ashby","company": "ramp","companySlug": "ramp","boardUrl": "https://jobs.ashbyhq.com/ramp","jobId": "34413f8d-β¦","title": "Security Engineer, Cloud","department": "Engineering","team": "Backend","employmentType": "FullTime","location": "New York, NY (HQ)","allLocations": ["New York, NY (HQ)", "Remote (Canada)", "Remote (US)"],"isRemote": true,"url": "https://jobs.ashbyhq.com/ramp/β¦","applyUrl": "https://jobs.ashbyhq.com/ramp/β¦","postedAt": "2026-04-07T17:12:35.753Z","updatedAt": null,"compensation": "USD 180000β240000 / year"}
Results land in the default dataset; a SUMMARY key-value record reports which boards were found, how many jobs each returned, and which slugs failed.
Use cases
- Job boards & niche aggregators β build a vertical board from the companies you care about.
- Recruiting / sourcing β watch a competitor's hiring signals ("they just opened 12 infra roles").
- Sales & market signals β headcount growth by department, market by market.
- AI / research datasets β normalized, multi-company, multi-ATS job corpus with dates and locations.
Notes & limits
- No HR email addresses. These endpoints publish postings, not contact emails. Any Actor claiming otherwise is guessing.
- About
includeDescription. Plain text, HTML stripped, capped at 20,000 characters per posting. Measured 2026-10-14 on live boards: Greenhousestripereturns ~4.6k chars per posting, Ashbyopenai~6.9k, Leverleverdemo~1.4k. Two things worth knowing before you switch it on:- Ashby and Lever have no "no description" mode. Their public endpoints always return the text, so the toggle only decides whether it is written to your dataset. Only Greenhouse actually saves you bandwidth when it is off (
stripe: 451 KB β 5.6 MB with content on). - Descriptions are the biggest cost lever, because pricing is per returned posting, not per byte β enabling it does not change what you pay, but it does change dataset size.
- Ashby and Lever have no "no description" mode. Their public endpoints always return the text, so the toggle only decides whether it is written to your dataset. Only Greenhouse actually saves you bandwidth when it is off (
- A wrong board slug is a hard 404, not an empty result. Verified on Greenhouse:
boards-api.greenhouse.io/v1/boards/<nope>/jobsβ404 {"status":404,"error":"Job not found"}. The Actor reports it underfailuresin theSUMMARYrecord, so "wrong slug" never gets confused with "this company is not hiring". A board that answers with zero postings is still a successful hit. department/teamare populated for Ashby and Lever, but usuallynullfor Greenhouse β Greenhouse's board endpoint stopped returning per-job department objects. Verified, not assumed: 950 Greenhouse postings in a test run came back without departments while the Ashby/Lever ones all carried them.- Which ATS does a company use? Not provided by any API; auto-detect answers it by probing. Two calls, at most, for the common cases.
- Workday dates are approximate. Its list endpoint returns relative strings ("Posted Today", "Posted 30+ Days Ago"), so
postedAtis normalised to that day's midnight UTC and the raw string is kept inpostedText. Enable Include job description to replace it with the exactstartDatefrom the detail endpoint. - Workday locations can read "2 Locations". The list endpoint collapses multi-site postings; the full list is only in the detail endpoint.
allLocationstherefore holds one entry for Workday. - Five other ATS platforms are deliberately not supported. Workable (the widget endpoint returned an empty
jobsarray for six real slugs), SmartRecruiters (keys on internal company IDs β returnedtotalFound: 0for Visa, McDonald's and Ubisoft), Recruitee (401), BambooHR (302), Personio (XML only), Teamtailor (JSON Feed with no per-company endpoint). Listing a source that silently returns nothing is worse than not listing it β every provider here was verified against a live board first. - Only public, documented endpoints. No authentication, no rate-limit circumvention, no anti-bot evasion.
Tested (2026-10-11, direct connection, strict TLS)
| Case | Result |
|---|---|
stripe (auto-detect) | greenhouse / 729 jobs |
gitlab (auto-detect) | greenhouse / 221 jobs |
openai (auto-detect) | ashby / 815 jobs |
ramp (auto-detect) | ashby / 165 jobs |
lever:leverdemo (explicit) | lever / 10 jobs |
https://job-boards.greenhouse.io/gitlab (URL) | greenhouse / 221 jobs |
workday:nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite | workday / 2,000 jobs |
https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite (URL) | workday / 2,000 jobs |
ashby:nonexistent-board-xyz | clean error: ashby:404 |
workday:this-does-not-exist.wd5.myworkdayjobs.com/NoSite | clean error: workday:422 |
zzz-not-a-real-company | clean error, all three auto-detect providers probed |
| Full local regression, 8 boards | 8 ok / 0 empty / 3 expected errors β 61 seconds wall clock |
Workday pagination, measured: the list endpoint caps at 20 postings per request and returns 0 rows (not an error) if you ask for more β a silent truncation trap. We page by 20 and fetch pages concurrently, which brought a 2,000-posting board from 3m49s to 68s.
Descriptions, measured separately (2026-10-14): the Greenhouse endpoint does not include the posting body by default β the bare response carries 14 fields and no content at all, and only ?content=true adds it (stripe: 451,481 B β 5,630,572 B). That parameter is now always sent when the toggle is on, and the escaped HTML (<h2>β¦) is decoded before tag-stripping, so what you get is prose, not markup. Regression suite: src/test-description.js, 27/27 assertions, covering the three providers plus the 404 semantics.
Pricing
Pay-per-event, in two parts:
| Event | Price | What it covers |
|---|---|---|
| Actor start | $0.00005 per run | Booting the container (platform default β Apify still covers the first 5s of compute) |
| Result returned | $0.002 per posting | Each row pushed to the dataset |
That is ~$2 per 1,000 postings, plus a nominal start fee. A 50-company run returning 1,000β3,000 postings costs $2β6.
For context: the most-installed Actor in this category charges $0.012 per posting β six times more for largely the same public endpoints. We're pricing for adoption first, and will revisit once there is usage data.