Greenhouse Jobs Scraper: Any Company's Board, with Pay Ranges
Pricing
from $1.20 / 1,000 jobs
Greenhouse Jobs Scraper: Any Company's Board, with Pay Ranges
Scrape open jobs from any company's Greenhouse job board: title, department, offices, locations, remote flag, posted and updated dates, pay range, apply link and description. Paste board links, tokens or company names, many at once. Filter by keyword, location, department or date. No login.
Pricing
from $1.20 / 1,000 jobs
Rating
0.0
(0)
Developer
The Mine Works
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
15 days ago
Last modified
Categories
Share
From The Mine Works, makers of Threads Scraper and B2B Leads Finder, with over 140,000 runs across 170+ public actors.
Why choose this actor?
- Pay ranges as numbers, not just text. Greenhouse lets employers attach pay ranges to a job, and this actor asks for them in the same request as the jobs. Where an employer only writes the range into the job description, as many US employers do, the actor reads it from there. In our proof run, 442 of 820 jobs (54%) came back with a minimum, maximum, currency and period: 350 from Greenhouse's own pay data, 92 from the description. No extra request, no add-on.
- Many companies in one run, pasted any way you have them. Our proof run read 6 boards and returned 820 jobs in 10.5 seconds, one request per board. Paste board links (including the EU host), embed links, single job links, board tokens, plain company names, or your company's own careers page. A company that is not found is reported and never charged.
- Only new jobs on a schedule. Switch on "Only jobs not delivered before" and each run returns, and charges, only jobs no earlier run in your account delivered. In our test the second run skipped the 120 jobs the first had delivered, and once caught up a repeat run returned 0 jobs and charged nothing but the start fee. Jobs removed by your filters are never charged either.
Part of The Mine Works Jobs and hiring family: Foundit Monster India Jobs, Hirist Jobs Scraper, India Jobs MCP, Naukri Jobs Scraper, Shine.com Jobs Scraper, Internshala Scraper.
Try it in one minute
Paste this input and press Start. It returns the 20 newest open jobs at Figma in a few seconds:
{"companies": ["figma"],"maxJobsPerCompany": 20}
You can name a company in five ways, and mix them in one list:
- Board link:
https://job-boards.greenhouse.io/figma,https://boards.greenhouse.io/discord, or the EU hosthttps://job-boards.eu.greenhouse.io/proton. A single job link such ashttps://job-boards.greenhouse.io/figma/jobs/6207801004reads that company's whole board. - Embed link:
https://boards.greenhouse.io/embed/job_board?for=airbnb, as found in a careers page's source. - Board token:
figma,stripe,airbnb. It is the word after the domain in the board link. - Company name:
Scale AIis tried asscaleaiand thenscale-ai. Use a link when the token is something else. - Your company's careers page:
https://www.figma.com/careers/. The page is read once and searched for its Greenhouse board link. This works when the page's HTML links to or embeds the board; a page that loads its jobs later with JavaScript is reported as "no board on page" and never charged.
On Apify's free plan every run returns the first 10 results as a preview, so you can check the data and the fields before you pay. A paid Apify plan returns every result: https://apify.com/pricing?fpr=ymnoit
Copy to your AI assistant
themineworks/greenhouse-jobs-scraper on Apify. Returns open jobs from companies' Greenhouse job boards, one row per job with company, title, department, locations, remote flag, employment type when published, first published and updated dates, pay range (min, max, currency, period), job and apply links, and a 500 character description (full text on request). Call ApifyClient("TOKEN").actor("themineworks/greenhouse-jobs-scraper").call(run_input={"companies": ["figma", "https://boards.greenhouse.io/airbnb"], "keywords": ["engineer"], "maxJobsPerCompany": 100}), then client.dataset(run["defaultDatasetId"]).list_items().items. Required: companies (Greenhouse board links, board tokens, company names or careers page links). Optional: keywords (title words), excludeKeywords, locations, departments, remoteOnly (default false), postedWithinDays, maxJobsPerCompany (default 500, 20 to 5,000), includeDescription (default false), onlyNewJobs (default false). Skip rows that have "_type": "info". Full spec: GET https://api.apify.com/v2/acts/themineworks~greenhouse-jobs-scraper/builds/default (Bearer TOKEN), which returns inputSchema and readme. Token: https://console.apify.com/account/integrations?fpr=ymnoit&utm_source=apify-readme&utm_medium=referral
Key features
- 32 fields per job: company, board token, job id, requisition id, title, every department, every location and office, remote flag, employment type, first published and last updated dates, pay range with its source, every pay range the employer entered, job and apply links, language, application deadline, a short description and, on request, the whole description as plain text.
- One request per board, whatever its size. Greenhouse's public board API returns a whole board with descriptions in one answer: Stripe's 718 open jobs arrive as one 5.5 MB response. Three boards are read at a time.
- Filters that run before you pay: title keywords and exclusions, locations (every location of a job is checked, and United States matches "San Francisco, CA" and "Remote, USA"), departments, remote only, and posted within N days. Filtered jobs are never charged.
- Newest first, with a cap per company. Jobs are sorted by first published date before the cap is applied, so a cap of 50 gives each company's 50 newest matching jobs. The cap runs from 20 to 5,000.
- Only new jobs on repeat runs, kept in a named key value store in your account, so a daily schedule returns only what was posted since.
- Plain HTTP, no browser, no login. 512 MB of memory. A run report (status per company, jobs on the board, matches, filtered counts, requests, charges) is saved as the
OUTPUTrecord.
How to use it
Basic: every open job at one company
{"companies": ["https://boards.greenhouse.io/airbnb"],"maxJobsPerCompany": 500}
Airbnb had 150 open jobs on 5 Oct 2026, so this returns all of them, newest first. Raise maxJobsPerCompany (up to 5,000) for very large boards.
Several companies at once
{"companies": ["https://job-boards.greenhouse.io/figma","discord","https://boards.greenhouse.io/airbnb","stripe","https://job-boards.eu.greenhouse.io/proton","Scale AI"],"maxJobsPerCompany": 200,"includeDescription": true}
This is the input of our proof run: 820 jobs in 10.5 seconds, with the whole description of every job. Up to 1,000 companies per run; a board given twice (for example as stripe and as its link) is read once.
Job: daily alert on new jobs at a watchlist of companies
{"companies": ["stripe", "figma", "airbnb", "discord"],"keywords": ["engineer", "data"],"onlyNewJobs": true,"maxJobsPerCompany": 500}
Schedule it daily (Console, Schedules, Add schedule). The first run delivers every matching open job; each later run delivers only jobs no earlier run delivered, so the dataset of each run is the list of new postings. Send it to Slack or email with a webhook, Make or Zapier.
Job: salary benchmarking for one role across companies
{"companies": ["figma", "airbnb", "discord", "scaleai", "stripe"],"keywords": ["product designer", "designer"],"locations": ["United States"],"maxJobsPerCompany": 100}
Every row with a published range has salary_min, salary_max, salary_currency and salary_period, so a spreadsheet can compare them directly. salary_source tells you whether the range came from Greenhouse's pay data (posting) or was read from the description (description), and pay_ranges keeps every range the employer entered, for example one per location tier.
Job: remote engineering roles posted this week
{"companies": ["airbnb", "stripe", "figma", "discord", "scaleai"],"keywords": ["engineer"],"excludeKeywords": ["intern", "manager"],"remoteOnly": true,"postedWithinDays": 7}
Remote means the location, an office, or the title says remote, as in "Remote, USA" or "San Francisco Bay Area or Remote (U.S.)". Greenhouse has no separate remote field, so jobs that are remote only in their description are not marked.
Job: hiring signals for sales prospecting
{"companies": ["stripe", "airbnb", "figma"],"departments": ["sales", "marketing"],"postedWithinDays": 30,"maxJobsPerCompany": 200}
A company opening several sales or marketing roles this month is a warm account. Count rows per company and department; posted_at gives the date each role first went live.
Input parameters
| Parameter | Type | Default | What it does |
|---|---|---|---|
companies | array of strings | ["https://job-boards.greenhouse.io/figma", "discord", "https://boards.greenhouse.io/airbnb"] | Required. Greenhouse board links, embed or single job links, board tokens, company names, or careers page links, one per line. Up to 1,000 per run; repeats are read once. |
keywords | array of strings | none | Keep jobs whose title has a word starting with one of these (engineer also matches Engineering Manager). Not case sensitive. |
excludeKeywords | array of strings | none | Drop jobs whose title has a word starting with one of these, for example senior, intern. |
locations | array of strings | none | Keep jobs with a location containing one of these, for example London, Germany, Remote. United States, USA and US match each other and US state codes ("Austin, TX"); United Kingdom and UK match each other. |
departments | array of strings | none | Keep jobs whose department contains one of these, for example Engineering, Sales. |
remoteOnly | boolean | false | Keep only jobs that are remote or offer a remote location. |
postedWithinDays | integer | none | Keep only jobs first published in the last N days, 1 to 365. |
maxJobsPerCompany | integer | 500 (the form starts at 20) | Most jobs delivered per company after the filters, newest first, 20 to 5,000. Also the most you pay for per company. |
includeDescription | boolean | false | Add the whole description as plain text in description. Costs nothing extra: Greenhouse sends it with the board. |
onlyNewJobs | boolean | false | Skip, and never charge, jobs an earlier run of this actor in your account already delivered. |
What data do you get?
One row per open job. A field with no value (for example no pay range published) is left out of the row rather than filled with an empty value.
The company: company (the name Greenhouse publishes, such as "Scale AI"), company_slug (the board token), platform (always greenhouse).
The job: job_id (Greenhouse's job id, stable across runs), requisition_id (the employer's own requisition number, when published), internal_job_id (one job can have several postings), title, department and departments (every department it is listed under), employment_type (full-time, part-time, contract, intern or temporary, when the board publishes it or the title says intern, contract, part time or temporary), language, application_deadline (when the employer set one).
Where: location (as the board shows it), locations (split into a list when the board lists several, such as "San Francisco, CA" and "New York, NY"), offices (the Greenhouse offices the job is attached to), is_remote, workplace_type (remote or hybrid when the location or title says so).
When: posted_at (first published, ISO 8601 UTC) and updated_at (last change).
Pay: salary_min, salary_max, salary_currency (USD, EUR, GBP and others as published), salary_period (year, month, week, day or hour), salary_text (one readable line, for example "USD 196,000 to 227,000 per year"), salary_source (posting for Greenhouse's pay data, description when read from the description), pay_ranges (every range the employer entered, with its title, for example one per location tier). Several ranges are widened to one lowest minimum and highest maximum in the main fields.
Links and text: job_url (the posting, on Greenhouse or on the company's own careers site when the employer set one), apply_url, description_short (the start of the description, one line, at most 500 characters), description (the whole description as plain text, only with includeDescription on).
How it was read: input (the company entry as you typed it), scraped_at.
At the end of a run with results, one extra row with "_type": "info" carries scheduling tips. It is never charged; filter it out with _type. A full run report (status per company, jobs on the board, matches, filtered counts, requests, charges) is saved as the OUTPUT record of the run's key value store.
Stable fields for automations
These fields were present in every one of the 820 rows of our proof run:
| Field | Meaning |
|---|---|
company | Company name as Greenhouse publishes it |
company_slug | Greenhouse board token |
platform | Always greenhouse |
job_id | Greenhouse job id; use it to deduplicate |
title | Job title |
location | Location as the board shows it |
locations | Every location, as a list |
is_remote | True when the job is remote or offers a remote location |
posted_at | First published, ISO 8601 UTC |
updated_at | Last updated, ISO 8601 UTC |
job_url | Link to the posting |
apply_url | Link to apply |
description_short | Start of the description, at most 500 characters |
input | The company entry as you gave it |
scraped_at | When the row was collected |
These names will not change. New fields may be added, never renamed.
Output examples
A remote job with a pay range from Greenhouse's pay data (Airbnb):
{"company": "Airbnb","company_slug": "airbnb","platform": "greenhouse","job_id": "8250093","internal_job_id": "3569396","title": "Senior Software Engineer, Native Mobile","department": "Software Engineering","departments": ["Software Engineering"],"location": "Remote, USA","locations": ["Remote, USA"],"offices": ["United States"],"workplace_type": "remote","is_remote": true,"posted_at": "2026-10-05T18:23:07.000Z","updated_at": "2026-10-05T18:23:07.000Z","salary_min": 196000,"salary_max": 227000,"salary_currency": "USD","salary_period": "year","salary_text": "USD 196,000 to 227,000 per year","salary_source": "posting","pay_ranges": [{ "title": "Pay Range", "min": 196000, "max": 227000, "currency": "USD" }],"job_url": "https://careers.airbnb.com/positions/8250093?gh_jid=8250093","apply_url": "https://careers.airbnb.com/positions/8250093?gh_jid=8250093","language": "en","description_short": "Airbnb was born in 2007 when two hosts welcomed three guests to their San Francisco home, and has since grown to over 5 million hosts who have…","input": "https://boards.greenhouse.io/airbnb","scraped_at": "2026-10-05T19:06:09.646Z"}
A job whose pay range was read from the description (Discord):
{"company": "Discord","company_slug": "discord","platform": "greenhouse","job_id": "8856467002","requisition_id": "R-107444","title": "Senior Software Engineer, Engagement","department": "Product Engineering","location": "San Francisco Bay Area","locations": ["San Francisco Bay Area"],"offices": ["San Francisco, CA"],"is_remote": false,"posted_at": "2026-10-01T18:55:39.000Z","updated_at": "2026-10-01T18:55:39.000Z","salary_min": 196000,"salary_max": 245000,"salary_currency": "USD","salary_period": "year","salary_text": "USD 196,000 to 245,000 per year","salary_source": "description","job_url": "https://job-boards.greenhouse.io/discord/jobs/8856467002","apply_url": "https://job-boards.greenhouse.io/discord/jobs/8856467002","description_short": "Discord has a highly engaged community of millions of daily active users who use the platform for many different reasons, but there’s one thing that…","input": "discord"}
An internship with hourly pay and two locations (Figma):
{"company": "Figma","company_slug": "figma","platform": "greenhouse","job_id": "6207801004","requisition_id": "2622","title": "PhD Intern, AI Applied Research (2027)","department": "Early Career","location": "San Francisco, CA • New York, NY","locations": ["San Francisco, CA", "New York, NY"],"is_remote": false,"employment_type": "intern","posted_at": "2026-10-05T17:58:07.000Z","salary_min": 74,"salary_max": 74,"salary_currency": "USD","salary_period": "hour","salary_text": "USD 74 per hour","salary_source": "posting","job_url": "https://boards.greenhouse.io/figma/jobs/6207801004?gh_jid=6207801004","input": "https://job-boards.greenhouse.io/figma"}
Pricing
Pay per event: you pay for the job rows you receive, plus a flat $0.005 per run, whatever memory you choose.
| Event | When it is charged | Free plan | Bronze (Starter) | Silver (Scale) | Gold (Business) |
|---|---|---|---|---|---|
job-scraped | Once per job row saved to your dataset | $1.20 per 1,000 | $1.20 per 1,000 | $1.20 per 1,000 | $1.20 per 1,000 |
run-start | Once per run, when it starts | $0.005 | $0.005 | $0.005 | $0.005 |
Free plan runs return up to 10 results each; paid plans have no cap.
The price per single job is the price per 1,000 divided by 1,000. 200 jobs from one company are 200 events.
Never charged:
- companies that are not found, careers pages with no board link, and boards with no open jobs;
- jobs removed by your filters (keywords, exclusions, locations, departments, remote only, posted within);
- jobs above your
maxJobsPerCompanycap; - a job already delivered in the same run;
- with
onlyNewJobson, jobs an earlier run in your account already delivered; - the full description (it comes with the board at no extra request);
- retries the actor makes on other IP addresses;
- the information row at the end of the run and the
OUTPUTrun report.
If you set a maximum charge for the run in Apify, the actor stops when it is reached and keeps everything delivered so far.
FAQ
What do I get on the free plan?
On Apify's free plan every run returns the first 10 results as a preview, so you can check the data and the fields before you pay. A paid Apify plan returns every result with no cap, at the prices in the table above.
What exactly does this actor read?
Greenhouse's public Job Board API, the same data a company's Greenhouse job board page shows to any visitor: every open job with its description, departments, offices, dates and the pay ranges the employer chose to publish. It reads it live when you run it; there is no cached index in between.
How many jobs can I get?
Every open job on a board, up to 5,000 per company per run (maxJobsPerCompany), and up to 1,000 companies per run. Most boards hold fewer than 1,000 jobs; Stripe's had 718 on 5 Oct 2026.
Where does the pay range come from, and why do some jobs have none?
First from Greenhouse's own pay data, which employers attach to a job to meet US pay transparency laws (salary_source: "posting"). When that is empty, the actor reads a range written in the description, and only when a currency, two amounts and a pay word such as salary, pay or compensation appear together (salary_source: "description"), so figures like "a $100B market" are ignored. Jobs in places without pay transparency rules often publish no range at all; those rows simply have no salary fields. In our proof run 54% of jobs had one.
How do I find a company's board token?
Open the company's job board: the token is the word after the domain, figma in https://job-boards.greenhouse.io/figma. On a company's own careers site, a job link often ends in ?gh_jid= followed by a number; pasting the careers page itself lets the actor find the board when the page links to it. You can also simply try the company name.
How fresh is the data?
As fresh as the board: every run asks Greenhouse at run time, so a job posted a minute ago is included and a job closed a minute ago is not. posted_at is when the job was first published and updated_at when it last changed.
How long does a run take?
One request per board, three boards at a time. Our six board proof run (820 jobs with full descriptions) took 10.5 seconds; the same input took 22 and 30 seconds on other runs, depending on how quickly the proxy answered. A list of 100 boards usually takes a few minutes.
What if a company is not found?
The run goes on with the others. The company gets a status in the OUTPUT record (not_found, no_board_on_page or page_unreadable) with the reason, and nothing is charged for it. If no job at all is delivered, the info row in the dataset says why.
Do I need a Greenhouse account, cookies or an API key?
No. Job boards are public, and the actor reads them without logging in. Requests go through Apify's datacenter proxy.
Can I monitor new jobs over time?
Yes. Switch on onlyNewJobs and schedule the actor. The ids of delivered jobs are kept in a named key value store in your Apify account; each run skips, and never charges, jobs a previous run delivered. The first run delivers up to maxJobsPerCompany per company, newest first; later runs deliver whatever you have not had yet, so after a catch up run each run returns only jobs posted since.
Can I get Lever, Ashby or Workday jobs too?
This actor reads Greenhouse only, so its input and output are built around Greenhouse's data. For several platforms in one run, our Career Site Jobs Scraper reads Greenhouse, Lever, Ashby and Workday together.
Why do some job links point to the company's own website?
Employers can host their Greenhouse board inside their own careers site. Greenhouse then gives that address as the job's link (for example careers.airbnb.com/positions/...?gh_jid=...), and the application form opens there. job_id is the same either way.
Which formats can I download?
JSON, CSV, Excel, XML, RSS and an HTML table, from the run's Storage tab or the dataset API. Lists such as locations and pay_ranges stay lists in JSON and are flattened in CSV and Excel.
Can I use it from Claude, ChatGPT or Cursor (MCP)?
- Connector URL: https://mcp.apify.com/?tools=themineworks/greenhouse-jobs-scraper
- Claude: Settings > Connectors > Add custom connector, paste the URL, sign in with Apify.
- ChatGPT: developer mode, add an MCP connector with the URL, sign in with Apify.
- Cursor or VS Code: add it as an HTTP MCP server with that URL.
- Claude Code:
claude mcp add -t http greenhouse-jobs-scraper "https://mcp.apify.com/?tools=themineworks/greenhouse-jobs-scraper"
Is it legal to scrape Greenhouse job boards?
The actor only reads job postings that employers publish for anyone to see, without signing in, and returns no personal contact details. You are responsible for how you use the data, for the terms of the sites involved, and for data protection law such as GDPR and CCPA. If in doubt, ask a lawyer about your use case.
Integrations
- Google Sheets: send each run's rows to a sheet with Apify's Google Sheets integration, or import the CSV link of the dataset.
- Make, Zapier and n8n: start the actor and read its dataset with the Apify apps and nodes, for example "new engineering jobs at our target accounts to Slack every morning".
- Webhooks: have Apify call your URL when a run succeeds, then fetch the dataset.
- API and SDKs: run it from Python or JavaScript with the Apify client, or with a plain HTTP call (see "Copy to your AI assistant" above).
- MCP clients: Claude, ChatGPT, Cursor and VS Code can run it as a tool through the connector URL in the FAQ.
More from The Mine Works
Jobs and hiring
- Foundit Monster India Jobs
- Hirist Jobs Scraper
- India Jobs MCP
- Naukri Jobs Scraper
- Shine.com Jobs Scraper
- Internshala Scraper
- Indeed Jobs Scraper
- Instahyre Jobs Scraper
- Apna Jobs Scraper
- CutShort Jobs Scraper
- LinkedIn Jobs Scraper
- Recruiting & Jobs MCP
Social media and video
Leads and business directories
Marketing, SEO and reviews
Real estate
Science, health and government data
Company and business data
E-commerce and marketplaces
Food and local services
Developer and AI tools
More tools
Support
Found a Greenhouse board that should work and does not? Open an issue in the Issues tab with the board link and the run ID, and we will look at it. For a new source or a field you need, email dmineworks@gmail.com.
Paste Greenhouse boards, links or company names, filter by title, place, department and date, and get every open job back as a clean row with its departments, locations, dates and pay range, newest first.

