# Greenhouse Jobs Scraper & New-Job Monitor (`honestdata/greenhouse-jobs-monitor`) Actor

Public Greenhouse job boards in, jobs out. With 'only new' on, scheduled runs bill only new jobs. Posting age and a 90+ days-open flag included.

- **URL**: https://apify.com/honestdata/greenhouse-jobs-monitor.md
- **Developed by:** [Honest Data](https://apify.com/honestdata) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

### What does Greenhouse Jobs Scraper & New-Job Monitor do?

**In short:** Returns the newest open jobs (up to your cap per board) from the Greenhouse boards you name (title, location, remote, apply link, days since published, a `longOpen` flag for 90+ days, pay range quoted from the description) at $0.001 per job. "Only new" mode bills just the jobs not delivered before, and boards that fail come back as free miss rows.

Thousands of companies publish their open jobs on Greenhouse, and every board is open JSON. This actor
turns boards into clean rows: title, location, departments, dates, link, optional description text.
It is built for recruiters, job-board builders, market researchers and job seekers who check the same
companies again and again. Schedule it with **Only new since the last run** and each run returns, and
bills, only the jobs it hasn't delivered before.

It also shows what a job list can't tell you on its own: how long each job has been open, a flag for
postings open 90+ days (often evergreen or ghost postings), and any pay range the description quotes.

### What you get

Sample output (real rows from a test run, trimmed):

```json
[
  {
    "id": "stripe|8287912",
    "board": "stripe",
    "title": "Staff Software Engineer, Radar",
    "company": "Stripe",
    "location": "San Francisco, Seattle",
    "departments": ["8525 Radar - Eng"],
    "remote": false,
    "url": "https://stripe.com/jobs/search?gh_jid=8287912",
    "firstPublished": "2026-10-20T12:07:32-04:00",
    "daysSincePublished": 0,
    "longOpen": false,
    "payRangeText": null
  },
  {
    "id": "datadog|8289964",
    "board": "datadog",
    "title": "Director, Key Accounts",
    "company": "Datadog",
    "location": "San Francisco, California, USA",
    "departments": ["Enterprise Sales"],
    "remote": false,
    "url": "https://careers.datadoghq.com/detail/8289964/?gh_jid=8289964",
    "firstPublished": "2026-10-19T18:40:59-04:00",
    "daysSincePublished": 0,
    "longOpen": false,
    "payRangeText": "$158,000 — $210,000 USD"
  }
]
```

| Field | Meaning |
|---|---|
| `title`, `company`, `location`, `departments`, `offices` | As the company wrote them on its board |
| `remote` | True when "remote" appears in the title, location or office names (a text guess) |
| `url` | Link to the posting |
| `firstPublished`, `updatedAt` | Greenhouse's own dates. `updatedAt` moves on any recruiter edit, so it is not proof of a repost |
| `daysSincePublished` | Whole days since `firstPublished` |
| `longOpen` | True when open 90+ days: an evergreen or ghost-posting hint, not proof |
| `payRangeText` | First pay range the description quotes, copied as written (the unit, like "per hour", is kept when it follows the range). Null means none was recognised, not that the job has no pay |
| `descriptionText` | Plain-text description, only with **Include description** |

**Honest limits.**

- Pay is matched in the description text: ranges with $, €, £, US$ or a USD/EUR/GBP/CAD/AUD prefix, in
  formats like `$120,000 - $160,000`, `€48.000 — €56.000` or `$50 - $70 per hour`. Other currencies and
  pay shown outside the description are missed, so the counts are a floor. In our test the pattern found a
  range in 21 of 726 Stripe descriptions and 43 of 44 at Discord.
- Only companies that use Greenhouse have a board, and closed jobs disappear from it, so there are no
  "job removed" alerts. A job that was edited is not delivered again.
- Title and location filters match whole words or phrases, not parts of words: "US" matches "US" but not
  "Australia", and "intern" matches "Intern" but not "Internship" or "International", so list each variant
  you want ("intern", "internship"). Locations are the company's own text ("US", "USA" and "United States"
  all occur), so list variants.
- "Only new" remembers the newest 50,000 job ids per input. Past that, the oldest ids are forgotten and
  those jobs, if still open, are delivered and billed again; the run log and the `seenIdsForgotten` field
  of the OUTPUT record say when it happens.
- `descriptionText` is cut at 20,000 characters.

### How to use it

