# Greenhouse, Lever & Ashby Job Scraper + Hiring Signals (`flawless_reishi/ats-job-scraper`) Actor

Scrape all job postings from any company’s Greenhouse, Lever, Ashby or SmartRecruiters job board. Normalized output, salary data where published, plus hiring signals: roles by department, hiring velocity, remote share.

- **URL**: https://apify.com/flawless\_reishi/ats-job-scraper.md
- **Developed by:** [Maxime](https://apify.com/flawless_reishi) (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 $2.00 / 1,000 job results

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.

- **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, Lever & Ashby Job Scraper + Hiring Signals

Extract **all open job postings** from any company's career page powered by **Greenhouse, Lever, Ashby, or SmartRecruiters** — the four ATS platforms behind the job boards of most startups and scale-ups. Get every job in one **normalized format** across all four systems, plus optional **per-company hiring signals**: open roles by department, hiring velocity, remote share, and salary ranges where published.

Unlike scrapers for aggregator sites (LinkedIn, Indeed), this Actor reads directly from the **company's own job board**, so the data is always complete, first-party, and fresh — no stale duplicates, no missing postings, and a **near-100% success rate** because it uses the boards' stable public endpoints instead of fragile HTML scraping.

### What can you do with it?

- **Sales & GTM signals** — hiring is a buying signal. A company opening 5 sales-engineering roles is investing in that area. Feed hiring signals into Clay, HubSpot, or your CRM to prioritize outreach.
- **Recruiting & talent intelligence** — track which companies are hiring for the roles you place, with salary ranges where published (Ashby & Lever).
- **Competitor monitoring** — watch competitors' headcount plans by department. New "Head of EU Sales" posting? They're expanding into Europe.
- **Job boards & aggregators** — build a niche job board from first-party listings with clean, structured data.
- **Market research** — track hiring trends across hundreds of companies over time by scheduling daily/weekly runs.

### Supported job board platforms

| ATS | Example board URL | Extra data |
|-----|-------------------|------------|
| **Greenhouse** | `https://boards.greenhouse.io/stripe` | departments, offices, first published & updated dates |
| **Lever** | `https://jobs.lever.co/palantir` | team, commitment, workplace type, salary ranges |
| **Ashby** | `https://jobs.ashbyhq.com/openai` | department, team, **compensation ranges**, remote flag |
| **SmartRecruiters** | `https://careers.smartrecruiters.com/…` | department, function, employment type, remote flag |

EU-hosted Greenhouse and Lever boards are supported too. Don't know which ATS a company uses? Just enter the company slug (e.g. `stripe`) and the Actor auto-detects it.

### How to use

1. Enter one or more companies — full board URLs, `greenhouse:slug` / `lever:slug` / `ashby:slug` / `smartrecruiters:slug`, or bare slugs for auto-detection.
2. Optionally filter by **title, location, department keywords** or **posting date**.
3. Run it. Each matched job is saved to the dataset; each company additionally gets one hiring-signals summary record (can be turned off).
4. Export as JSON, CSV, Excel, or connect via [API](https://docs.apify.com/api/v2), webhooks, or integrations (Make, Zapier, Google Sheets). Schedule daily runs to monitor changes.

### Input example

```json
{
    "companies": [
        "https://boards.greenhouse.io/stripe",
        "lever:palantir",
        "https://jobs.ashbyhq.com/openai"
    ],
    "titleFilter": ["engineer", "developer"],
    "locationFilter": ["remote", "london"],
    "postedAfter": "2026-06-01",
    "includeCompanySignals": true
}
```

### Output example — job

```json
{
    "type": "job",
    "source": "ashby",
    "company": "openai",
    "id": "240d459b-696d-43eb-8497-fab3e56ecd9b",
    "title": "Research Engineer",
    "department": "Research",
    "team": "Research",
    "location": "San Francisco",
    "secondaryLocations": [],
    "isRemote": null,
    "employmentType": "FullTime",
    "compensation": "$250K – $445K • Offers Equity",
    "url": "https://jobs.ashbyhq.com/openai/240d459b-696d-43eb-8497-fab3e56ecd9b",
    "applyUrl": "https://jobs.ashbyhq.com/openai/240d459b-696d-43eb-8497-fab3e56ecd9b/application",
    "publishedAt": "2025-04-05T00:03:20.653Z",
    "updatedAt": null
}
```

### Output example — company hiring signals

```json
{
    "type": "company-signals",
    "source": "greenhouse",
    "company": "stripe",
    "companyName": "Stripe",
    "boardUrl": "https://boards.greenhouse.io/stripe",
    "totalOpenJobs": 522,
    "jobsByDepartment": { "Solutions Architecture": 17, "Data Science": 11, "...": 0 },
    "topLocations": { "San Francisco, CA": 84, "Remote": 61 },
    "remoteJobs": 61,
    "remoteShare": 0.12,
    "jobsPostedLast7Days": 18,
    "jobsPostedLast30Days": 74,
    "jobsPostedLast90Days": 203,
    "newestPostingDate": "2026-07-13T14:37:36.000Z"
}
```

Tip: filter the dataset by `type` to separate jobs from signals (`?fields=…&view=…` in the API, or the **type** column in exports).

### Pricing

You pay per result: one **job result** event per job saved, and one **company signals** event per company summary. Use the filters and `maxJobsPerCompany` to control exactly how much you spend. A run's cost is capped by your "Maximum cost per run" setting — the Actor stops cleanly when the cap is reached.

### FAQ

**Is it legal to scrape job boards?** This Actor only collects public, first-party data that companies deliberately publish to attract applicants, via the boards' public endpoints. No login, no personal data.

**A company wasn't found — why?** The company may use a different ATS (Workable, Recruitee, BambooHR…), or its board slug differs from the company name. Find the careers page and paste the actual board URL. More ATS platforms are on the roadmap.

**How fresh is the data?** Real-time — every run reads the live board. Schedule runs to track changes over time.

**Can AI agents use this?** Yes — the Actor works out of the box with the [Apify MCP server](https://apify.com/apify/actors-mcp-server), so Claude, ChatGPT, and other agents can call it as a tool.

### Roadmap

- Workable, Recruitee, BambooHR, Personio support
- New-jobs-only mode (diff vs. previous run) with webhook alerts
- Company enrichment (domain, LinkedIn URL) on signal records

Missing a feature or an ATS? Open an issue on the Actor's **Issues** tab — feedback ships fast.

# Actor input Schema

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

Job board URLs or company slugs. Accepts: full board URLs (e.g. <code>https://boards.greenhouse.io/stripe</code>, <code>https://jobs.lever.co/palantir</code>, <code>https://jobs.ashbyhq.com/openai</code>), prefixed slugs (<code>greenhouse:stripe</code>, <code>lever:palantir</code>, <code>ashby:openai</code>, <code>smartrecruiters:Visa</code>), or bare slugs (<code>stripe</code>) which are auto-detected across all four ATSes.

## `titleFilter` (type: `array`):

Only keep jobs whose title contains at least one of these keywords (case-insensitive). Leave empty to keep all jobs.

## `locationFilter` (type: `array`):

Only keep jobs whose location (or any secondary location) contains at least one of these keywords (case-insensitive), e.g. <code>Remote</code>, <code>London</code>, <code>United States</code>.

## `departmentFilter` (type: `array`):

Only keep jobs whose department or team contains at least one of these keywords (case-insensitive), e.g. <code>Engineering</code>, <code>Sales</code>.

## `postedAfter` (type: `string`):

Only keep jobs published after this date (YYYY-MM-DD). Jobs with no publish date available are kept.

## `maxJobsPerCompany` (type: `integer`):

Maximum number of matched jobs to save per company. Use 0 for no limit.

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

Include the full job description (HTML) with each job. Increases output size. For SmartRecruiters this requires one extra API call per job.

## `includeCompanySignals` (type: `boolean`):

Add one summary record per company with hiring signals: total open roles, jobs by department and location, remote share, hiring velocity (jobs posted in the last 7/30/90 days).

## Actor input object example

```json
{
  "companies": [
    "https://boards.greenhouse.io/stripe",
    "https://jobs.lever.co/palantir",
    "https://jobs.ashbyhq.com/openai"
  ],
  "maxJobsPerCompany": 0,
  "includeDescription": false,
  "includeCompanySignals": true
}
```

# Actor output Schema

## `jobs` (type: `string`):

All matched job postings (items with type='job'), one item per posting: title, company, department, location, remote flag, compensation where published, posting URL and publish date.

## `hiringSignals` (type: `string`):

One summary item per company (items with type='company-signals'): total open jobs, jobs by department, top locations, remote share, and hiring velocity over the last 7/30/90 days.

# 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": [
        "https://boards.greenhouse.io/stripe",
        "https://jobs.lever.co/palantir",
        "https://jobs.ashbyhq.com/openai"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("flawless_reishi/ats-job-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 = { "companies": [
        "https://boards.greenhouse.io/stripe",
        "https://jobs.lever.co/palantir",
        "https://jobs.ashbyhq.com/openai",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("flawless_reishi/ats-job-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 '{
  "companies": [
    "https://boards.greenhouse.io/stripe",
    "https://jobs.lever.co/palantir",
    "https://jobs.ashbyhq.com/openai"
  ]
}' |
apify call flawless_reishi/ats-job-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/ucVrjsdha5KthPgNu/builds/kJqZGMAtPvIYOt4P2/openapi.json
