ATS Job Feed — Greenhouse, Lever & Ashby in one schema
Pricing
from $2.00 / 1,000 job postings
ATS Job Feed — Greenhouse, Lever & Ashby in one schema
Pull live job postings from Greenhouse, Lever and Ashby career boards and get them back in one normalized schema. Official public endpoints only — no browser, no proxy, no API key.
Pricing
from $2.00 / 1,000 job postings
Rating
0.0
(0)
Developer
tokyo cat
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Pull live job postings straight from company career boards and get them back in one normalized schema, whichever applicant tracking system the company uses.
Most job scrapers cover a single ATS and hand you that vendor's raw JSON. If you aggregate postings from more than one, you end up writing the mapping layer yourself — categories.commitment on Lever, employmentType on Ashby, nothing at all on Greenhouse. This Actor does that mapping for you.
- Three ATS platforms — Greenhouse, Lever, Ashby
- Official public endpoints only — no browser, no proxy, no API key, no login
- One schema — same 28 fields regardless of source
- Filters run before billing — you are never charged for a posting a filter removes
What you get
Paste board URLs, get structured postings:
{"ats": "ashby","company": "ramp","jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245","title": "Security Engineer, Cloud","department": "Engineering","team": "Backend","employmentType": "Full-time","location": "New York, NY (HQ)","locations": ["New York, NY (HQ)", "Remote (Canada)", "Remote (US)", "Miami, FL"],"isRemote": true,"workplaceType": "Hybrid","country": "USA","publishedAt": "2026-04-07T17:12:35.753Z","jobUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-...","applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-.../application","salaryText": "$211.4K - $290.6K","salaryMin": 211400,"salaryMax": 290600,"salaryCurrency": "USD","descriptionHtml": "…","descriptionText": "…"}
Every posting also carries companySlug, requisitionId, departments, updatedAt, language, sourceUrl and scrapedAt.
Timestamps are always ISO 8601 UTC. Missing values are null, never an empty string — so salaryMin === null means the company did not publish a range, not that parsing failed.
Field coverage by ATS
| Field | Greenhouse | Lever | Ashby |
|---|---|---|---|
title, location, jobUrl, applyUrl | ✅ | ✅ | ✅ |
department | ✅ | ✅ | ✅ |
team | — | ✅ | ✅ |
employmentType | — | ✅ | ✅ |
isRemote | inferred from location | ✅ | ✅ |
workplaceType | — | ✅ | ✅ |
country | — | ✅ | ✅ |
publishedAt | ✅ | ✅ | ✅ |
updatedAt | ✅ | — | — |
salaryMin / salaryMax | — | when published | when published |
descriptionHtml / descriptionText | ✅ | ✅ | ✅ |
Dashes mark data the platform does not expose publicly. Nothing is guessed.
Input
{"boards": ["https://job-boards.greenhouse.io/stripe","https://jobs.lever.co/palantir","ashby:ramp"],"titleKeywords": ["engineer"],"titleExcludeKeywords": ["manager", "director"],"remoteOnly": true,"postedAfter": "2026-07-01","maxJobs": 500}
| Option | What it does |
|---|---|
boards | Board URLs or ats:slug pairs. Duplicates across forms are collapsed. |
includeDescription | Full posting body as HTML and text. Default true. |
includeCompensation | Posted salary ranges. Default true. |
titleKeywords / titleExcludeKeywords | Case-insensitive title matching. |
locationKeywords | Match any of the posting's locations, e.g. Tokyo, Remote. |
departmentKeywords | Match department or team. |
remoteOnly | Keep only postings the ATS flags remote. |
postedAfter | ISO date. Postings without a publish date are kept. |
maxJobsPerBoard / maxJobs | Hard caps on how much a run can charge. |
concurrency | Boards fetched in parallel. Default 5. |
Finding a board
The slug is the last part of the company's careers URL.
| ATS | Careers URL | boards entry |
|---|---|---|
| Greenhouse | job-boards.greenhouse.io/stripe | greenhouse:stripe |
| Lever | jobs.lever.co/palantir | lever:palantir |
| Ashby | jobs.ashbyhq.com/ramp | ashby:ramp |
You can paste the URL itself — the ATS is detected automatically.
Pricing
You are charged per job posting saved to the dataset, plus the standard Actor start event.
Charging happens on the same call that writes the posting, so:
- Filtered-out postings cost nothing.
- A board that 404s or times out costs nothing.
- If a run is aborted, you keep — and pay for — only what was already saved.
maxJobs and maxJobsPerBoard put a ceiling on any single run, and the Actor stops cleanly when it hits the maximum run cost you set in Apify Console.
Common uses
- Job boards and aggregators — refresh listings from a roster of companies on a schedule.
- Recruiting and talent research — track which teams a set of companies is hiring for, and when.
- Compensation benchmarking — collect published salary bands across Ashby and Lever boards.
- Hiring-signal lead generation — a company opening five sales roles is a company with budget.
- AI agents and RAG pipelines — a stable, flat schema that needs no per-vendor mapping.
Notes and limits
- Only publicly listed postings are returned. Confidential and internal-only roles are not exposed by these endpoints and are not accessible to this Actor.
- No personal data is collected. Postings describe roles, not people.
- Greenhouse returns the entire board in one request; large boards (500+ postings) come back in a few seconds. Lever is the slowest of the three.
- Turning
includeDescriptionoff makes Greenhouse boards roughly 10x smaller. Lever and Ashby return descriptions either way. - Boards that cannot be read are recorded in the
BOARD_ERRORSrecord in the run's key-value store, with the reason for each.
Development
npm installnpm test # unit tests, no networkapify run # end-to-end against live boards
Input for local runs goes in storage/key_value_stores/default/INPUT.json.