# Greenhouse Jobs Scraper \[Only $2.5/1K💰] | 2,000+ Boards (`ahmed_jasarevic/boards-greenhouse-scraper`) Actor

Scrape job postings from 2,000+ Greenhouse-powered career boards in one run - title, company, location, department, full description & apply URL. Built for recruiters, HR-tech pipelines, job-board builders and hiring intelligence. Pay per result.

- **URL**: https://apify.com/ahmed\_jasarevic/boards-greenhouse-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.47 / 1,000 results

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?

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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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 — Bulk Job Postings from 2,000+ Career Boards

Scrape job postings across thousands of startup career boards powered by **Greenhouse** (boards.greenhouse.io) in a single run — job title, company, location, department, full description HTML, apply URL and update timestamps, all normalized into one dataset. Built for **recruiters, HR-tech aggregators, job-board builders, and salary/talent researchers**.

### Main Use Cases

- **Competitor & market hiring intelligence** — track which companies are hiring, where, and in which departments
- **Startup job aggregation** — feed thousands of Greenhouse-powered boards into your job board or ATS
- **Talent & salary research** — collect titles, locations, departments, and descriptions at scale for benchmarks
- **Recruiter lead generation** — identify growing companies and open roles across tech, fintech, and SaaS
- **HR-tech data pipelines** — structured job rows with `jobId`, `updatedAt`, `firstPublished` for dedup and change tracking
- **Hiring velocity analysis** — detect new postings and re-posts on a schedule (diff on `jobId` + `updatedAt`)

### How It Works

The actor uses Greenhouse's official public **Board JSON API** (`boards-api.greenhouse.io/v1/boards/{boardToken}/jobs?content=true`) — one unauthenticated HTTP request per board returns all its jobs inline, including full HTML descriptions. No browser, no anti-bot handling, no per-job detail calls. You provide board tokens (the slug from `boards.greenhouse.io/<token>`) or full board URLs; each board's jobs are returned with a realistic User-Agent plus `Accept: application/json`.

### Aggregate Thousands of Greenhouse Boards In One Run

Pass up to 2,000 board tokens (e.g. `stripe`, `airbnb`, `coinbase`) and collect every posting per board. Unknown or removed tokens return HTTP 404 and are skipped with a warning, so a run never fails because one company migrated off Greenhouse — companies like OpenAI are skipped automatically. Loop-safety caps (`maxBoardsPerRun`, `maxJobsPerBoard`, `maxRequestsPerCrawl`) keep runs predictable.

### Build Job Data Pipelines Without the Harvest API

Greenhouse's Job Board API is public and keyless for read access, but it is **per-company**: you must know each board token and call each board separately — there is no bulk endpoint and no enumeration. The private Harvest API requires company credentials. This actor wraps the public API into a single bulk operation across thousands of boards with one normalized output schema, scheduling, proxy rotation, and dataset export.

### Input

| Field | Type | Required | Default | Notes |
|-------|------|----------|---------|-------|
| `boardTokens` | array | no | `["stripe", "airbnb"]` | Greenhouse board slugs from `boards.greenhouse.io/<token>` |
| `boardUrls` | array | no | `[]` | Alternative: full board URLs; tokens are extracted automatically |
| `includeDescription` | boolean | no | `true` | Fetch full posting HTML per job. Off = ~5x smaller responses |
| `maxBoardsPerRun` | integer | no | `50` | Loop-safety cap on boards processed |
| `maxJobsPerBoard` | integer | no | `1000` | Cap on jobs collected per board |
| `maxRequestsPerCrawl` | integer | no | `200` | Overall request safety cap |
| `useApifyProxy` | boolean | no | `true` | Route through Apify proxy (recommended) |
| `proxyConfiguration` | object | no | `{"useApifyProxy": true}` | Advanced proxy settings |

### Output

One dataset item per job posting:

- `jobId` — Greenhouse job ID (unique per board)
- `boardToken` / `company` — board slug and company name
- `title`, `location`, `department`, `departments`, `offices`
- `descriptionHtml`, `descriptionText` — full posting body
- `applyUrl`, `jobUrl` — canonical apply and board URLs
- `updatedAt`, `firstPublished` — change-tracking timestamps
- `requisitionId`, `metadata` — optional board-specific fields

