# Greenhouse, Lever & Ashby Jobs Scraper API + New Job Alerts (`piracema_labs/ats-jobs-monitor`) Actor

Scrape open jobs from any company's Greenhouse, Lever or Ashby careers page into one clean table: title, location, remote, salary, department, description. Paste a careers URL or company name and it finds the platform automatically. Monitor mode returns only new jobs, and you pay only for those.

- **URL**: https://apify.com/piracema_labs/ats-jobs-monitor.md
- **Developed by:** [Piracema Labs](https://apify.com/piracema_labs) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 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

## Greenhouse, Lever & Ashby Jobs Scraper API + New Job Alerts

Get every open job from any company that hires through **Greenhouse**, **Lever** or **Ashby**: title, department, location, remote status, **salary range**, publish date, apply link and full description. Results come back in one clean, consistent format, whichever platform the company uses.

Turn on **monitor mode** and schedule it daily. You get a feed of **only the jobs posted since the last run**, and you pay only for those.

Thousands of companies use these three platforms, including Stripe, OpenAI, Spotify, Figma, Notion, Airbnb, Ramp and Linear.

### What can I use it for?

- **Job seekers and job boards:** collect fresh openings from a list of target companies, filtered by role, location or remote.
- **Sales teams (hiring signals):** a company hiring "Head of Data" or "Security Engineer" is likely buying related tools. Get an alert the day the job appears.
- **Recruiters and talent intelligence:** track which teams competitors are growing, and where.
- **Salary research:** many Ashby and Lever postings, and some Greenhouse ones, publish pay ranges. You get them as numbers (`salaryMin`, `salaryMax`, `salaryCurrency`), not just text.
- **Investors and analysts:** watch hiring velocity across a portfolio or a market.

### How to use it

1. Add companies to **Companies**. You can paste either of these:
   - a careers URL: `https://boards.greenhouse.io/stripe`, `https://jobs.lever.co/spotify`, `https://jobs.ashbyhq.com/openai`, `https://jobs.eu.lever.co/...`
   - just the board name, such as `stripe`. The Actor checks Greenhouse, Ashby and Lever and finds it.
2. Optional filters: **title keywords**, **exclude keywords**, **locations**, **remote only**, **posted within N days**.
3. Click **Start**. Download results as JSON, CSV, Excel or HTML, or pull them through the API.

**Tip: how do I find a company's board name?** Open their careers page and click any job. If the link contains `greenhouse.io/<name>`, `lever.co/<name>` or `ashbyhq.com/<name>`, that `<name>` is what you need.

#### Monitor mode: only new jobs

Turn on **Only new jobs** and give it a **Monitor name**, such as `fintech-engineers`, then add a [schedule](https://docs.apify.com/platform/schedules) (for example daily at 8:00).

- The first run returns all matching open jobs. This is your baseline.
- Each later run returns only jobs that weren't returned before.
- Jobs that close and disappear are forgotten, so memory stays small.
- Use different monitor names for different watch lists.

Connect the run to Slack, email, Google Sheets, Zapier or Make with Apify [integrations](https://docs.apify.com/platform/integrations) to get new jobs delivered automatically.

### How to scrape Greenhouse jobs

Paste a Greenhouse board URL such as `https://boards.greenhouse.io/stripe` or `https://job-boards.greenhouse.io/figma`, or just the board name (`stripe`). You get every open role with department, office locations and the company name. Pay ranges are extracted when the posting includes them.

### Lever job scraper

Paste a Lever careers URL such as `https://jobs.lever.co/spotify`. EU-hosted boards (`jobs.eu.lever.co`) work too. Lever provides workplace type (remote, hybrid or onsite), commitment, team and, when the company publishes it, a structured salary range.

### Ashby jobs API

Paste an Ashby board URL such as `https://jobs.ashbyhq.com/openai`. Ashby is used by many fast-growing startups and often publishes **structured compensation**, so you get `salaryMin`, `salaryMax` and currency for most roles.

### Hiring signals for sales teams

A company that starts hiring for a role is often about to buy tools for that team: new "Data Engineer" roles suggest data tooling, new "Security Engineer" roles suggest security tooling.

1. Put your target accounts in **Companies** and the roles you care about in **Title keywords**.
2. Turn on **Only new jobs** and schedule a daily run.
3. Connect the run to **Slack**, **Google Sheets**, **email**, **Zapier** or **Make** with Apify [integrations](https://docs.apify.com/platform/integrations).

Each morning you get only the new postings, ready for outreach.

### Use it as an API

Call it from your own code and get the jobs back in one request:

```bash
curl -X POST "https://api.apify.com/v2/acts/piracema_labs~ats-jobs-monitor/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"companies": ["stripe", "https://jobs.lever.co/spotify"], "keywords": ["engineer"]}'
```

Official Apify clients for [JavaScript](https://docs.apify.com/api/client/js) and [Python](https://docs.apify.com/api/client/python) work as well.

### Input example

```json
{
    "companies": ["stripe", "https://jobs.lever.co/spotify", "https://jobs.ashbyhq.com/openai"],
    "keywords": ["engineer", "data"],
    "excludeKeywords": ["intern"],
    "locations": ["London", "Remote"],
    "postedWithinDays": 30,
    "onlyNewJobs": true,
    "monitorId": "eng-watchlist"
}
```

### Output example

Each job is one row with the same fields, whichever platform it came from:

```json
{
    "ats": "ashby",
    "companySlug": "openai",
    "companyName": "openai",
    "jobId": "e99105f1-0a15-4f25-9538-60312568f835",
    "title": "Software Engineer, Privacy Engineering",
    "department": "Security",
    "team": "Security",
    "employmentType": "Full-time",
    "location": "San Francisco",
    "allLocations": ["San Francisco"],
    "isRemote": false,
    "workplaceType": null,
    "salaryMin": 347000,
    "salaryMax": 385000,
    "salaryCurrency": "USD",
    "salaryInterval": "year",
    "salaryText": "$347K – $385K • Offers Equity",
    "url": "https://jobs.ashbyhq.com/openai/e99105f1-...",
    "applyUrl": "https://jobs.ashbyhq.com/openai/e99105f1-.../application",
    "publishedAt": "2026-10-21T22:55:41.495Z",
    "updatedAt": null,
    "description": "About the Team\n\nThe Privacy Engineering team builds…",
    "scrapedAt": "2026-10-22T14:57:01.575Z"
}
```

| Field                       | Notes                                                                                                                                                        |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ats`                       | `greenhouse`, `lever` or `ashby`                                                                                                                             |
| `companyName`               | Greenhouse supplies the real company name. Lever and Ashby give the board name.                                                                              |
| `isRemote`, `workplaceType` | Taken from the platform when available, otherwise detected from the location text                                                                            |
| `salary*`                   | Ashby and Lever: structured pay data. Greenhouse: extracted from the description when a range is written there. `null` when the company doesn't publish pay. |
| `publishedAt`               | When the job was first published (ISO 8601)                                                                                                                  |
| `description`               | Plain text. Turn off **Include job description** for smaller exports.                                                                                        |

### How much does it cost?

You pay for the jobs saved to your results: **$1.00 per 1,000 jobs** ($0.001 per job), plus a tiny **$0.0005 start fee per run**. There are no proxy costs, no platform usage costs, and no extra fees for companies with zero matches.

| Example                                          | Jobs       | Cost         |
| ------------------------------------------------ | ---------- | ------------ |
| Engineering roles at 20 startups (one run)       | ~400       | ~$0.40       |
| Daily monitor of 100 companies, ~30 new jobs/day | ~900/month | ~$0.92/month |
| Full export of 1,000 companies (one run)         | ~50,000    | ~$50         |

In monitor mode you're charged only for new jobs, so watching a large list every day stays cheap. You can set a maximum cost per run in the run options, and the Actor stops cleanly when it's reached.

### Is it legal? Where does the data come from?

The Actor reads each platform's **official public job-board API**: the same endpoints companies use to show jobs on their own careers pages ([Greenhouse](https://developers.greenhouse.io/job-board.html), [Lever](https://github.com/lever/postings-api), [Ashby](https://developers.ashbyhq.com/docs/public-job-posting-api)). No logins, no private data, no personal profiles. Only public job postings. It respects robots.txt and Lever's requested crawl delay.

### FAQ

**A company returns "no public job board found".**
Check the board name in a job link (see the tip above). Some companies use other platforms, such as Workday or SmartRecruiters. Those aren't supported yet.

**Why are some salaries empty?**
Many companies don't publish pay ranges, especially outside the US. The Actor fills salary fields only when the company provides them.

**Do I need a Greenhouse, Lever or Ashby API key?**
No. The Actor uses the public job-board endpoints that power companies' own careers pages. You only need an Apify account.

**How often can I run it?**
As often as you like. Daily is typical for monitoring; hourly works for time-sensitive alerts. In monitor mode, runs with no new jobs cost only the $0.0005 start fee.

**Can I export to CSV or Excel?**
Yes. Every run's results can be downloaded as CSV, Excel, JSON, XML or HTML, or sent to Google Sheets automatically.

**Can I get jobs from Workday, Workable or other platforms?**
Not yet. If you need one, open an issue on the Issues tab. Requests decide what gets added next.

**Something broke or looks wrong?**
Open an issue on the Issues tab with a link to your run.

# Actor input Schema

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

Companies to pull jobs from. Paste a careers-page URL (boards.greenhouse.io/…, job-boards.greenhouse.io/…, jobs.lever.co/…, jobs.eu.lever.co/…, jobs.ashbyhq.com/…) or just the company's board name, such as <code>stripe</code>. Bare names are looked up on Greenhouse, Ashby and Lever automatically.

## `ats` (type: `string`):

Which platform bare company names belong to. Leave on Auto-detect unless a name exists on more than one platform. URLs always use the platform in the URL.

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

Keep only jobs whose title, department or team contains at least one of these words (case-insensitive). Leave empty to keep all jobs.

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

Drop jobs whose title contains any of these words, for example <code>intern</code> or <code>senior</code>.

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

Keep only jobs whose location contains one of these texts, such as <code>London</code>, <code>Germany</code> or <code>Remote</code>. Leave empty for all locations.

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

Keep only jobs marked as remote.

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

Keep only jobs published in the last N days. 0 means any date. Greenhouse, Lever and Ashby all report a publish date.

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

Add the full job description as plain text. Turn off for smaller, faster exports.

## `onlyNewJobs` (type: `boolean`):

Remember which jobs earlier runs returned and output only jobs that are new since then. The first run returns every matching job as a baseline. Schedule the Actor daily to get a feed of fresh openings, and pay only for new jobs.

## `monitorId` (type: `string`):

Keeps separate memory for different watch lists. Use a different name for each schedule, such as <code>fintech-engineers</code>.

## `maxJobs` (type: `integer`):

Stop after saving this many jobs. 0 means no limit.

## Actor input object example

```json
{
  "companies": [
    "stripe",
    "https://jobs.lever.co/spotify",
    "https://jobs.ashbyhq.com/openai"
  ],
  "ats": "auto",
  "keywords": [
    "engineer",
    "data"
  ],
  "excludeKeywords": [],
  "locations": [],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "includeDescription": true,
  "onlyNewJobs": false,
  "monitorId": "default",
  "maxJobs": 0
}
```

# 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 = {
    "companies": [
        "stripe",
        "https://jobs.lever.co/spotify",
        "https://jobs.ashbyhq.com/openai"
    ],
    "keywords": [
        "engineer",
        "data"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("piracema_labs/ats-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 = {
    "companies": [
        "stripe",
        "https://jobs.lever.co/spotify",
        "https://jobs.ashbyhq.com/openai",
    ],
    "keywords": [
        "engineer",
        "data",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("piracema_labs/ats-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 '{
  "companies": [
    "stripe",
    "https://jobs.lever.co/spotify",
    "https://jobs.ashbyhq.com/openai"
  ],
  "keywords": [
    "engineer",
    "data"
  ]
}' |
apify call piracema_labs/ats-jobs-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,piracema_labs/ats-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/21oKoBnRZiUW6gl6z/builds/qZde0A0cCtCzwLE3G/openapi.json
