Job Postings Scraper - Greenhouse, Lever & Ashby (Multi-ATS) avatar

Job Postings Scraper - Greenhouse, Lever & Ashby (Multi-ATS)

Pricing

from $0.40 / 1,000 jobs

Go to Apify Store
Job Postings Scraper - Greenhouse, Lever & Ashby (Multi-ATS)

Job Postings Scraper - Greenhouse, Lever & Ashby (Multi-ATS)

Scrape live job postings from any Greenhouse, Lever, or Ashby careers board by slug, URL, or auto-detect. Returns title, location, department, employment type, remote flag, salary, apply URL and dates. Built-in keyword, location, department and remote filters. HTTP-first, no auth, no anti-bot.

Pricing

from $0.40 / 1,000 jobs

Rating

0.0

(0)

Developer

Ihor Bielievskiy

Ihor Bielievskiy

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

1

Monthly active users

3 days ago

Last modified

Share

Pull live job openings from any company that hires on Greenhouse, Lever, or Ashby. Give it a company slug, paste a careers-board URL, or let it auto-detect the platform for you. Every posting comes back as one clean, normalized row no matter which ATS it came from: title, location, department, team, employment type, remote flag, salary (where the ATS exposes it), the listing and apply URLs, created/updated dates, and the full description in both plain text and HTML. Export as JSON, CSV, or Excel.

It calls each ATS's own public job-board API directly instead of driving a headless browser, so it's fast, needs no login, and doesn't trip anti-bot. Mix as many boards and ATS types as you want in a single run.

Three ways to point it at a board

You can put any of these in the sources array, and mix them freely:

  1. Explicit object{ "ats": "greenhouse", "company": "stripe" }
  2. Pasted board URL"https://jobs.lever.co/spotify" or "https://boards.greenhouse.io/stripe" (the ATS and slug are read straight out of the URL)
  3. Bare company slug"ramp" (the actor probes Greenhouse, Lever, and Ashby and uses whichever one has a board)

The company slug is the identifier in the careers-page URL: boards.greenhouse.io/stripe, jobs.lever.co/spotify, jobs.ashbyhq.com/ramp.

Underlying endpoints:

  • greenhouseboards-api.greenhouse.io/v1/boards/{company}/jobs
  • leverapi.lever.co/v0/postings/{company}
  • ashbyapi.ashbyhq.com/posting-api/job-board/{company}

Filters

Narrow the run before anything is billed — filtered-out rows never cost you a thing:

  • titleKeyword — title must contain this text
  • locationKeyword — location must contain this text
  • department — department or team must contain this text
  • remoteOnly — keep only jobs detected as fully remote

Input

FieldTypeDescription
sourcesarrayBoard objects {ats, company}, board URLs, or bare slugs (any mix). Required.
titleKeywordstringKeep only jobs whose title contains this (case-insensitive).
locationKeywordstringKeep only jobs whose location contains this (case-insensitive).
departmentstringKeep only jobs whose department or team contains this (case-insensitive).
remoteOnlybooleanKeep only fully-remote jobs.
maxItemsintegerStop after this many rows across all boards (0 = no limit).
impersonatestringBrowser TLS fingerprint (chrome by default).
{
"sources": [
{ "ats": "greenhouse", "company": "stripe" },
"https://jobs.lever.co/spotify",
"ramp"
],
"titleKeyword": "engineer",
"remoteOnly": true,
"maxItems": 500
}

Output fields

One row per posting. A check means the field is populated when that ATS provides it; otherwise it's null.

FieldTypeGreenhouseLeverAshby
source_atsstring
companystring
job_idstring
global_idstring {ats}:{company}:{job_id}
titlestring
locationstring
departmentstring
teamstring
employment_typestring
remotebooleaninferred
remote_typeremote/hybrid/onsiteinferred
salarystringwhen setwhen set
urlstring (listing)
apply_urlstring
created_atISO 8601
updated_atISO 8601when set
posted_atISO 8601
scraped_atISO 8601
descriptionplain text
description_htmlHTML

global_id is stable across runs, so you can diff datasets or join against your own systems. Greenhouse's board API has no employment-type, team, or salary, no explicit remote flag, and no separate apply endpoint — remote/remote_type there are inferred from the location and title text (treat them as best-effort for that source), and apply_url is null since the listing url is the only link Greenhouse exposes.

Example output

{
"source_ats": "lever",
"company": "spotify",
"job_id": "88499546-e9f7-4403-87a5-240050bd7c5b",
"global_id": "lever:spotify:88499546-e9f7-4403-87a5-240050bd7c5b",
"title": "Accounts Payable Analyst",
"location": "New York, NY",
"department": "Finance",
"team": "Accounting",
"employment_type": "Permanent",
"remote": false,
"remote_type": "hybrid",
"salary": null,
"url": "https://jobs.lever.co/spotify/88499546-e9f7-4403-87a5-240050bd7c5b",
"apply_url": "https://jobs.lever.co/spotify/88499546-e9f7-4403-87a5-240050bd7c5b/apply",
"created_at": "2026-05-11T11:20:11.285000+00:00",
"updated_at": null,
"posted_at": "2026-05-11T11:20:11.285000+00:00",
"scraped_at": "2026-06-24T09:15:02.110000+00:00",
"description": "Spotify is looking for an Accounts Payable Analyst ..."
}

Why this one

  • One shape for every ATS. Greenhouse, Lever, and Ashby each return a different JSON structure; this maps all of them to the same fields, so you can dump multiple companies into one dataset and not care where each row came from.
  • Paste a URL or just a name. No need to know which ATS a company uses — paste the careers link or the bare slug and it figures the rest out.
  • Nothing fails silently. A wrong slug, a failed request, or an API that changes shape gives you a typed error row (fetch_failed, parse_failed, invalid_source, invalid_input) instead of a quietly empty run. One bad board never aborts the rest, but if every source fails the run is marked failed (not a green empty dataset), and a rate-limit/anti-bot block (HTTP 403/429/5xx) is reported as a block rather than a false "no board found".
  • You're billed per valid posting delivered, so error rows, duplicates, and rows you filter out don't cost you anything.
  • Duplicates are removed within a run, per ATS, by job id.

Notes

Only public, unauthenticated job-board APIs are used — the same data these companies publish on their own careers pages. Follow each provider's Terms and the laws that apply to you, and use the data responsibly.

Who built this

I build scrapers for my own projects and publish the ones that turn out genuinely useful. This is one of them. If you need a custom scraper, a data pipeline, or a change to this actor, I'm available for freelance work.

GitHub: github.com/bujhmml · Site: bujhmml.fun