Greenhouse, Lever, Ashby & Recruitee Jobs Scraper avatar

Greenhouse, Lever, Ashby & Recruitee Jobs Scraper

Pricing

from $1.50 / 1,000 job results

Go to Apify Store
Greenhouse, Lever, Ashby & Recruitee Jobs Scraper

Greenhouse, Lever, Ashby & Recruitee Jobs Scraper

Scrape all open jobs from company career pages on Greenhouse, Lever, Ashby and Recruitee using their official public job-board APIs. One clean schema, salary ranges where published, keyword, location and remote filters, plus new-jobs-only monitoring. No login, no proxies.

Pricing

from $1.50 / 1,000 job results

Rating

0.0

(0)

Developer

Mark Demian

Mark Demian

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 hours ago

Last modified

Categories

Share

What does this ATS jobs scraper do?

Greenhouse, Lever, Ashby & Recruitee Jobs Scraper collects every open job from company career pages hosted on the four most common applicant tracking systems (ATS). You give it a list of companies (career-page URLs or names), and you get back one clean, normalized dataset: title, department, team, location, remote/hybrid status, employment type, salary range where the company publishes one, posting date, description, and the public job and apply URLs.

It reads the ATS vendors' official public job-board APIs, the same JSON feeds that power companies' own careers pages. That makes it fast (about 4,900 jobs from 26 companies in about 20–40 seconds in our tests), reliable (no HTML parsing, so a careers-page redesign doesn't break it) and cheap to run. It needs no login, no cookies, no proxies and no browser.

Try it now: click Start. The example input pulls 20 jobs each from Figma (Greenhouse), Palantir (Lever) and Ramp (Ashby).

Main features

  • 🏢 4 ATS platforms in one schema: Greenhouse, Lever, Ashby, Recruitee
  • 🔎 Auto-detection: paste a careers URL, ats:slug, or just a company slug
  • 💰 Salary extraction: structured pay ranges from the ATS (including Greenhouse's pay-transparency ranges), plus ranges found in the job text, and yearly min/max so hourly, monthly and annual pay are comparable
  • 🎯 Filters: title keywords (include and exclude), location keywords, remote/hybrid only, posted in the last N days
  • 🔔 Monitor mode: "Only new jobs since last run" turns a scheduled run into a new-job alert feed
  • 🛡️ Privacy by design: recruiter emails and phone numbers are stripped from descriptions, and contact fields are never collected
  • 🤝 Polite: respects robots.txt, waits at least 1 second between requests to the same host, and backs off on errors

Because it runs on Apify, you also get scheduling, a REST API, webhooks and integrations (Google Sheets, Slack, Zapier, Make, n8n, Airbyte and more), plus exports to JSON, CSV, Excel and XML.

What can you use it for?

  • Niche job boards and newsletters: build feeds like "remote Rust jobs" or "Toronto fintech jobs" from the companies you choose.
  • Hiring signals and market research: see which teams, locations and roles competitors, customers or portfolio companies are hiring for.
  • Recruiting and job-search automation: get daily alerts for new matching roles at your target companies.
  • Salary benchmarking: collect published pay ranges (common in pay-transparency regions such as NY, CA, CO and WA).

Supported systems

ATSAccepted input examplesData source (public API)
Greenhousehttps://boards.greenhouse.io/figma, https://job-boards.greenhouse.io/figma, greenhouse:figmaboards-api.greenhouse.io Job Board API
Leverhttps://jobs.lever.co/palantir, lever:palantirapi.lever.co Postings API
Ashbyhttps://jobs.ashbyhq.com/ramp, ashby:rampapi.ashbyhq.com Job Postings API
Recruiteehttps://bunq.recruitee.com, recruitee:bunq<company>.recruitee.com/api/offers

A bare slug such as figma is tried on Greenhouse, then Lever, Ashby and Recruitee, in that order, and the first non-empty board is used. Use an explicit ats:slug or a URL when you know the ATS. It is faster and avoids picking the wrong board.

A company's own careers domain (for example stripe.com/jobs) is not accepted directly. Use the ATS board URL or slug instead (see the FAQ).

How to use it

  1. Click Try for free or Start in Apify Console.
  2. In Companies / career boards, add one company per line (a URL, ats:slug or slug).
  3. Optionally add filters: title keywords, location keywords, remote only, or posted within N days.
  4. Set Max jobs per company to 0 to get every job. The example input uses 20 to keep your first run cheap.
  5. Click Start, then download the results as JSON, CSV or Excel, or use the API.
  6. For alerts, enable Only new jobs since last run and add a Schedule (for example daily), with an integration to Slack, Sheets or a webhook.

Input examples

Quick start (the example input):

{
"companies": ["greenhouse:figma", "https://jobs.lever.co/palantir", "ashby:ramp"],
"maxJobsPerCompany": 20
}

Remote engineering roles posted in the last 14 days, without descriptions:

{
"companies": [
"https://boards.greenhouse.io/stripe",
"https://boards.greenhouse.io/cloudflare",
"https://jobs.ashbyhq.com/ramp",
"lever:palantir"
],
"titleKeywords": ["engineer", "developer"],
"excludeTitleKeywords": ["intern", "manager"],
"remoteOnly": true,
"postedWithinDays": 14,
"includeDescription": false
}

Daily new-job monitor for a location (schedule it, and only jobs not seen in earlier runs are output):

{
"companies": ["greenhouse:figma", "greenhouse:datadog", "ashby:ramp", "recruitee:bunq"],
"locationKeywords": ["New York", "Remote"],
"onlyNewSinceLastRun": true
}

Input fields

FieldTypeDefaultDescription
companiesarray of strings(required)Career-board URLs, ats:slug, or bare slugs
titleKeywordsarray[]Keep jobs whose title contains any of these (case-insensitive)
excludeTitleKeywordsarray[]Drop jobs whose title contains any of these
locationKeywordsarray[]Keep jobs whose location, locations or workplace type contains any of these
remoteOnlybooleanfalseKeep only jobs whose location or workplace type mentions remote or hybrid
postedWithinDaysinteger0Keep jobs updated or posted in the last N days (0 = no limit)
includeDescriptionbooleantrueInclude the plain-text description (with emails and phones removed)
onlyNewSinceLastRunbooleanfalseMonitor mode: output only jobs not seen in earlier runs
maxJobsPerCompanyinteger0Cap on jobs per company after filters (0 = all)
requestDelayMsinteger1000Minimum delay between requests to the same host (minimum 1000)

Output

Each dataset item is one job posting. Example (description shortened):

{
"ats": "ashby",
"companySlug": "ramp",
"company": "ramp",
"jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"title": "Security Engineer, Cloud",
"department": "Engineering",
"team": "Backend",
"location": "New York, NY (HQ)",
"locations": ["New York, NY (HQ)", "Remote (Canada)", "Remote (US)", "Miami, FL"],
"workplaceType": "Hybrid",
"employmentType": "FullTime",
"salary": { "min": 211400, "max": 290600, "currency": "USD", "interval": "1 YEAR" },
"salaryText": "$211.4K - $290.6K",
"salarySource": "ats",
"salaryMinYearly": 211400,
"salaryMaxYearly": 290600,
"salaryCurrency": "USD",
"payRanges": null,
"postedAt": "2026-04-07T17:12:35.753Z",
"updatedAt": null,
"url": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application",
"descriptionText": "ABOUT RAMP\n\nRamp is building the smart infrastructure for finance teams…",
"key": "ashby:ramp:34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"scrapedAt": "2026-10-27T20:51:07.896Z"
}

Output fields

FieldDescription
atsgreenhouse, lever, ashby or recruitee
companySlugBoard identifier on the ATS (for example figma)
companyCompany display name when the ATS provides it (Greenhouse, Recruitee); otherwise the slug
jobIdThe job's ID on the ATS
titleJob title
department, teamAs published (can be null)
locationPrimary location text
locationsAll listed locations
workplaceTypeRemote, Hybrid or OnSite when stated. On Greenhouse it is inferred only from "remote" in the location, so it's often null
employmentTypeFor example FullTime, Full-time or Contract, as the ATS words it. Greenhouse's public API doesn't expose it
salary{min, max, currency, interval} or null
salaryTextHuman-readable range
salarySourceats (structured field from the ATS), description (parsed from the job text; an interval of year? or hour? is a guess), or null
salaryMinYearly, salaryMaxYearlySalary converted to a yearly amount in the original currency: hour × 2,080, day × 260, week × 52, month × 12. null when the period is unknown or one-time
salaryCurrencyCurrency of the salary and the yearly fields (no currency conversion)
payRangesGreenhouse only, when a job lists several ranges (pay zones or countries): every range with min, max, currency, interval and its label. salary then shows the widest span in the first range's currency
postedAt, updatedAtISO 8601 dates when the ATS exposes them
url, applyUrlPublic job page and application page
descriptionTextPlain-text description, with emails and phone numbers replaced by [email removed] / [phone removed] (omitted when includeDescription is false)
keyStable unique ID ats:companySlug:jobId, for deduplication
scrapedAtWhen this run collected the job

The Output tab has two views: Jobs (all jobs) and With salary. A RUN_STATS record in the run's key-value store lists boards found and not found, and any errors.

How complete is each field? Measured on our test set of 26 company boards and 4,869 jobs on October 27, 2026 (version 0.1.3). Your companies will differ.

ATSJobs in testSalary presentSalary from the ATS's own fieldWorkplace typeEmployment type
Greenhouse2,77449%38%23%0%
Lever62470%34%100%99%
Ashby1,45164%57%78%100%
Recruitee200%0%100%100%

Every job with a salary also got salaryMinYearly/salaryMaxYearly in this test. The rest of the salaries come from ranges parsed from the job text.

Was this useful? If this Actor saved you time, a quick star rating on the Reviews tab helps other people find it. If something didn't work, please open an issue instead, so it can be fixed.

How much does it cost to scrape Greenhouse, Lever, Ashby and Recruitee jobs?

This Actor uses pay-per-event pricing, so you pay per job result and nothing for compute:

  • $0.0015 per job in the dataset ($1.50 per 1,000 jobs)
  • plus Apify's standard Actor start event of $0.00005 per run (charged once per GB of memory; this Actor defaults to 1 GB)
ExampleJobsApproximate cost
Example input (3 companies × 20 jobs)60$0.09
One large company (around 500 open jobs)500$0.75
25 companies, all jobs5,000$7.50
Daily monitor, about 30 new jobs a day, for a month900$1.35

Costs are simply the number of jobs × $0.0015, plus a fraction of a cent per run. Filters are applied before results are saved, so you only pay for jobs that match. Monitor mode only charges for new jobs.

Control your spending: set Max cost per run in the run options. The Actor stops right away when the limit is reached (it cancels any board downloads still in progress), and jobs it couldn't deliver are not marked as "seen", so the next monitor run picks them up.

Free plan: Apify's free plan includes monthly platform credit (currently $5), which covers about 3,300 jobs from this Actor.

Use it from AI agents (Apify MCP)

AI agents and assistants (Claude, Cursor, VS Code and other MCP clients) can run this Actor through Apify's hosted MCP server. Add this to your MCP client's configuration. On first connection it opens your browser so you can sign in to Apify:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=fetch-actor-details,markdemian/ats-jobs-scraper"
}
}
}