Download as JSON, CSV, Excel, or HTML, or stream via the Apify API.

### Example Input

```json
{
  "boardTokens": ["stripe", "airbnb"],
  "includeDescription": true,
  "maxBoardsPerRun": 50,
  "maxJobsPerBoard": 1000
}
```

Fast listing mode (titles/locations/dates only, ~5x smaller):

```json
{
  "boardTokens": ["stripe", "coinbase"],
  "includeDescription": false,
  "maxBoardsPerRun": 100
}
```

### Example Output

```json
{
  "jobId": 8172508,
  "boardToken": "stripe",
  "company": "Stripe",
  "title": "Abuse Investigator",
  "location": "Dublin",
  "department": "8611 Security Analytics",
  "departments": ["8611 Security Analytics"],
  "offices": ["Ireland Locations"],
  "descriptionHtml": "<h2><strong>Who we are</strong></h2> ...",
  "descriptionText": "Who we are ...",
  "applyUrl": "https://stripe.com/jobs/search?gh_jid=8172508",
  "jobUrl": "https://boards.greenhouse.io/stripe/jobs/8172508",
  "updatedAt": "2026-09-04T14:12:20-04:00",
  "firstPublished": "2026-09-03T13:32:53-04:00",
  "requisitionId": "See Opening ID",
  "metadata": null
}
```

### Integrations & Automation

- **Apify API** — call from any app, script, or AI agent
- **Apify Schedules** — run daily to detect new/updated postings (diff on `jobId` + `updatedAt`)
- **Webhooks** — push jobs to Slack, ATS, CRM, or a database in real time
- **Export** — JSON, CSV, Excel, HTML, XML

**Recommended schedule:** daily for hiring-velocity monitoring; weekly for full board aggregation snapshots.

### Related Actors

