# Workday, Greenhouse, Lever & Ashby Jobs Scraper — $1/1k jobs (`tidydata/ats-jobs-scraper`) Actor

Scrape job postings straight from company career sites: Workday, Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee, Personio and Breezy. Paste any career page, filter by keyword, location, remote and date, get only new jobs. Salary, description, apply link. $1 per 1,000 jobs.

- **URL**: https://apify.com/tidydata/ats-jobs-scraper.md
- **Developed by:** [tidydata](https://apify.com/tidydata) (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

from $0.80 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## 💼 Workday, Greenhouse, Lever & Ashby Jobs Scraper — Career Sites (ATS)

Scrape **job postings straight from company career sites** — the source that LinkedIn and Indeed copy from — in one run and one table. Works with the 9 most used applicant tracking systems: **Workday, Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee, Personio and Breezy HR**.

Paste job board links or just a company's careers page (the job board is detected for you), filter by **title keywords, location, remote and posting date**, and get **title, location, department, employment type, salary (when published), posting date, full description and apply link**. Turn on **"Only new jobs"** and schedule it daily for job alerts.

**$1 per 1,000 jobs.** No login, no API key, no browser.

- ✅ **9 ATS in one scraper**, same columns for all (`ats`: `workday`, `greenhouse`, `lever`, `ashby`…)
- ✅ **Any input**: job board links, careers pages (`https://www.notion.com/careers` → Ashby), or `greenhouse:stripe`
- ✅ **Filters**: title keywords (include / exclude), locations, remote only, posted in the last N days
- ✅ **Salary** where the company publishes it (Ashby, Lever, Recruitee…) — min, max, currency, period
- ✅ **Only new jobs since the last run** — remembers what you already got, per company and filters
- ✅ **Full description** as clean text (or off, for lighter rows)
- ✅ **Workday at scale**: keywords are searched on Workday itself, newest jobs first
- ✅ Official public job-board feeds → fast, reliable, no blocking

### Who uses it

- **Job boards & aggregators** — fill your site with fresh jobs straight from the source.
- **Recruiters & staffing agencies** — see who's hiring for which roles, and spot new openings first.
- **B2B sales** — hiring = buying signal: a company hiring 5 data engineers needs data tools.
- **Job seekers** — a daily alert from your 50 dream companies, before the jobs hit LinkedIn.
- **Researchers & HR analytics** — hiring trends, salary ranges and remote share by company.

### How to use it

1. **Companies** — one per line, any mix:
   ```
   https://boards.greenhouse.io/stripe
   https://jobs.lever.co/palantir
   https://jobs.ashbyhq.com/openai
   https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite
   https://apply.workable.com/huggingface
   https://careers.smartrecruiters.com/BoschGroup
   https://bunq.recruitee.com
   https://www.notion.com/careers
   linear
   ```
   A bare name like `linear` is tried on Greenhouse, Lever and Ashby.
2. **Filters** (optional): title keywords like `engineer`, `data`, `account executive`; exclude words like `senior` or `intern`; locations like `London`, `Germany`, `Remote`; remote only; posted in the last N days.
3. **Only new jobs** (optional) + a daily **schedule** = job alerts. Export to CSV, Excel, JSON, Google Sheets, Slack…

### Output example

```json
{
  "type": "job",
  "company": "openai",
  "ats": "ashby",
  "title": "Software Engineer, Financial Engineering",
  "location": "San Francisco",
  "remote": false,
  "workplaceType": "Hybrid",
  "department": "Applied AI",
  "employmentType": "FullTime",
  "postedAt": "2026-08-28T17:41:41.133+00:00",
  "salaryText": "$266K – $445K • Offers Equity",
  "salaryMin": 266000,
  "salaryMax": 445000,
  "salaryCurrency": "USD",
  "salaryInterval": "1 YEAR",
  "url": "https://jobs.ashbyhq.com/openai/…",
  "applyUrl": "https://jobs.ashbyhq.com/openai/…/application",
  "description": "About the team…",
  "boardUrl": "https://jobs.ashbyhq.com/openai",
  "scrapedAt": "2026-10-20T09:15:02+00:00",
  "charged": true
}
```

Other fields when the job board has them: `jobId`, `locations` (all locations), `country`, `team`, `requisitionId`, `salaryInterval`, `updatedAt`, `postedAtText` (Workday, e.g. "Posted 3 Days Ago"), `hiringEntity` (Workday legal entity), `extra` (seniority, function, industry…), `isNew`.

### What each job board gives

| ATS | Description | Salary | Remote flag | Posted date |
|---|---|---|---|---|
| Workday | ✅ | in text | ✅ | ✅ |
| Greenhouse | ✅ | in text | from location | ✅ |
| Lever | ✅ | ✅ when published | ✅ | ✅ |
| Ashby | ✅ | ✅ when published | ✅ | ✅ |
| Workable | ✅ | — | ✅ | ✅ |
| SmartRecruiters | ✅ | — | ✅ | ✅ |
| Recruitee | ✅ | ✅ when published | ✅ | ✅ |
| Personio | ✅ | — | from location | ✅ |
| Breezy HR | — | ✅ when published | ✅ | ✅ |

### Pricing

**$0.001 per job ($1 per 1,000).** Store discounts apply automatically on paid Apify plans (−10 % Bronze, −15 % Silver, −20 % Gold). Error rows (e.g. a company with no job board found) are free, and with **Only new jobs** you only pay for new postings. Set a maximum cost per run and the scraper stops right there.

Example: 50 companies, ~40 matching jobs each = 2,000 jobs = **$2**. A daily alert on the same 50 companies with only new jobs usually costs a few cents.

### Tips

- **Can't find the job board?** Open the company's careers page, click a job, and paste that page's link — it shows which ATS they use.
- Workday links look like `https://<company>.wd1.myworkdayjobs.com/<SiteName>` (wd1, wd3, wd5…).
- Use **max jobs per company** to keep big employers (5,000+ jobs) under control.

### More from TidyData

[Website Contact Extractor](https://apify.com/tidydata/website-contact-extractor) — emails, phones and social links of the companies that are hiring · [Merge, Deduplicate & Transform](https://apify.com/tidydata/merge-dedupe-datasets) — combine runs and remove repeated jobs · [Google Sheets Export](https://apify.com/tidydata/google-sheets-export-import).

### FAQ

**Is it legal?** It reads the public job-board feeds that companies publish so their jobs can be shown on other sites, without login. Job postings are public business information. Use the data responsibly and follow the terms of the sites where you republish.

**Something missing?** Want another ATS (BambooHR, Teamtailor, iCIMS…)? Open an issue in the Issues tab.

# Actor input Schema

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

One per line. Job board links (e.g. https://boards.greenhouse.io/stripe, https://jobs.lever.co/palantir, https://jobs.ashbyhq.com/openai, https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite, https://apply.workable.com/huggingface, https://careers.smartrecruiters.com/BoschGroup, https://bunq.recruitee.com), a company's own careers page (the job board is detected) or 'greenhouse:stripe'.

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

Keep jobs whose title contains ANY of these (case-insensitive), e.g. 'engineer', 'data', 'sales'. Empty = all jobs.

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

Drop jobs whose title contains any of these, e.g. 'senior', 'intern', 'manager'.

## `searchInDescription` (type: `boolean`):

Look for the keywords in the job description too (e.g. a technology like 'python').

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

Keep jobs whose location contains ANY of these, e.g. 'London', 'Germany', 'Remote', 'NY'.

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

Only jobs the company marks as remote (or with 'Remote' in the location).

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

0 = any date.

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

Remembers the jobs already returned (per company and filters) and only returns new ones next time. Perfect for a daily schedule / job alerts. The first run returns everything.

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

Full description as clean text. Turn off for faster runs with lighter rows (same price).

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

Upper limit of jobs saved per company after filters.

## Actor input object example

```json
{
  "companies": [
    "https://boards.greenhouse.io/stripe",
    "https://jobs.lever.co/palantir",
    "https://jobs.ashbyhq.com/openai",
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "keywords": [
    "engineer"
  ],
  "searchInDescription": false,
  "remoteOnly": false,
  "postedWithinDays": 0,
  "onlyNewJobs": false,
  "includeDescription": true,
  "maxJobsPerCompany": 1000
}
```

# Actor output Schema

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

One row per result.

# 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",
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    ],
    "keywords": [
        "engineer"
    ]
};

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

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

```

## MCP server setup

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