Then ask things like "List Ramp's open engineering roles in New York" or "Which of these 10 companies posted a remote data job this week?"

Tips for agents:

  • Set includeDescription: false and a small maxJobsPerCompany to keep responses short and cheap.
  • Use salaryMinYearly / salaryMaxYearly to compare pay across hourly and annual roles.
  • Set a max cost (maxTotalChargeUsd in the call options) to cap what a single call can spend.

What's new

  • 0.1.3 (October 27, 2026)
    • Greenhouse salaries now come from Greenhouse's structured pay-transparency ranges. In our test, Greenhouse jobs with a salary went from 11% to 49%.
    • New salaryMinYearly, salaryMaxYearly and salaryCurrency fields for all four ATSes, and payRanges for Greenhouse jobs that list several pay zones.
    • The With salary output view shows the yearly columns.
  • 0.1.2 (October 27, 2026): when the max cost per run is reached, the Actor now stops right away instead of finishing board downloads it can no longer output.
  • 0.1.1 (October 27, 2026): first public release.

FAQ

This Actor reads only public job postings that companies deliberately publish through their ATS's public job-board APIs, the same data shown on their careers pages without logging in. It does not collect candidate data, applicant information or anything behind a login. It removes email addresses and phone numbers from descriptions and never maps recruiter or contact fields. You are responsible for how you use the data. Respect each company's terms, and consult a lawyer if you're unsure about your use case.

