# Greenhouse Jobs Scraper — Search All Boards, No Token Needed (`charliemorrisondev/greenhouse-jobs-scraper`) Actor

Search open jobs across a built-in index of public Greenhouse boards. No login, no anti-bot, no board token needed. Normalized JSON: title, location, remote, department, url, posted date.

- **URL**: https://apify.com/charliemorrisondev/greenhouse-jobs-scraper.md
- **Developed by:** [Petro Pankov](https://apify.com/charliemorrisondev) (community)
- **Categories:** Jobs, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 jobs

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Greenhouse Jobs Scraper — search every indexed board at once

Scrape open jobs from Greenhouse career boards through Greenhouse's **own public board API**.
No login, no cookies, no browser, no anti-bot workarounds.

**What makes this one different:** every other Greenhouse scraper asks you to already know the
company's board token. This one ships a **built-in, validated index of public Greenhouse boards** —
currently **140 companies with 17,000+ open roles** — so you can leave the input empty and search
across all of them by keyword, location, department or remote flag in a single run.

Need one specific company instead? Pass its board token (or just paste the board URL) and the index
is ignored.

### Use cases

- **Job aggregators / job boards** — pull thousands of fresh, structured roles daily without
  maintaining a company list.
- **Recruiting & sourcing** — see who is hiring for a given title across hundreds of employers.
- **Sales & GTM signals** — hiring is a buying signal; watch departments ramp up in real time.
- **Market research** — track demand for a skill, a location or a seniority band over time.
- **Personal job search** — one query across every indexed company, filtered to remote.

### Input

Everything is optional. An empty input searches the built-in index (capped at 1000 jobs by default).

| Field | Type | What it does |
|---|---|---|
| `companies` | array | Board tokens (`stripe`), shorthand (`greenhouse:stripe`) or full board URLs. **Empty = search the built-in index.** |
| `keywords` | array | Keep jobs whose title or department contains any of these. |
| `locations` | array | Keep jobs whose location or office contains any of these. |
| `departments` | array | Keep jobs in a matching department. |
| `remoteOnly` | boolean | Remote roles only. |
| `postedWithinDays` | integer | Only roles first published in the last N days. |
| `includeDescription` | boolean | Include the full plain-text job description. |
| `maxItems` | integer | **Spend cap** — you are billed per job returned. Default 1000. |
| `maxJobsPerBoard` | integer | Stop one huge employer from eating the whole run. |
| `maxBoards` | integer | Scan only the first N companies (index is sorted by open-role count). |

#### Example — every remote engineering job across all indexed companies

```json
{
  "keywords": ["engineer"],
  "remoteOnly": true,
  "postedWithinDays": 14,
  "maxItems": 500
}
````

#### Example — two specific companies, full descriptions

```json
{
  "companies": ["stripe", "https://job-boards.greenhouse.io/figma"],
  "includeDescription": true
}
```

### Output

One row per job:

```json
{
  "company": "Stripe",
  "boardSlug": "stripe",
  "jobId": "7954688",
  "title": "Account Executive, AI Sales",
  "location": "San Francisco, CA",
  "offices": ["San Francisco"],
  "remote": false,
  "department": "Sales",
  "departments": ["Sales", "Account Executive"],
  "url": "https://job-boards.greenhouse.io/stripe/jobs/7954688",
  "postedAt": "2026-07-14T00:00:00-04:00",
  "updatedAt": "2026-07-21T11:02:19-04:00",
  "requisitionId": "1234",
  "description": ""
}
```

### Cost

Pay per result: you are charged for each job row returned, plus a fraction of a cent per run start.
Filters are applied **before** anything is pushed to the dataset, so a narrow query costs less —
and `maxItems` is a hard ceiling you set yourself.

### Reliability

Greenhouse publishes its board data as structured JSON at
`boards-api.greenhouse.io/v1/boards/<slug>/jobs`. There is no rendering, no rate-limit dance and no
markup to break, which is why this actor does not suffer the breakage that scrapers of
Indeed/Glassdoor-style sites do. The actor identifies itself honestly by User-Agent and only reads
boards companies publish for the public.

### About the built-in index

The index is assembled from company names published in public job feeds, then **validated**: a board
only enters it after the public API answers with at least one open role. It is re-validated when
rebuilt, so boards that go dark drop out. If a company you need is missing, just pass its token in
`companies` — nothing is restricted to the index.

### FAQ

**Do I need a Greenhouse account or API key?** No. The board endpoint is public.

**Where do I find a board token?** It is the path segment in the board URL —
`job-boards.greenhouse.io/**stripe**`. You can also paste the whole URL.

**Can I get salary data?** Only when the company publishes it in the job description; Greenhouse
does not expose a structured salary field on the board API. Set `includeDescription: true` and parse.

**How fresh is the data?** It is read live from the board on every run — there is no cached copy.

**Why did a company return 0 jobs?** Either the board has no open roles right now, or the token is
wrong. Unreachable boards are logged as warnings and the run continues.

# Actor input Schema

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

Company board tokens to scrape, e.g. "stripe". A full board URL (https://job-boards.greenhouse.io/stripe) or the "greenhouse:stripe" shorthand also works. LEAVE THIS EMPTY to search every company in the actor's built-in index of public Greenhouse boards — that is the point of this actor: you do not need to know the board tokens up front.

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

Keep only jobs whose title or department contains at least one of these (case-insensitive). Empty = keep all.

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

Keep only jobs whose location or office contains at least one of these (case-insensitive), e.g. 'London', 'New York', 'Germany'. Empty = keep all.

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

Keep only jobs in a department matching one of these (case-insensitive), e.g. 'Engineering', 'Sales'. Empty = keep all.

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

Keep only roles flagged remote (detected from the location text and the board's own workplace fields).

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

Keep only jobs first published within the last N days. 0 = no date filter.

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

Fetch and include the plain-text job description. Slower — the board API returns the full HTML content for every role.

## `maxItems` (type: `integer`):

Hard cap on dataset items. This is your spend cap: you are billed per job returned, so the run stops as soon as it is reached. 0 = unlimited (only do this with a filter set).

## `maxJobsPerBoard` (type: `integer`):

Cap roles taken from any single company, so one huge board cannot eat the whole run. 0 = no per-company cap.

## `maxBoards` (type: `integer`):

When searching the built-in index, stop after this many company boards. The index is ordered by number of open roles, so a capped run covers the largest employers first. 0 = scan every indexed board.

## Actor input object example

```json
{
  "companies": [
    "stripe",
    "figma",
    "gitlab"
  ],
  "keywords": [
    "engineer",
    "data"
  ],
  "locations": [
    "london",
    "new york"
  ],
  "departments": [
    "engineering"
  ],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "includeDescription": false,
  "maxItems": 1000,
  "maxJobsPerBoard": 0,
  "maxBoards": 0
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("charliemorrisondev/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 = {}

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

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

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

```

## CLI example

```bash
echo '{}' |
apify call charliemorrisondev/greenhouse-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=charliemorrisondev/greenhouse-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Greenhouse Jobs Scraper — Search All Boards, No Token Needed",
        "description": "Search open jobs across a built-in index of public Greenhouse boards. No login, no anti-bot, no board token needed. Normalized JSON: title, location, remote, department, url, posted date.",
        "version": "0.0",
        "x-build-id": "sld6cqdt1lXJBW2vt"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/charliemorrisondev~greenhouse-jobs-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-charliemorrisondev-greenhouse-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/charliemorrisondev~greenhouse-jobs-scraper/runs": {
            "post": {
                "operationId": "runs-sync-charliemorrisondev-greenhouse-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/charliemorrisondev~greenhouse-jobs-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-charliemorrisondev-greenhouse-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "companies": {
                        "title": "Greenhouse boards (leave empty to search the built-in index)",
                        "type": "array",
                        "description": "Company board tokens to scrape, e.g. \"stripe\". A full board URL (https://job-boards.greenhouse.io/stripe) or the \"greenhouse:stripe\" shorthand also works. LEAVE THIS EMPTY to search every company in the actor's built-in index of public Greenhouse boards — that is the point of this actor: you do not need to know the board tokens up front.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Title keywords (any-match)",
                        "type": "array",
                        "description": "Keep only jobs whose title or department contains at least one of these (case-insensitive). Empty = keep all.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "locations": {
                        "title": "Location contains (any-match)",
                        "type": "array",
                        "description": "Keep only jobs whose location or office contains at least one of these (case-insensitive), e.g. 'London', 'New York', 'Germany'. Empty = keep all.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "departments": {
                        "title": "Department contains (any-match)",
                        "type": "array",
                        "description": "Keep only jobs in a department matching one of these (case-insensitive), e.g. 'Engineering', 'Sales'. Empty = keep all.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "remoteOnly": {
                        "title": "Remote roles only",
                        "type": "boolean",
                        "description": "Keep only roles flagged remote (detected from the location text and the board's own workplace fields).",
                        "default": false
                    },
                    "postedWithinDays": {
                        "title": "Posted within N days",
                        "minimum": 0,
                        "maximum": 365,
                        "type": "integer",
                        "description": "Keep only jobs first published within the last N days. 0 = no date filter.",
                        "default": 0
                    },
                    "includeDescription": {
                        "title": "Include full job description",
                        "type": "boolean",
                        "description": "Fetch and include the plain-text job description. Slower — the board API returns the full HTML content for every role.",
                        "default": false
                    },
                    "maxItems": {
                        "title": "Max jobs to return (cost cap)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Hard cap on dataset items. This is your spend cap: you are billed per job returned, so the run stops as soon as it is reached. 0 = unlimited (only do this with a filter set).",
                        "default": 1000
                    },
                    "maxJobsPerBoard": {
                        "title": "Max jobs per company",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap roles taken from any single company, so one huge board cannot eat the whole run. 0 = no per-company cap.",
                        "default": 0
                    },
                    "maxBoards": {
                        "title": "Max companies to scan",
                        "minimum": 0,
                        "type": "integer",
                        "description": "When searching the built-in index, stop after this many company boards. The index is ordered by number of open roles, so a capped run covers the largest employers first. 0 = scan every indexed board.",
                        "default": 0
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
