Greenhouse, Lever & Ashby Jobs | $1/1K | Auto-Detect ATS avatar

Greenhouse, Lever & Ashby Jobs | $1/1K | Auto-Detect ATS

Pricing

from $1.00 / 1,000 job returneds

Go to Apify Store
Greenhouse, Lever & Ashby Jobs | $1/1K | Auto-Detect ATS

Greenhouse, Lever & Ashby Jobs | $1/1K | Auto-Detect ATS

Scrape jobs from any Greenhouse, Lever or Ashby board. Auto-detects which ATS a company uses, returns one normalized schema across all three, and parses salary out of the posting text. $1 per 1,000 jobs.

Pricing

from $1.00 / 1,000 job returneds

Rating

0.0

(0)

Developer

Extract Kit

Extract Kit

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Greenhouse, Lever & Ashby Jobs Scraper

Scrape job postings from any company running Greenhouse, Lever or Ashby — three of the most widely deployed applicant tracking systems — and get them back in one schema, whichever ATS they came from.

Built on the providers' own public JSON APIs. No proxies, no login, no browser, no anti-bot workarounds.

What makes this different

You don't need to know which ATS a company uses. That is the whole point. Give it stripe and it works out that Stripe is on Greenhouse; give it ramp and it finds Ashby. Single-ATS Actors push that lookup back onto you, which is unhelpful when you have 200 companies and no idea how they're split.

One schema across all three. Greenhouse calls a title title, Lever calls it text. Lever timestamps in epoch milliseconds, Ashby in ISO 8601, Greenhouse in ISO with an offset. Ashby says FullTime, Lever says Full-time. All of it is normalized before you see it.

Salary, including where the provider doesn't publish it. Ashby returns structured compensation. Greenhouse and Lever return none at all — any pay range lives in the posting prose, because US pay-transparency laws require it in the text rather than in a field. This Actor reads both, and tells you which is which:

"salary": {
"min": 211400, "max": 290600, "currency": "USD",
"interval": "year", "source": "structured", "raw": "$211.4K – $290.6K"
}

source is structured (from the provider, reliable) or parsed (read from prose, best-effort). raw is the exact text the numbers came from, so you can audit any parse you don't trust. When no range can be established confidently, salary is null — the parser is deliberately biased toward returning nothing rather than guessing, because a wrong salary silently corrupts your dataset in a way an empty field never does.

A bad slug doesn't cost you the run. Unrecognized companies are recorded in the COMPANIES key-value record with a reason, and the other boards continue.

Input

Give it board slugs, full board URLs, or a mix:

{
"companies": ["stripe", "https://jobs.lever.co/palantir", "https://jobs.ashbyhq.com/ramp"],
"titleKeywords": ["engineer"],
"locationKeywords": ["remote", "berlin"],
"remoteOnly": false,
"includeSalary": true
}

Pasting a board URL is worth it — the ATS is read straight off the hostname, which skips detection entirely.

FieldDefaultNotes
companiesRequired. Slugs (stripe) or board URLs.
providerautoPin to one ATS only if every company on the list uses it.
titleKeywords[]Case-insensitive substring; any match keeps the job.
locationKeywords[]Matches secondary locations too.
departmentKeywords[]Matches department or team.
remoteOnlyfalseInferred from location text on Greenhouse.
employmentTypes[]⚠️ Greenhouse publishes none — this filter excludes all Greenhouse postings.
postedAfternullISO date. Excludes undated postings.
includeDescriptionfalseAdds 5–15 KB per job. Salary parsing works without it.
includeSalarytrue
maxJobsPerCompany / maxJobsTotal00 = no limit. Applied after filtering.
concurrency3Boards fetched at once.

Filters are applied before you are charged. If you ask for engineering roles in Berlin, you pay for those — not for the other 540 postings that had to be fetched to find them.

Output

One record per job:

{
"provider": "ashby",
"company": "ramp",
"companyName": "ramp",
"id": "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)"],
"workplaceType": "hybrid",
"isRemote": true,
"employmentType": "full-time",
"employmentTypeRaw": "FullTime",
"salary": { "min": 211400, "max": 290600, "currency": "USD", "interval": "year", "source": "structured", "raw": "$211.4K – $290.6K" },
"publishedAt": "2026-04-07T17:12:35.753Z",
"updatedAt": "2026-04-07T17:12:35.753Z",
"url": "https://jobs.ashbyhq.com/ramp/34413f8d",
"applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d/application",
"scrapedAt": "2026-08-17T09:00:00.000Z"
}

Two extra records are written to the key-value store: SUMMARY (counts by provider, how many carried salary, how many were remote) and COMPANIES (per-board outcome, including why any board failed).

What this Actor will not do

  • No LinkedIn, Indeed or Glassdoor. Those are login-walled or Cloudflare-defended, and scraping them means a permanent proxy bill and an anti-bot arms race. This Actor reads official public APIs only, which is why it doesn't break.
  • No SmartRecruiters. Its robots.txt is Disallow: / for every agent but LinkedIn's. Greenhouse, Lever and Ashby all permit the paths used here.
  • No unlisted postings. Ashby's isListed: false marks jobs a company deliberately hid from its public board; those are dropped.

Field coverage by provider

Not every provider publishes every field. Rather than fabricate them, the Actor reports null:

FieldGreenhouseLeverAshby
Title, location, URL, dates
Department / team
Employment type❌ never published
Workplace type⚠️ inferred from location
Structured salary❌ parsed from text⚠️ rare
Company display name❌ slug used❌ slug used