Does it collect personal data?

No, by design. Job postings describe roles, not people. Contact details that sometimes appear in description text (recruiter emails and phone numbers) are automatically redacted, and fields like Recruitee's mailbox_email are never mapped. A job description can still mention a hiring manager by name in free text. If that matters for your use case, set includeDescription to false.

How do I find a company's ATS and slug?

Open the company's careers page and click a job. If the URL or the application form is on boards.greenhouse.io, job-boards.greenhouse.io, jobs.lever.co, jobs.ashbyhq.com or <name>.recruitee.com, paste that URL. If you only know the name, try the bare slug (for example figma) and the Actor will check all four systems.

Why was a company "not found"?

The company either uses a different ATS (Workday, SmartRecruiters, iCIMS, Taleo, its own system and so on), uses a different slug, or has no public board. Not-found companies are listed in the run log and in RUN_STATS. They are not charged, because no job results are produced.

How fresh is the data?

It is live: every run reads the ATS APIs directly, at the moment the run happens. For alerts, schedule it daily or hourly with Only new jobs since last run.

How does monitor mode work?

The Actor remembers the key of every job it has output in a named key-value store in your account (ats-jobs-scraper-seen). With monitor mode on, jobs already seen are skipped. To start fresh, delete that store in Storage.

Can I use it via API, Python, JavaScript, Zapier or Make?

