# ATS Jobs Scraper: Greenhouse, Lever, Ashby, Workday (`ksvan/ats-jobs-scraper`) Actor

Scrape open jobs straight from company career boards on Greenhouse, Lever, Ashby, Workday and SmartRecruiters. Paste board URLs, any careers page or just company names. Unified fields: title, department, location, remote, salary, dates, apply link, full description.

- **URL**: https://apify.com/ksvan/ats-jobs-scraper.md
- **Developed by:** [K.S. Van](https://apify.com/ksvan) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$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

## ATS Jobs Scraper: Greenhouse, Lever, Ashby, Workday

Scrape **open job postings straight from company career boards** on **Greenhouse, Lever, Ashby, Workday and SmartRecruiters**. Paste board URLs, **any careers page** that embeds one of these boards, or **just company names**. The platform is detected automatically and every job comes back in **one unified format**: title, department, location, remote flag, employment type, dates, salary range (when the company publishes it), apply link and the full description.

The data comes from the public job-board endpoints the companies themselves publish, so it is fresh, complete and fast. No login, no browser. Pay only per job delivered.

### What you can paste

- Greenhouse: `https://job-boards.greenhouse.io/airbnb`, `boards.greenhouse.io/stripe`
- Lever: `https://jobs.lever.co/palantir` (EU boards `jobs.eu.lever.co` too)
- Ashby: `https://jobs.ashbyhq.com/ramp`
- Workday: `https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite`, `https://wd1.myworkdaysite.com/recruiting/wf/WellsFargoJobs`
- SmartRecruiters: `https://jobs.smartrecruiters.com/BoschGroup`
- Any careers page: `https://www.figma.com/careers/`, `https://openai.com/careers/search/` (the embedded board is found for you)
- Company names in **Company names**: `stripe`, `notion`, `duolingo`

### What you get

| Field | Example |
|---|---|
| `company`, `companySlug`, `platform`, `boardUrl` | Airbnb, airbnb, greenhouse |
| `jobId`, `title`, `requisitionId` | 7532824, Engineering Manager, Guest & Host |
| `department`, `team` | Software Engineering, Backend |
| `location`, `locations`, `country` | London, United Kingdom |
| `isRemote`, `workplaceType` | true, Hybrid |
| `employmentType`, `experienceLevel` | Full-time, Associate |
| `postedAt`, `updatedAt` | 2026-01-23T11:33:08-05:00 |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryInterval`, `salaryText` | 211400, 290600, USD, 1 YEAR, $211.4K – $290.6K • Offers Equity |
| `url`, `applyUrl` | job page and application link |
| `descriptionText`, `descriptionHtml` | full description (turn off **Include job description** to skip) |

Fields a platform does not publish are `null` (for example Workday and SmartRecruiters have no salary field).

### Use cases

- **Job aggregators and job boards**: pull fresh postings from hundreds of companies in one consistent schema.
- **Recruiting and sales intelligence**: see who is hiring, for which teams and where. Hiring signals are strong buying signals.
- **Market and salary research**: compare roles, locations, remote share and published pay ranges across companies.
- **Job alerts**: schedule a daily run with **Posted after**, **Job title contains** and **Location contains**.
- **AI and RAG**: clean description text for matching, classification and LLM pipelines.

### How to use

1. Add board URLs, careers pages and/or company names.
2. Optionally filter by title words, excluded words, location, department, remote only and posted date.
3. Set **Max jobs per company** and run. Each job is one dataset record.

#### Example input

```json
{
  "startUrls": ["https://job-boards.greenhouse.io/airbnb", "https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite"],
  "companies": ["stripe", "notion"],
  "titleKeywords": ["engineer"],
  "locations": ["Remote", "New York"],
  "postedAfter": "2026-09-01",
  "maxJobsPerCompany": 200
}
```

### Pricing

- **Job**: charged per job saved to the dataset. Sources that fail (company not found, no board on the page) are reported in the dataset as `error` records and are **not charged**.

### Tips and limits

- Filters run before charging: you only pay for jobs that match.
- Workday sites show at most 2,000 jobs per search. For very large employers add **Job title contains** words: each word runs its own Workday search, so you can reach more than 2,000 jobs.
- Company-name detection tries Greenhouse, Lever, Ashby and SmartRecruiters. Workday needs the career site URL because each company has its own address.
- `postedAt` for Workday is the posting start date. The site's relative label ("Posted 30+ Days Ago") is in `postedOnText`.

### FAQ

**Is it legal?** The actor reads the public job listings that companies publish for job seekers and aggregators. Use the data in line with the job board's terms and data protection rules.

**Which companies use these platforms?** Thousands of tech and enterprise employers: Greenhouse (Airbnb, Stripe, Figma, Duolingo), Ashby (OpenAI, Notion, Ramp), Lever (Palantir), Workday (NVIDIA, Wells Fargo and most Fortune 500 companies), SmartRecruiters (Bosch and many others).

**Something missing?** Open an issue on the Issues tab and I will look at it.

# Actor input Schema

## `startUrls` (type: `array`):

Greenhouse, Lever, Ashby, Workday (myworkdayjobs.com / myworkdaysite.com) or SmartRecruiters board URLs, or any company careers page that embeds one of them (the board is detected automatically).

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

Optional. Bare company names or board slugs (stripe, notion, figma). The platform is detected automatically: Greenhouse, Lever, Ashby, then SmartRecruiters. Workday needs the career site URL.

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

Optional. Keep jobs whose title contains any of these words (engineer, marketing, sales).

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

Optional. Drop jobs whose title contains any of these words (intern, senior).

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

Optional. Keep jobs whose location contains any of these (London, Remote, Germany).

## `departments` (type: `array`):

Optional. Keep jobs whose department or team contains any of these.

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

Keep only remote jobs.

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

Optional YYYY-MM-DD. Keep jobs first published on or after this date.

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

Limit per board, after filters.

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

Add the full description as text and HTML.

## `platforms` (type: `array`):

Platforms tried for company names and careers pages.

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

Stop after this many jobs in total. 0 = no limit.

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

Apify datacenter proxy works well.

## `maxRetries` (type: `integer`):

Retries with a fresh proxy IP before a source is reported as failed.

## Actor input object example

```json
{
  "startUrls": [
    "https://job-boards.greenhouse.io/airbnb",
    "https://jobs.ashbyhq.com/ramp"
  ],
  "remoteOnly": false,
  "postedAfter": "",
  "maxJobsPerCompany": 1000,
  "includeDescription": true,
  "platforms": [
    "greenhouse",
    "lever",
    "ashby",
    "workday",
    "smartrecruiters"
  ],
  "maxItems": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxRetries": 5
}
```

# Actor output Schema

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

One record per job posting.

# 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 = {
    "startUrls": [
        "https://job-boards.greenhouse.io/airbnb",
        "https://jobs.ashbyhq.com/ramp"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ksvan/ats-jobs-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 = {
    "startUrls": [
        "https://job-boards.greenhouse.io/airbnb",
        "https://jobs.ashbyhq.com/ramp",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("ksvan/ats-jobs-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 '{
  "startUrls": [
    "https://job-boards.greenhouse.io/airbnb",
    "https://jobs.ashbyhq.com/ramp"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call ksvan/ats-jobs-scraper --silent --output-dataset

```

## MCP server setup

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