Multi-ATS Jobs Scraper (Greenhouse, Lever, Ashby)
Scrape open jobs from Greenhouse, Lever, and Ashby boards by company. Get title, location, department, and apply link as JSON, CSV, or Excel. No key needed.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
companies,ats,company(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Inputs
| Field | What it does | Type |
|---|---|---|
companies | List of job boards to scrape, each as "ats:token". The ats is greenhouse, lever or ashby; the token is the company's board slug. Examples: "greenhouse:stripe", | array |
ats | Alternative to the list above: pick one ATS and pair it with a single Company below. Ignored when Companies is filled. | string |
company | The single company's board slug to scrape with the ATS selected above (e.g. "stripe"). Ignored when Companies is filled. | string |
maxItems | Cap the number of postings emitted per company. Leave at 0 (or empty) to return every open posting on each board. | integer |
notionConnector | Optional. Write each job as a page into your Notion when the run finishes. Authorize a Notion connector once in Settings → API & Integrations → MCP connectors, | string |
notionParentId | Optional. The Notion data source ID of the database to write into (only used if a Notion connector is set). Leave empty to create the pages privately in your wo | string |
What you get
A structured dataset — each result includes fields like:
atscompanydepartmentdescriptionemploymentTypelocationpostedAtsalarytitleurlExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
3 ready-to-run use cases
Stripe Jobs Scraper - Greenhouse Open Roles & Apply Links
Every open Stripe role from its Greenhouse board, with job title, location, department and apply link. A clean jobs feed for recruiters and sourcers.
Fintech Hiring Tracker - Plaid, Brex & Mercury Job Data
Who Plaid, Brex and Mercury are hiring right now, pulled from their ATS boards. Headcount and team growth signals for competitor and market analysts.
Startup Jobs Feed Builder - Multi-Company ATS Aggregator
Live openings from fast-growing startups merged into one structured jobs feed for a job board or newsletter. Add or drop companies as you go.
Multi-ATS Jobs Scraper (Greenhouse · Lever · Ashby)
Scrape open job listings straight from the public JSON APIs of the three most common applicant-tracking systems — Greenhouse, Lever and Ashby. No API key, no login, no anti-bot to fight. Point it at a list of company boards and get every posting back in one normalized schema.
Thousands of companies post their jobs through exactly these three boards. Instead of writing a scraper per company, give this actor a list like ["greenhouse:stripe","lever:spotify","ashby:ramp"] and it figures out the right endpoint for each and merges the results.
Input
| Field | Notes |
|---|---|
companies | Array of "ats:token" strings. ats is greenhouse, lever, or ashby; token is the company's board slug. e.g. greenhouse:stripe, lever:spotify, ashby:openai. |
ats + company | Convenience pair for a single board (e.g. ats: "greenhouse", company: "stripe"). Ignored when companies is set. |
maxItems | Max postings per company. 0 (default) = all open postings. |
proxyConfiguration | Optional, off by default. These public APIs have no anti-bot, so no proxy is needed. Only enable one if you hit IP-based rate limits across many boards. |
Where do I find the token?
It's the slug in the public careers URL:
- Greenhouse →
boards.greenhouse.io/<token>(also<token>.greenhouse.io) - Lever →
jobs.lever.co/<company> - Ashby →
jobs.ashbyhq.com/<name>
Output
One dataset row per job posting, deduped by url:
{
"ok": true,
"ats": "greenhouse",
"company": "stripe",
"title": "Account Executive, AI Sales",
"location": "San Francisco, CA",
"department": "1650 AI GTM Strategy & Solutions",
"employmentType": "FullTime",
"url": "https://stripe.com/jobs/search?gh_jid=7964697",
"postedAt": "2026-06-05T15:44:04-04:00",
"description": "Who we are… (plain text, HTML stripped)",
"salary": "$211.4K – $290.6K • Offers Equity"
}
Field availability differs by ATS, so several fields can be null even on a successful row:
| Field | Greenhouse | Lever | Ashby |
|---|---|---|---|
employmentType | null (not exposed) | ✓ (commitment) | ✓ |
salary | null (not exposed) | best-effort (often null) | ✓ (structured, may be null) |
department | ✓ | ✓ (dept / team) | ✓ (dept / team) |
location / postedAt / url | ✓ when present, else null | ✓ when present, else null | ✓ when present, else null |
title and company are always present on a success row. Every other field above is null when the board doesn't supply it — this is honest data, not a failed scrape.
Greenhouse job descriptions come HTML-entity-encoded; the actor decodes and strips them to clean plain text.
Diagnostic rows (ok:false)
When a board has no open postings, uses a wrong/retired slug, or hits a network/blocked error, the actor pushes a single ok:false diagnostic row instead of job rows, for example:
{ "ok": false, "errorCode": "NO_RESULTS", "error": "The request succeeded but returned no results for this input.", "ats": "greenhouse", "company": "acme", "note": "No open postings for greenhouse:acme." }
An ok:false row means that one board had nothing to return — not that the run failed. These rows are never charged. Filter on ok:true to get only billable job postings. Empty input produces an ok:false row with errorCode: "BAD_INPUT" instead of crashing the run.
Billing & empty boards
Billed per job posting returned (job), and only for genuine ok:true rows. A board with no open postings (or a wrong/retired slug) produces a single ok:false diagnostic row explaining why — and is not charged. Network/blocked errors and empty/invalid input likewise return a coded ok:false diagnostic row instead of failing the whole run, and are never charged.
Example
{
"companies": ["greenhouse:stripe", "greenhouse:airbnb", "lever:spotify", "ashby:ramp", "ashby:openai"],
"maxItems": 0
}