1. Enter company board tokens (the last part of `boards.greenhouse.io/stripe`) or full board links, one per line.
2. Optionally filter by words in the title or location, or keep only remote jobs.
3. Click **Start**. Results appear in the Overview tab; export to CSV, JSON or Excel, or use the API.
4. **For monitoring:** schedule it daily or weekly with **Only new since the last run** on and a
   **Max jobs per board** above the board's size (the default 100 is a cap, and the cap is applied before
   the "only new" check). A board with no new jobs costs nothing but the tiny start fee.

### How much does it cost?

**$0.001 per job** delivered, so **1,000 jobs cost $1**. Boards that don't exist, empty boards and
filters that match nothing are listed free with the reason, and with "only new" on, jobs you already
received on the same input are free. Changing the input (boards, filters, max jobs, description option)
starts a fresh memory, so the next run delivers and bills those jobs again. There's also a tiny start fee of $0.00005 per run. Apify's free
plan includes $5 of monthly credit.

### Input

See the **Input** tab. **Max jobs per board** keeps the newest postings first. Filters match any of the
words you list. The memory for "only new" is kept per input, so two schedules with different boards or
filters don't share state.

### Tips

- Start with one board and 20 jobs to see the fields, then add boards.
- Pair **Title must contain** with a daily schedule to get an alert feed for a role like "data engineer".
- Filter on `longOpen: false` afterwards if you only want fresh postings.
- Greenhouse boards are open, so the actor connects directly by default. Turn Apify Proxy on if a run gets refused.

### FAQ

**Can I use it from Claude, ChatGPT or Cursor?** Yes, through Apify's MCP server:
`https://mcp.apify.com?tools=honestdata/greenhouse-jobs-monitor`.

**Does it collect personal data?** No. It reads public job postings, not candidates or recruiters.

**Is it legal?** It reads the public job-board data Greenhouse publishes for companies. You are responsible
for how you use it; check the terms of the sites involved and your local laws.

**Something broke?** Open an issue on the **Issues** tab. We test every tool every morning and
answer fast.

### More from Honest Data

- [Google Trends Scraper: 200 Keywords on One Scale](https://apify.com/honestdata/google-trends-one-scale)
- [AliExpress Scraper: Real Prices, Ads Flagged](https://apify.com/honestdata/aliexpress-product-search)
- [YouTube Transcript Scraper](https://apify.com/honestdata/youtube-transcript-scraper)
- [Product Demand Radar](https://apify.com/honestdata/product-demand-radar)

Found it useful? A short [review](https://apify.com/honestdata/greenhouse-jobs-monitor/reviews) helps others find it.

# Actor input Schema

## `boards` (type: `array`):

Company board tokens (the last part of boards.greenhouse.io/stripe) or full board links, one per line. Only companies that publish on Greenhouse have one.

## `titleKeywords` (type: `array`):

Keep only jobs whose title contains one of these whole words or phrases, like engineer or data ("intern" does not match "International"). Leave empty for all jobs.

## `locationKeywords` (type: `array`):

Keep only jobs whose location or office names contain one of these words, like Berlin or Canada. Whole words only ("US" does not match "Australia"). Companies write places their own way (US, USA, United States), so list variants. Leave empty for all.

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

Keep only jobs with 'remote' in the title, location or office names.

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

Add the plain-text job description to every row. Makes the dataset larger.

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

Stop after this many jobs for each board, newest postings first. For 'only new' monitoring set it above the board's size, because the cap is applied before the new-job check.

## `onlyNewSinceLastRun` (type: `boolean`):

For schedules: return (and pay for) only jobs this input hasn't returned before. The memory is kept per exact input (changing boards, filters or options starts it over) in a key-value store in your account.

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

Greenhouse's job-board data is open, so no proxy is used by default (faster and cheaper). Turn Apify Proxy on only if your runs get refused.

## Actor input object example

```json
{
  "boards": [
    "stripe"
  ],
  "remoteOnly": false,
  "includeDescription": false,
  "maxItems": 100,
  "onlyNewSinceLastRun": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (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 = {
    "boards": [
        "stripe"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("honestdata/greenhouse-jobs-monitor").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 = {
    "boards": ["stripe"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("honestdata/greenhouse-jobs-monitor").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 '{
  "boards": [
    "stripe"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call honestdata/greenhouse-jobs-monitor --silent --output-dataset

```

## MCP server setup

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

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/OADj4ne9ZVWU2Ies5/builds/DcYAI5NHPjrnOnfqn/openapi.json
