ATS Job Boards Scraper (Greenhouse, Lever, Ashby)
Pricing
$0.80 / 1,000 jobs
ATS Job Boards Scraper (Greenhouse, Lever, Ashby)
Live job postings straight from companies' Greenhouse, Lever and Ashby job boards, normalised into one schema: title, locations, remote/hybrid/onsite, department, employment type, salary range where published, full description, dates, apply URL. No cap, no stale database, no login.
Pricing
$0.80 / 1,000 jobs
Rating
0.0
(0)
Developer
KF P
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Share
Live job postings straight from the public job-board APIs that thousands of companies' careers pages run on: Greenhouse, Lever and Ashby. Give it company slugs or careers URLs and get every open posting as one normalised row — the same fields whichever ATS the company uses.
Why this one: it reads the boards live (no database, no 6-month window, no per-run cap), auto-detects the ATS from a careers URL, exposes structured salary ranges where boards publish them (Ashby, Lever), and bills per job delivered.
Input
| Field | Type | Description |
|---|---|---|
companies | array | Board slugs or URLs (max 500). A bare slug (stripe) is tried on all three ATSes; <ats>:<slug> (lever:spotify) pins one; any boards.greenhouse.io / job-boards.greenhouse.io / jobs.lever.co / jobs.ashbyhq.com URL works too. |
ats | array | Restrict auto-detection to some of greenhouse, lever, ashby. Empty = all. |
includeDescriptions | boolean | Keep the full description (HTML + plain text). Default true. |
maxItems | integer | Stop after this many jobs (default 500, max 100000). You pay only for pushed jobs. |
maxConcurrency | integer | Parallel requests (default 5, max 10); each API host is also paced ~1 request/s. |
proxyConfiguration | object | Optional; normally not needed. |
The slug is the path segment after the host on the company's careers page: boards.greenhouse.io/**stripe**, jobs.lever.co/**spotify**, jobs.ashbyhq.com/**openai**. Other careers domains (e.g. careers.example.com) are not auto-detected — open the page, find the embedded ATS link, and pass that.
{"companies": ["stripe", "lever:spotify", "https://jobs.ashbyhq.com/openai"],"maxItems": 2000}
Output
One dataset item per posting:
{"ats": "ashby","company": "ramp","id": "4f8c...","title": "Software Engineer, Backend","locations": ["New York", "San Francisco"],"workplaceType": "hybrid","isRemote": false,"department": "Engineering","team": "Platform","employmentType": "FullTime","compensation": { "min": 211400, "max": 290600, "currency": "USD", "interval": "1 YEAR", "summary": "$211.4K - $290.6K" },"descriptionHtml": "<p>...</p>","descriptionText": "...","publishedAt": "2026-08-24T14:44:49.699Z","updatedAt": null,"url": "https://jobs.ashbyhq.com/ramp/4f8c...","applyUrl": "https://jobs.ashbyhq.com/ramp/4f8c.../application","raw": { "address": { "addressLocality": "New York", "addressRegion": "New York", "addressCountry": "United States" }, "isListed": true, "compensationTiers": [] }}
raw carries ATS-specific extras: Greenhouse offices, metadata, requisitionId, internalJobId, language, applicationDeadline; Lever country, level, opening; Ashby address, isListed, compensationTiers.
Field coverage by ATS
| Field | Greenhouse | Lever | Ashby |
|---|---|---|---|
locations | split from the board's location string (•, ;, | separators) | categories.location + allLocations | location + secondaryLocations |
workplaceType / isRemote | derived: per-board metadata ("Workplace Type", "Location Type") or the location string ("Remote - USA", "Hybrid; In-Office", "Distributed"); null when neither says | workplaceType | workplaceType, isRemote |
department / team | departments joined with / | categories.department / team | department / team |
employmentType | per-board metadata ("Employment Type": Regular, Intern, ...) when the board has it, else null | categories.commitment | employmentType |
compensation | not exposed (sometimes in raw.metadata) | salaryRange when the board publishes it | compensation summary + salary component |
publishedAt / updatedAt | first_published / updated_at | createdAt / – | publishedAt / – |
Billing
Pay per event: one job event per posting pushed. Postings are de-duplicated per ATS id within a run. If the run's charge limit (maxTotalChargeUsd) is reached, it stops cleanly and reports how many jobs were pushed.
Speed and run timeout
Each board is one API call; a typical company takes 1–3 s, a very large board (800+ postings, ~15 MB) a few seconds more. 100 companies ≈ 2–4 min; large boards dominate (measured on Apify: 5,274 postings with descriptions from 24 boards in 47 s, SpaceX alone 2,281). Set maxItems and the run's charge limit together: a 10,000-job request with a $4 limit stops at ~5,000 jobs. A slug with no board on any ATS is reported in the status message under "no board found", not treated as a failure.
Limitations
- Only Greenhouse, Lever and Ashby boards; other ATSes (Workday, SmartRecruiters, iCIMS, …) are not supported.
- Greenhouse's public API has no salary and no native workplace/employment type (both are derived from location strings and per-board custom metadata, so some boards stay null); Lever's
salaryRangeand Ashby'scompensationare present only when the company chooses to publish them. locationsstrings are passed through as the ATS writes them; they are not geocoded or normalised to country/city.
Compliance
All three APIs are unauthenticated and documented as public: Greenhouse ("Job Board data is publicly available, so authentication is not required"), Lever (published postings "may be scraped by third parties"), Ashby (public job-posting API). No login, no personal data beyond what the company publishes about its own openings.