Yes. Like every Apify Actor you can start it through the Apify API or client libraries, receive webhooks when it finishes, and connect it to Zapier, Make, n8n, Google Sheets, Slack and more. See the API tab.

Something's wrong or missing?

Open an issue on the Issues tab with the company input you used. Requests for more ATS platforms are welcome.

Limitations

  • Supports Greenhouse, Lever, Ashby and Recruitee only. Workday, SmartRecruiters, iCIMS, Taleo, BambooHR, Workable and others are not supported yet.
  • It returns what the ATS publishes. Fields the vendor's public API doesn't expose (for example employment type on Greenhouse) stay null.
  • Salaries parsed from description text (salarySource: "description") are a best-effort heuristic. Check the salaryText, and treat an interval of year? or hour? as a guess.
  • Greenhouse doesn't state the pay period as a field, so it's read from the range's label (for example "Annual Base Salary Range" or "Hourly Rate"). When the label doesn't say, the period is guessed from the amount and marked year? or hour?.
  • The yearly fields assume full-time hours (2,080 a year) and don't convert currencies.
  • company is the slug for Lever and Ashby, because their public APIs don't include a company display name.
  • A bare slug is matched to the first ATS with a non-empty board. If two systems use the same slug for different companies, use an explicit ats:slug.
  • Some companies use their own careers domain in front of an ATS. Use the underlying ATS board URL or slug.
  • Requests to the same host are spaced at least 1 second apart, so very long lists on a single ATS take roughly 1 second per company.
  • It does not apply to jobs, and it does not collect applicant or candidate data.

Was this useful? If this Actor saved you time, a quick star rating on the Reviews tab helps other people find it. If something didn't work, please open an issue instead, so it can be fixed.