# Job Postings Monitor - Greenhouse, Lever & Ashby (`hryndev/ats-hiring-monitor`) Actor

Monitor job boards of any companies on Greenhouse, Lever or Ashby. Get new, changed and closed job postings as events — perfect hiring signals for outbound sales, recruiting and market intelligence.

- **URL**: https://apify.com/hryndev/ats-hiring-monitor.md
- **Developed by:** [Vladimir](https://apify.com/hryndev) (community)
- **Categories:** Jobs, Business, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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

## Job Postings Monitor — Greenhouse, Lever & Ashby

Track the job boards of **any list of companies** hiring through [Greenhouse](https://www.greenhouse.com/), [Lever](https://www.lever.co/) or [Ashby](https://www.ashbyhq.com/) — and get **new, changed and closed job postings as clean events**, not a raw dump you have to diff yourself.

Companies post jobs before they buy tools, expand teams, or enter markets. That makes job postings the highest-signal, publicly available buying intent data there is. This Actor turns them into a feed you can pipe straight into your outreach, recruiting or market-intelligence workflow.

### Who is this for?

- **Outbound sales & GTM teams** — "company X just opened 3 Sales Ops roles" is a perfect trigger to reach out. Feed events into Clay, n8n, Make or your CRM.
- **Recruiters & sourcing agencies** — know the moment target companies open (or quietly close) positions.
- **Founders & analysts** — watch competitors' hiring to see what they're building next.
- **Job seekers** — get notified the hour your dream company posts a matching role.

### What it does

1. You give it a list of company slugs (from their job board URL — the Actor **auto-detects** whether each company uses Greenhouse, Lever or Ashby).
2. On the first run it snapshots the full board (optional baseline output, so you get data immediately).
3. On every following run it compares against the stored state and outputs **only what happened**:

| `event` | Meaning |
|---------|---------|
| `new` | job posting appeared since last run |
| `changed` | title / location / department of a posting changed |
| `closed` | posting disappeared (filled or withdrawn) |
| `baseline` | first-run snapshot (optional) |
| `heartbeat` | nothing changed this run (single record, so you can see the monitor is alive) |

4. Optionally it POSTs the events to your **webhook** (Slack, Discord, Zapier, Make, n8n — anything that accepts JSON).

Run it on a [schedule](https://docs.apify.com/platform/schedules) (daily is typical) and you have a fully automated hiring-signals feed.

### Quick start

```json
{
    "companies": ["gitlab", "duolingo", "ramp"],
    "roleFilters": ["engineer", "sales|account executive"],
    "webhookUrl": "https://hooks.slack.com/services/XXX/YYY/ZZZ"
}
````

- `companies` — slugs from the job board URL: `boards.greenhouse.io/gitlab` → `gitlab`, `jobs.lever.co/acme` → `acme`, `jobs.ashbyhq.com/ramp` → `ramp`. ATS is auto-detected; pin it explicitly with `gitlab:greenhouse` if you want to skip detection.
- `roleFilters` — optional case-insensitive regex list. Only postings whose title matches are tracked ("companies hiring **this role**").
- `webhookUrl` — optional. Fires only when there are actual events (never on baseline).

### Output example

```json
{
    "event": "new",
    "source": "greenhouse",
    "company": "gitlab",
    "job_id": "8565469002",
    "title": "AI Engineer",
    "location": "Remote, US",
    "department": null,
    "url": "https://job-boards.greenhouse.io/gitlab/jobs/8565469002",
    "published_at": "2026-07-01T09:12:44-04:00",
    "detected_at": "2026-07-23T20:01:17+00:00"
}
```

Get results as JSON, CSV or Excel from the dataset, via [API](https://docs.apify.com/api/v2), or in the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) for AI agents.

### Why this instead of a generic job scraper?

Generic scrapers give you today's snapshot. To get *signals* you'd have to store yesterday's snapshot, diff them, handle companies that temporarily fail, and de-duplicate — every day, yourself. This Actor does exactly that internally (state is kept in a named key-value store in **your** Apify account) and charges you for **events**, so a quiet day costs almost nothing.

- Covers the three most popular startup/scaleup ATS platforms in one Actor
- Auto-detection: paste slugs, not ATS names
- Role regex filters: track "who is hiring senior Python engineers", not everything
- Resilient: if one company's board is temporarily down, its jobs are **not** falsely reported as closed
- No login, no proxies to configure, no cookies — public JSON APIs only

### FAQ

**Where do I find a company's slug?** Open their careers page and look at the job application links: `boards.greenhouse.io/<slug>`, `jobs.lever.co/<slug>` or `jobs.ashbyhq.com/<slug>`.

**What if a company isn't on Greenhouse/Lever/Ashby?** The run reports it in `companies_failed` (see the `SUMMARY` key-value record) and continues with the rest.

**How often should I run it?** Daily fits most sales/recruiting workflows. The monitor state is per-configuration, so you can run several different company lists in parallel without them interfering.

**Is this legal?** The Actor reads the same public job-board APIs the companies' own careers pages use. No authentication is bypassed and no personal data is collected.

# Actor input Schema

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

Company slugs as used in their job board URL (e.g. `gitlab` from boards.greenhouse.io/gitlab, `ramp` from jobs.ashbyhq.com/ramp). The ATS is auto-detected, or pin it with `slug:ats`, e.g. `gitlab:greenhouse`.

## `roleFilters` (type: `array`):

Only track jobs whose title matches any of these patterns (case-insensitive regex). Example: `engineer`, `sales|account executive`, `senior.*python`. Leave empty to track all jobs.

## `webhookUrl` (type: `string`):

POST JSON with new/changed/closed jobs to this URL after each run that detects changes. Works great with Slack/Discord/Zapier/Make/n8n webhooks.

## `includeBaseline` (type: `boolean`):

First run has nothing to compare against. When enabled (default), it outputs every current job with event=baseline, so you get data immediately.

## Actor input object example

```json
{
  "companies": [
    "gitlab",
    "duolingo",
    "ramp"
  ],
  "roleFilters": [],
  "includeBaseline": true
}
```

# 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 = {
    "companies": [
        "gitlab",
        "duolingo",
        "ramp"
    ],
    "roleFilters": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("hryndev/ats-hiring-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 = {
    "companies": [
        "gitlab",
        "duolingo",
        "ramp",
    ],
    "roleFilters": [],
}

# Run the Actor and wait for it to finish
run = client.actor("hryndev/ats-hiring-monitor").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 '{
  "companies": [
    "gitlab",
    "duolingo",
    "ramp"
  ],
  "roleFilters": []
}' |
apify call hryndev/ats-hiring-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=hryndev/ats-hiring-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Job Postings Monitor - Greenhouse, Lever & Ashby",
        "description": "Monitor job boards of any companies on Greenhouse, Lever or Ashby. Get new, changed and closed job postings as events — perfect hiring signals for outbound sales, recruiting and market intelligence.",
        "version": "0.1",
        "x-build-id": "ufWo60WOJ5ZC4Xt4x"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/hryndev~ats-hiring-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-hryndev-ats-hiring-monitor",
                "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/hryndev~ats-hiring-monitor/runs": {
            "post": {
                "operationId": "runs-sync-hryndev-ats-hiring-monitor",
                "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/hryndev~ats-hiring-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-hryndev-ats-hiring-monitor",
                "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",
                "required": [
                    "companies"
                ],
                "properties": {
                    "companies": {
                        "title": "Companies",
                        "type": "array",
                        "description": "Company slugs as used in their job board URL (e.g. `gitlab` from boards.greenhouse.io/gitlab, `ramp` from jobs.ashbyhq.com/ramp). The ATS is auto-detected, or pin it with `slug:ats`, e.g. `gitlab:greenhouse`.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "roleFilters": {
                        "title": "Role filters (regex, optional)",
                        "type": "array",
                        "description": "Only track jobs whose title matches any of these patterns (case-insensitive regex). Example: `engineer`, `sales|account executive`, `senior.*python`. Leave empty to track all jobs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "webhookUrl": {
                        "title": "Notification webhook (optional)",
                        "type": "string",
                        "description": "POST JSON with new/changed/closed jobs to this URL after each run that detects changes. Works great with Slack/Discord/Zapier/Make/n8n webhooks."
                    },
                    "includeBaseline": {
                        "title": "Output all current jobs on first run",
                        "type": "boolean",
                        "description": "First run has nothing to compare against. When enabled (default), it outputs every current job with event=baseline, so you get data immediately.",
                        "default": true
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
