ATS Jobs Scraper — Greenhouse, Lever & Ashby avatar

ATS Jobs Scraper — Greenhouse, Lever & Ashby

Pricing

from $2.00 / 1,000 results

Go to Apify Store
ATS Jobs Scraper — Greenhouse, Lever & Ashby

ATS Jobs Scraper — Greenhouse, Lever & Ashby

Pull open job postings straight from companies' public ATS boards (Greenhouse, Lever, Ashby). Full descriptions, skills, normalized salary, cross-run dedupe and webhook delivery. No browser, no proxy.

Pricing

from $2.00 / 1,000 results

Rating

0.0

(0)

Developer

Mukesh Kumar

Mukesh Kumar

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

Share

Pull open job postings straight from companies' public ATS boards. One HTTP request per board returns every job with the full description — no browser, no proxy, no anti-bot, so it's fast and cheap.

Reads only public, company-published job-board APIs. Not affiliated with Greenhouse, Lever, or Ashby.

Why this vs a job-aggregator scraper

Aggregators (Indeed etc.) are Cloudflare-walled and expensive to scrape. Company ATS boards expose clean public JSON — richer data (full description, department, team, comp when published), zero blocking, near-zero cost.

Input

Give board tokens per provider, and/or paste board URLs (provider auto-detected). At least one board required.

{
"greenhouseBoards": ["gitlab"],
"leverBoards": ["leverdemo"],
"ashbyBoards": ["Ramp"],
"boardUrls": ["https://jobs.lever.co/someco", "https://boards.greenhouse.io/anotherco"],
"searchKeywords": ["engineer", "data"],
"remoteOnly": true,
"postedWithinDays": 14,
"maxJobs": 0
}
FieldWhat it does
greenhouseBoards / leverBoards / ashbyBoardsProvider tokens (e.g. gitlab, leverdemo, Ramp)
boardUrlsAny board URL; provider auto-detected from host
searchKeywordsKeep jobs whose title/description contains ANY (case-insensitive)
locationFilter / departmentFilterSubstring filters
remoteOnlyKeep only remote-detected roles
postedWithinDaysRecency filter (0 = all)
maxJobsPerBoard / maxJobsCaps (0 = no limit)
extractSkillsAdds skills[], detectedSeniority, minYearsExperience
normalizeSalary + targetCurrencyAdds normalizedSalary{} when comp is published
onlyNewSinceLastRun + dedupeStoreNameCross-run dedupe for scheduled monitoring
notifyWebhookUrlPOST run's jobs to Slack/Make/Zapier/custom on finish

Output

One record per job, normalized across providers:

{
"source": "greenhouse",
"company": "GitLab",
"jobId": "8503792002",
"title": "Account Executive - Italy",
"department": "Sales", "team": "EMEA",
"location": "Remote", "isRemote": true,
"employmentType": "Full-time",
"descriptionText": "…",
"salary": null,
"normalizedSalary": null,
"skills": ["SQL", "Salesforce"],
"detectedSeniority": "mid",
"applyUrl": "https://job-boards.greenhouse.io/gitlab/jobs/8503792002",
"jobUrl": "https://job-boards.greenhouse.io/gitlab/jobs/8503792002",
"postedAt": "2026-04-30T22:34:50.000Z",
"scrapedAt": "2026-05-18T10:00:00.000Z"
}

All slugs below were verified live to return jobs. Drop them into the matching input field.

Greenhouse (greenhouseBoards): gitlab stripe airbnb dropbox databricks robinhood instacart reddit figma asana discord gusto samsara cloudflare twitch lyft pinterest datadog mongodb elastic peloton sofi affirm chime betterment flexport amplitude airtable calendly faire scaleai anthropic

Ashby (ashbyBoards, case-sensitive): Ramp Vanta Linear Watershed Replit Modal Baseten Browserbase Notion Perplexity Cohere Zip Sierra Decagon Cursor

Lever (leverBoards): spotify gopuff ro swordhealth

Companies change ATS providers over time. If a slug returns nothing, the company likely moved — check their careers page URL (boards.greenhouse.io/…, jobs.lever.co/…, jobs.ashbyhq.com/…) and use that slug.

How it works

  • Greenhouse: boards-api.greenhouse.io/v1/boards/{token}/jobs?content=true
  • Lever: api.lever.co/v0/postings/{company}?mode=json
  • Ashby: api.ashbyhq.com/posting-api/job-board/{org}?includeCompensation=true

Each returns all postings with full content in a single request — no pagination, no detail fetch. Crawlee HttpCrawler, no browser. Enrichment, dedupe and webhook delivery are shared modules.

Scheduled monitoring

Set onlyNewSinceLastRun: true + a dedupeStoreName, optionally notifyWebhookUrl, then schedule the actor. Each run emits (and POSTs) only postings unseen in prior runs.

Local dev

npm install
# edit storage/key_value_stores/default/INPUT.json
npm start