# Greenhouse Jobs Scraper (`worthwhile_quinsy/greenhouse-jobs-scraper`) Actor

Scrape Greenhouse job boards: every open job from any company's Greenhouse careers page, or search 17,000+ jobs. Filter by role, country, remote.

- **URL**: https://apify.com/worthwhile\_quinsy/greenhouse-jobs-scraper.md
- **Developed by:** [Eki Soka](https://apify.com/worthwhile_quinsy) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 job rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Greenhouse Jobs Scraper: all open jobs from Greenhouse job boards

Get **every open job from any company's Greenhouse careers page**, or search **17,000+ Greenhouse jobs** already collected in our daily database. One clean row per job with title, company, location, countries, remote flag, department, seniority,
tech stack, salary (when published), dates and the apply link.

No browser, no proxies, no login: the Actor reads Greenhouse's public job board feed, the same data a candidate sees on the
careers page, so runs take seconds and do not break when the page design changes.

### What you can do with it

- Scrape all jobs from a Greenhouse job board: paste `https://job-boards.greenhouse.io/<company>` or just the company slug
- Monitor Greenhouse careers pages of target companies and get only new jobs every day
- Search Greenhouse jobs across every company we track by job title, country, remote and salary
- Build a job board, newsletter or Slack alert from Greenhouse companies
- Export Greenhouse job postings to CSV, Excel, JSON, Google Sheets or your database
- Feed Greenhouse jobs to an AI agent through Apify's MCP server

### Input

- **Greenhouse job board URLs or company slugs** (`boardUrls`): `boards.greenhouse.io/<company>`, `job-boards.greenhouse.io/<company>` or the embed link `boards.greenhouse.io/embed/job_board?for=<company>`. Leave empty to search all Greenhouse boards we track.
- **Job title keywords**, **exclude keywords**, **locations**, **countries**, **remote only**, **departments**,
  **seniority**, **technologies**, **posted within / new within (days)**, **only jobs with salary**,
  **include description**, **include duplicate postings** and **max results**.

Example: all open engineering jobs at two Greenhouse companies

```json
{ "boardUrls": ["https://job-boards.greenhouse.io/<company>", "another-company"], "keywords": ["engineer"] }
```

Example: remote Greenhouse jobs posted in the last 7 days that publish a salary

```json
{ "remoteOnly": true, "postedWithinDays": 7, "salaryOnly": true, "maxResults": 200 }
```

### Output

One row per job:

```json
{
  "title": "Senior Backend Engineer",
  "company": "Acme",
  "ats": "greenhouse",
  "location": "Remote (US)",
  "countries": ["US"],
  "is_remote": true,
  "department": "Engineering",
  "seniority": "senior",
  "technologies": ["Python", "PostgreSQL", "AWS"],
  "salary_min": 170000,
  "salary_max": 210000,
  "salary_currency": "USD",
  "salary_period": "year",
  "salary_type": "base",
  "visa_sponsorship": null,
  "published_at": "2026-10-01T09:00:00+00:00",
  "first_seen": "2026-10-01",
  "url": "https://boards.greenhouse.io/<company>/..."
}
```

Greenhouse gives the department, office locations, the first-published date and, for many US companies, a pay range in the job text that the Actor turns into salary fields; the Actor normalises all of it into the same schema it uses for Greenhouse, Lever, Ashby, Workable,
Recruitee, SmartRecruiters, BambooHR and Personio, so you can mix sources without rewriting your code.

### Pricing

Pay per result: **$0.002 per job**, less with an Apify subscription (Bronze $0.0018, Silver $0.0015, Gold $0.0012). Fetching a Greenhouse board that is not yet in
our database costs **$0.01 per board**; after that it is tracked daily for everyone. There is no fixed fee and no
subscription; set **Max results** or a maximum cost per run to cap spend.

### FAQ

**Do I need a Greenhouse account or API key?** No. Only public job board data is used.

**How fresh is the data?** Boards in the database are refreshed every morning. Boards you pass in `boardUrls` that
are not in the database yet are fetched live during your run.

**Can I get only new jobs?** Yes: schedule the Actor daily with `newWithinDays: 1`.

**Where does the salary come from?** From the structured pay fields when Greenhouse provides them, otherwise from the pay
range written in the full job text (for example "Salary: $150,000 - $190,000 per year"). `salary_type` says whether
the range is the base salary (`base`) or on-target earnings including commission (`ote`), so sales roles do not
inflate your benchmarks. Jobs without a published range have empty salary fields.

**Does it say whether a job sponsors visas?** `visa_sponsorship` is `true` when the posting says it sponsors visas,
`false` when it says it does not, and empty when the posting does not mention it.

**How is it different from other Greenhouse scrapers?** Besides scraping the boards you give it, it can search every Greenhouse
company we track at once, it can return only jobs first seen since yesterday, and every row uses the same schema as our other
job board Actors, so one pipeline handles all of them.

**Why can I get fewer rows than the careers page shows?** Large employers often post the same role several times
(same title and location). You get one row per company + title + location, and `similar_postings` says how many
identical postings it stands for. Turn on **Include duplicate postings** to get every posting.

**Does it include the full job description?** Turn on **Include description** (plain text, up to ~4,000 characters).

**What if a company is not on Greenhouse?** Use [ATS Detector](https://apify.com/worthwhile_quinsy/ats-detector) to find
which job board a company uses.

### Data and use

Only public job-posting data is collected, at a low request rate. No personal data about candidates. Please respect
the terms of the sites you use the data on and applicable laws.

### What it costs

| Example | Cost |
| --- | --- |
| 50 Greenhouse jobs | about $0.10 |
| all jobs from 10 Greenhouse boards (~300 jobs) | about $0.60 |
| fetching 10 Greenhouse boards not yet in the database | about $0.10 |

You only pay for rows you get. Set **Max results** (or a maximum cost per run in Apify) to cap spend. Apify's free plan includes monthly credit, so you can try it at no cost. Apify subscribers get automatic Store discounts on some events.

### Use it from code, no-code tools or AI agents

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("worthwhile_quinsy/greenhouse-jobs-scraper").call(run_input={'boardUrls': ['https://job-boards.greenhouse.io/gitlab'], 'maxResults': 1000})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript / Node.js** (`npm install apify-client`):

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('worthwhile_quinsy/greenhouse-jobs-scraper').call({"boardUrls": ["https://job-boards.greenhouse.io/gitlab"], "maxResults": 1000});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**One HTTP call** (returns the rows directly):

```bash
curl -X POST 'https://api.apify.com/v2/acts/worthwhile_quinsy~greenhouse-jobs-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"boardUrls": ["https://job-boards.greenhouse.io/gitlab"], "maxResults": 1000}'
```

**No-code:** connect it to **Make, Zapier, n8n, Google Sheets, Slack** or a **webhook** from the Integrations tab, and run it on a **Schedule** (for example every morning).

**AI agents (MCP):** use it as a tool in Claude, ChatGPT, Cursor or any MCP client through the Apify MCP server: `https://mcp.apify.com?tools=worthwhile_quinsy/greenhouse-jobs-scraper`. Your agent can then ask for live job data in plain language. Use this tool when the user asks for job listings from Greenhouse job boards or from a specific company's Greenhouse careers page.

### More tools from the same job-data suite

All of these read the same daily database of jobs from company career pages, so results are consistent across tools.

| Actor | What it gives you |
| --- | --- |
| [Company Jobs Search + Hiring Signals](https://apify.com/worthwhile_quinsy/ats-jobs-search) | Search all jobs in the database, check your own list of companies, or get per-company hiring signals. |
| [Remote Jobs API](https://apify.com/worthwhile_quinsy/remote-jobs-api) | Only remote jobs, ready for job boards, newsletters and alert bots. |
| [Companies Hiring by Tech Stack](https://apify.com/worthwhile_quinsy/companies-hiring-by-tech-stack) | B2B buying signals: which companies are hiring for the tools you sell into. |
| [Tech Salary Data API](https://apify.com/worthwhile_quinsy/tech-salary-data-api) | Salary benchmarks (median, P25, P75) from fresh job postings with published pay. |
| [Company Hiring Trends](https://apify.com/worthwhile_quinsy/company-hiring-trends) | Which companies are ramping up hiring, and which are slowing down. |
| [ATS Detector](https://apify.com/worthwhile_quinsy/ats-detector) | Which applicant tracking system (Greenhouse, Lever, Ashby...) a company uses, plus its career page. |
| [Lever Jobs Scraper](https://apify.com/worthwhile_quinsy/lever-jobs-scraper) | All open jobs from any Lever job board, or search every Lever board we track. |
| [Ashby Jobs Scraper](https://apify.com/worthwhile_quinsy/ashby-jobs-scraper) | All open jobs from any Ashby job board, or search every Ashby board we track. |

### Questions and feedback

Found a bug, need another filter, field or ATS? Open an **Issue** on this Actor's page; issues are answered quickly. If it saved you time, a short **review** helps other people find it.

# Actor input Schema

## `boardUrls` (type: `array`):

Get all open jobs from these Greenhouse boards, e.g. https://job-boards.greenhouse.io/<company> or just the company slug. Boards already in our database are instant; others are fetched live (billed per board) and added to the daily database. Leave empty to search every Greenhouse board we track. Max 100 per run.

## `keywords` (type: `array`):

Match any of these in the job title (case-insensitive), e.g. 'data engineer', 'account executive'. Empty = all jobs.

## `excludeKeywords` (type: `array`):

Drop jobs whose title contains any of these, e.g. 'intern', 'senior'.

## `locations` (type: `array`):

Keep jobs whose location contains any of these, e.g. 'London', 'Germany', 'Singapore', 'Remote'.

## `countries` (type: `array`):

Country names or 2-letter codes, e.g. 'Germany', 'US', 'Singapore'. Derived from the posting's location.

## `remoteOnly` (type: `boolean`):

Only jobs marked or described as remote.

## `departments` (type: `array`):

Keep jobs whose department or team contains any of these, e.g. 'Engineering', 'Sales'.

## `seniority` (type: `array`):

Heuristic level from the job title.

## `technologies` (type: `array`):

Keep jobs that mention any of these tools in the title or description, e.g. 'Snowflake', 'Kubernetes', 'Salesforce'.

## `companies` (type: `array`):

Limit to Greenhouse companies in our database whose name or board slug contains any of these words.

## `postedWithinDays` (type: `integer`):

Only jobs published in the last N days.

## `newWithinDays` (type: `integer`):

Only jobs that appeared in the database in the last N days (for daily alerts use 1).

## `salaryOnly` (type: `boolean`):

Jobs mode: only postings that publish a salary range.

## `includeDescription` (type: `boolean`):

Jobs mode: add the plain-text job description (up to ~4,000 characters) to each row.

## `includeDuplicates` (type: `boolean`):

Large employers often post the same role several times (same title and location). By default you get one row per company + title + location, with similar\_postings telling how many identical postings it stands for. Turn this on to get every posting.

## `searchInDescription` (type: `boolean`):

Match keywords in the job description too (e.g. a tool name like 'Snowflake').

## `maxResults` (type: `integer`):

Maximum number of jobs to return (you pay per job). 1,000 covers every open job of almost any company board.

## Actor input object example

```json
{
  "boardUrls": [
    "https://job-boards.greenhouse.io/gitlab"
  ],
  "remoteOnly": false,
  "salaryOnly": false,
  "includeDescription": false,
  "includeDuplicates": false,
  "searchInDescription": false,
  "maxResults": 1000
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "boardUrls": [
        "https://job-boards.greenhouse.io/gitlab"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("worthwhile_quinsy/greenhouse-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "boardUrls": ["https://job-boards.greenhouse.io/gitlab"] }

# Run the Actor and wait for it to finish
run = client.actor("worthwhile_quinsy/greenhouse-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "boardUrls": [
    "https://job-boards.greenhouse.io/gitlab"
  ]
}' |
apify call worthwhile_quinsy/greenhouse-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,worthwhile_quinsy/greenhouse-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/j8n03gIrVVdlaIcG7/builds/NIzElrcamFUkZS37b/openapi.json