- [Greenhouse Jobs API](https://apify.com/fantastic-jobs/greenhouse-jobs-api) — the most-used Greenhouse jobs actor, with AI-enriched fields
- [Greenhouse Jobs Scraper API](https://apify.com/jobo.world/greenhouse-jobs-scraper-api) — high-volume Greenhouse aggregation with pay ranges
- [Greenhouse Jobs Scraper](https://apify.com/automation-lab/greenhouse-jobs-scraper) — Greenhouse boards for 220,000+ companies
- [Greenhouse Jobs Scraper](https://apify.com/benthepythondev/greenhouse-jobs-scraper) — popular Greenhouse board scraper

### FAQ

**Why use this actor instead of the official Greenhouse API?**
Greenhouse's Job Board API is public and free to read, but it is per-company: you must know each board token and call boards one at a time — no bulk endpoint, no directory, no enumeration. This actor turns that into one run across up to 2,000 boards with a normalized output schema, scheduling, and exports. The private Harvest API needs company credentials and is not publicly accessible.

**What are alternatives to Greenhouse for job-board aggregation?**
Other ATS hosts with public boards include Lever (jobs.lever.co), Ashby, and Workday; many also publish via job boards federation. For non-Greenhouse ATS data, Apify has dedicated scrapers for those platforms.

**Do I need an API key to scrape Greenhouse job boards?**
No — the Job Board API GET endpoints require no authentication. A key is only needed to submit applications, which this actor does not do.

**Does the Greenhouse API include salary data?**
Greenhouse's public API has no structured salary field. Pay information, when disclosed, appears only inside the description text. This actor returns raw `descriptionHtml`/`descriptionText` so you can parse compensation mentions yourself.

**How do I find a company's Greenhouse board token?**
It's the slug in `boards.greenhouse.io/<token>` (or `job-boards.greenhouse.io/<token>`), usually the company name (e.g. `stripe`, `airbnb`). If a company's careers page is embedded on their own domain, check the embed script or the network tab for a call to `boards-api.greenhouse.io`.

**Why is a board empty or missing?**
The token may be wrong, the board private/removed, or the company migrated off Greenhouse — those tokens 404 and are skipped with a warning. Check `OUTPUT-SUMMARY` in the key-value store for per-run counts.

**How much does it cost to scrape Greenhouse jobs?**
Pay-per-result at $2.50 per 1,000 jobs plus $0.0005 per run start. One HTTP request fetches a whole board, so even hundreds of boards cost little compute.

### For AI Agents & LLM Apps

**Purpose:** Given Greenhouse board tokens or board URLs, returns job postings (title, company, location, department, description, apply URL, timestamps) from Greenhouse-powered career boards.

**Minimal working input:**

```json
{ "boardTokens": ["stripe"], "maxBoardsPerRun": 1 }
```

**Variant inputs:**

- Fast listing mode: `{ "boardTokens": ["stripe", "airbnb"], "includeDescription": false }`
- URL mode: `{ "boardUrls": ["https://boards.greenhouse.io/coinbase"] }`

**Output fields:** `jobId`, `boardToken`, `company`, `title`, `location`, `department`, `departments`, `offices`, `descriptionHtml`, `descriptionText`, `applyUrl`, `jobUrl`, `updatedAt`, `firstPublished`, `requisitionId`, `metadata`.

**Behaviors an agent should know:**

- `boardTokens` and `boardUrls` both work; URLs are parsed to tokens automatically
- Unknown/removed tokens return 404 and are skipped — they never fail the run
- `includeDescription: false` returns ~5x smaller responses but drops `descriptionHtml`/`descriptionText`
- Prefer `firstPublished` over `updatedAt` for "when was this posted" (updates bump `updatedAt` on any edit)
- There is no structured salary field in Greenhouse data — compensation lives in the description text
- Set `maxBoardsPerRun` / `maxRequestsPerCrawl` to bound cost on large token lists

**Billing:** pay-per-result — $0.0025 per job pushed to the dataset, plus $0.0005 per run start.

### Legal & Compliance Disclaimer

This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Greenhouse Software or any of the employers whose boards are scraped. It accesses only the publicly available Greenhouse Board API — no authentication, no private data, no application submission. Job postings belong to their respective employers; users are responsible for complying with each employer's terms and applicable law (e.g. GDPR where EU personal data is involved) when using or redistributing scraped job data.

### SEO Keywords

greenhouse jobs scraper, scrape greenhouse jobs, greenhouse boards api, boards.greenhouse.io, greenhouse career boards data, scrape stripe jobs, airbnb job board, startup hiring data, hr tech job aggregation, job board builder data, competitor hiring intelligence, greenhouse job postings, tech jobs dataset, talent analytics, engineering jobs tracker, startup recruiting data, greenhouse ats data, scrape company job boards, apply url extraction, job posting monitoring, first published jobs, greenhouse.io careers, bulk job board scraper, job board api alternative, recruiting data pipeline

# Actor input Schema

## `boardTokens` (type: `array`):

Greenhouse board tokens to scrape (the slug in boards.greenhouse.io/<token>). Example: stripe, airbnb, robinhood.

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

Optional full board URLs — the token is extracted automatically (e.g. https://boards.greenhouse.io/stripe). Bare tokens are accepted too.

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

Fetch the full description HTML per job (uses ?content=true, larger responses). Turn off for a fast lightweight listing scrape.

## `maxBoardsPerRun` (type: `integer`):

Maximum number of career boards to scrape in one run (loop safety cap).

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

Maximum jobs stored per board (largest boards have 500-1000+ postings).

## `maxRequestsPerCrawl` (type: `integer`):

Hard cap on HTTP requests for the whole run (one request per board).

## `useApifyProxy` (type: `boolean`):

Route requests through the Apify proxy (recommended ON).

## `proxyConfiguration` (type: `object`):

Custom proxy settings (used only when Use Apify proxy is ON). Leave empty for automatic proxy.

## Actor input object example

```json
{
  "boardTokens": [
    "stripe",
    "airbnb"
  ],
  "boardUrls": [],
  "includeDescription": true,
  "maxBoardsPerRun": 50,
  "maxJobsPerBoard": 1000,
  "maxRequestsPerCrawl": 200,
  "useApifyProxy": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "boardTokens": [
        "stripe",
        "airbnb"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/boards-greenhouse-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 = { "boardTokens": [
        "stripe",
        "airbnb",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/boards-greenhouse-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 '{
  "boardTokens": [
    "stripe",
    "airbnb"
  ]
}' |
apify call ahmed_jasarevic/boards-greenhouse-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/boards-greenhouse-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/bQDMuC4XdY7Dhm2Bj/builds/Sb0zgaeV0OTgDpFVN/openapi.json
