# ATS Jobs Scraper: Greenhouse, Lever, Ashby, Workday & 7 More (`sports-odds-lab/ats-jobs-scraper`) Actor

Open jobs straight from company career sites: Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Workable, Recruitee, Personio, Teamtailor, Breezy HR and Pinpoint. Paste career URLs or just company names. Salary, remote/hybrid, filters and only-new-jobs mode.

- **URL**: https://apify.com/sports-odds-lab/ats-jobs-scraper.md
- **Developed by:** [Min Maxxxer](https://apify.com/sports-odds-lab) (community)
- **Categories:** Jobs, Automation, Developer tools
- **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/actors/running/actors-in-store.md#pay-per-usage

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

> 🎁 **Free until 13 October 2026.** Press **Start** — the prefilled input returns jobs of OpenAI, Palantir and Figma in seconds.

![Sample output: open jobs of OpenAI, Zoox, Figma, Perplexity, Linear, bunq, Bosch and NVIDIA from 8 different ATS, with salary ranges and remote or hybrid](https://api.apify.com/v2/key-value-stores/CEtWcytR8Vm5hiMr1/records/preview-jobs.png?signature=zDDm9zEVFiaHwOz0h84V)

Get **every open job straight from company career sites** — **Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Workable, Recruitee, Personio, Teamtailor, Breezy HR and Pinpoint** — in **one clean format**, whatever system each company uses. Paste career page URLs, **just type company names** — the Actor finds the job board by itself — or **search thousands of companies at once** with the built-in company directory.

Every row has the title, department, all locations with country codes, **remote / hybrid / on-site**, employment type, **salary range** (from the ATS, or read from the job description), posting date, description and the apply link.

**Why straight from the career site?**

- **Fresher and complete** — jobs appear here the moment the company posts them, before job boards pick them up, and nothing is missing or reposted.
- **Salary ranges** — structured pay data from Greenhouse, Lever, Ashby, Recruitee and Pinpoint, and pay ranges read from the description everywhere else ("$150,000 – $190,000 per year", "€60k–80k").
- **No login, no proxy, no personal data** — the Actor reads the public job board APIs that the career sites themselves use. Recruiter names and emails are never collected.

### Supported applicant tracking systems

| ATS | Paste | Or just the name | Salary | Description |
|---|---|---|---|---|
| **Greenhouse** | `boards.greenhouse.io/stripe` | ✅ | pay ranges + description | ✅ |
| **Lever** | `jobs.lever.co/palantir` | ✅ | salary range + description | ✅ |
| **Ashby** | `jobs.ashbyhq.com/openai` | ✅ | compensation tiers | ✅ |
| **Workday** | `nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite` | URL only | from description | ✅ |
| **SmartRecruiters** | `jobs.smartrecruiters.com/BoschGroup` | ✅ | from description | ✅ |
| **Workable** | `apply.workable.com/skroutz` | ✅ | from description | ✅ |
| **Recruitee** | `bunq.recruitee.com` | ✅ | salary fields | ✅ |
| **Personio** | `personio.jobs.personio.de` | ✅ | from description | ✅ |
| **Teamtailor** | `career.teamtailor.com` or the company's own domain | ✅ | from description | ✅ |
| **Breezy HR** | `breezy.breezy.hr` | ✅ | salary line | ✅ |
| **Pinpoint** | `workwithus.pinpointhq.com` | ✅ | compensation fields | ✅ |

You can also paste **the company's own careers page or website** (`figma.com/careers`, `linear.app/careers`) — the Actor looks for the job board the page embeds or links to. Big Workday sites with more than 2,000 jobs (the Workday limit per search) are split automatically, so you still get all of them.

### Search all companies at once

Turn on **Search all companies** and give at least one filter — job title words, a location, remote, or "posted within" — and the Actor searches **every company in its built-in directory: 15,000+ companies with 1,100,000+ open jobs** on Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Workable and more, found in public web archives and job lists and checked for open jobs. Everything is read live from the career sites at the moment of your run — no stale database.

```json
{
  "searchAllCompanies": true,
  "keywords": ["data engineer", "analytics engineer"],
  "locations": ["Berlin", "Remote"],
  "postedWithinDays": 7
}
```

A search through the whole directory takes about 10–15 minutes and you pay only for the jobs it finds; picking systems in **Directory: only these systems** or fewer keywords makes it faster. Workday, SmartRecruiters and Workable sites are searched on the site itself, so they are included when you give job title words. Combine it with **Only new jobs** for alerts across the whole market, or with your own list of companies — they are searched first.

### What you get — one row per job

| Field | Example |
|---|---|
| `company`, `ats`, `companySlug` | Figma, greenhouse, figma |
| `title`, `department`, `team` | Product Designer, Design |
| `location`, `locations`, `city`, `region`, `country`, `countryCode` | San Francisco, CA • New York, NY → `["San Francisco, CA", "New York, NY"]`, US |
| `workplaceType`, `remote` | remote / hybrid / onsite |
| `employmentType`, `seniority` | full-time, part-time, contract, temporary, internship… |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `salaryText`, `salarySource` | 165000, 190000, USD, year, "165,000 – 190,000 USD per year", ats / description |
| `postedAt`, `updatedAt`, `applicationDeadline` | ISO dates in UTC |
| `url`, `applyUrl`, `boardUrl`, `companyWebsite` | job page, application form, career site |
| `requisitionId`, `jobId`, `language` | the company's own job reference |
| `description` / `descriptionHtml` | full text, HTML or both |

The **per-company summary** (key-value store record `SUMMARY`) tells which ATS every company uses, how many jobs are open, how many matched your filters and which inputs were not found.

### How to use it

1. Add **companies**: career page URLs, websites or plain names — one per line, as many as you like.
2. Optionally **filter**: words in the job title (or description), locations (`Berlin`, `Germany`, `US`, `Remote`), remote / hybrid / on-site, employment type, department, jobs posted in the last N days.
3. Click **Start**, then download JSON, CSV or Excel, or read the dataset through the Apify API.

#### Input example — every open job at five companies

```json
{
  "companies": ["OpenAI", "Databricks", "https://jobs.lever.co/palantir", "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite", "figma.com/careers"]
}
```

#### Input example — remote data jobs in the US posted this week

```json
{
  "companies": ["Stripe", "Notion", "Figma", "Databricks", "Linear"],
  "keywords": ["data engineer", "analytics", "machine learning"],
  "excludeKeywords": ["intern"],
  "locations": ["US"],
  "workplace": "remote",
  "postedWithinDays": 7
}
```

#### Input example — a daily schedule that only delivers new jobs

```json
{
  "companies": ["OpenAI", "Anthropic", "Perplexity", "ElevenLabs", "https://jobs.lever.co/zoox"],
  "keywords": ["engineer"],
  "onlyNew": true,
  "incrementalName": "ai-engineering-jobs"
}
```

The first run returns all current jobs; every later run returns only jobs that were not delivered before — so a schedule every hour costs only for what is new. The memory lives in the key-value store `ats-jobs-incremental` in your own Apify account.

#### Output example (a real row, shortened)

```json
{
  "ats": "greenhouse",
  "company": "Figma",
  "jobId": "6180053004",
  "title": "Early Career, Product Designer (2027)",
  "department": "Early Career",
  "location": "San Francisco, CA • New York, NY",
  "locations": ["San Francisco, CA", "New York, NY"],
  "country": "United States",
  "countryCode": "US",
  "salaryMin": 140000,
  "salaryMax": 140000,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "salaryText": "140,000 USD per year",
  "salarySource": "ats",
  "postedAt": "2026-09-23T00:27:29Z",
  "url": "https://boards.greenhouse.io/figma/jobs/6180053004?gh_jid=6180053004",
  "requisitionId": "2578",
  "description": "Figma is growing our team of passionate creatives and builders on a mission to make design accessible to all…",
  "boardUrl": "https://job-boards.greenhouse.io/figma"
}
```

### Ready-made examples

- 🤖 [Jobs at AI companies: OpenAI, Anthropic, Perplexity and more](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/ai-company-jobs)
- 🏠 [Remote software engineering jobs at top tech companies](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/remote-software-engineer-jobs)
- 💵 [US tech jobs with salary ranges](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/us-tech-jobs-with-salary)
- 🔔 [New job alerts: only jobs posted since the last run](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/new-job-alerts)
- 🏢 [Workday jobs: NVIDIA, Salesforce, Adobe, Intel](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/workday-jobs-scraper)
- 🌿 [Greenhouse](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/greenhouse-jobs-scraper) · [Lever](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/lever-jobs-scraper) · [Ashby](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/ashby-jobs-scraper) job boards
- 📊 [Data engineering and ML jobs from the last 14 days](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/data-engineer-ml-jobs)
- 🇩🇪 [Tech jobs in Germany and Berlin](https://apify.com/sports-odds-lab/ats-jobs-scraper/examples/tech-jobs-germany-berlin)

### Speed

Greenhouse, Lever, Ashby, Recruitee, Personio, Teamtailor and Pinpoint return a whole career site in one request — OpenAI's 800+ jobs take about 3 seconds. Workday, SmartRecruiters, Workable and Breezy HR need one more request per job for the description and the exact posting date: set **Job description** to *None* when you only need the list, and filters are applied before those requests so you never wait for jobs you drop. NVIDIA's full Workday site (2,600+ jobs) is listed in under a minute. The run page shows the progress and the time left.

### Pricing

⏱️ **Free until 13 October 2026** — during the launch period you only pay Apify's platform usage, typically well under $0.01 per run.

**From 14 October 2026 you pay per job saved — platform usage included**, nothing else:

| Apify plan | Per 1,000 jobs |
|---|---|
| Free | $2.00 |
| Starter | $1.80 |
| Scale | $1.60 |
| Business and higher | $1.40 |

💡 Nothing is charged for jobs your filters drop, and with **Only new jobs** a schedule pays only for new postings — checking 50 companies every day typically costs cents. The monthly $5 credit of Apify's free plan covers about 2,500 jobs. Set a spending limit on the run for a hard cap — the Actor stops as soon as it is reached.

### FAQ

**Which companies can I scrape?** Any company whose career site runs on one of the 11 systems above — tens of thousands of companies, from startups to NVIDIA, Bosch and Ubisoft.

**Which companies are in the directory?** Companies whose job boards appear in public web archives and public job lists, plus hiring Y Combinator startups — every one checked to have open jobs. The directory is refreshed regularly; any company that is missing can simply be added by name or URL in **Companies**.

**What if a name is not found?** Paste the career page URL instead — the summary lists every input that was not found. Workday sites always need their URL, because Workday addresses contain a site name that cannot be guessed. When a name exists on two systems, the board with more open jobs wins and the log names the other one.

**Is salary always filled?** Only when the company publishes it. Structured pay fields are used first (`salarySource: "ats"`); otherwise the first clear pay range in the description is used (`salarySource: "description"`). US pay-transparency states mean most US postings have one.

**How is "remote" decided?** From the ATS's own remote / hybrid / on-site flag when it has one, otherwise from the title and locations ("Remote - US"). Jobs with no signal have `workplaceType: null`.

**Do you collect personal data?** No. Only job postings — no recruiter or hiring-manager names, emails or phone numbers.

**Which time zone?** All dates are UTC. Workday lists days only ("Posted 3 Days Ago"); with descriptions on, the exact date comes from the job page, otherwise `postedAtApproximate` is `true`.

**Where does the data come from?** From the public job board APIs and feeds that the companies' career sites use. This Actor is not affiliated with any of these vendors.

### More from Min Maxxxer

- 🏀 [NBA, NFL, MLB & NHL Odds](https://apify.com/sports-odds-lab/nba-nfl-mlb-nhl-odds) — historical and closing lines from 40+ bookmakers
- 📋 [ESPN Scraper](https://apify.com/sports-odds-lab/espn-scraper) — box scores and player stats
- 📊 [Polymarket & Kalshi Scraper](https://apify.com/sports-odds-lab/polymarket-kalshi-odds) — prediction market odds and history

⭐ **Did this Actor save you time?** A short review on this page helps others find it — and tells us which systems to add next.

### Changelog

- **0.2** — **Search all companies**: a built-in directory of 15,000+ companies searched live in minutes; Greenhouse boards are listed first and only matching jobs are opened.
- **0.1** — first release: 11 applicant tracking systems, company names or career pages detected automatically, salary ranges, remote / hybrid detection, filters, only-new-jobs mode for schedules, per-company summary, progress with time left on the run page.

# Actor input Schema

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

One company per line, in any of these forms:
• a job board URL — boards.greenhouse.io/stripe, jobs.lever.co/palantir, jobs.ashbyhq.com/openai, nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite, jobs.smartrecruiters.com/BoschGroup, apply.workable.com/…, ….recruitee.com, ….jobs.personio.de, ….teamtailor.com, ….breezy.hr, ….pinpointhq.com
• the company's own careers page or website (figma.com/careers) — the Actor finds the job board it uses
• just the name (OpenAI, Databricks, Notion) — the Actor tries it on every ATS and picks the board with most jobs
• 'ats:slug' to be explicit (greenhouse:stripe, lever:palantir, smartrecruiters:BoschGroup)
Workday sites always need their URL.
Leave it empty when you use 'Search all companies'.

## `searchAllCompanies` (type: `boolean`):

Search every company in the built-in directory — thousands of companies on Greenhouse, Lever, Ashby, Workday and more — instead of (or besides) your list. Needs at least one filter below, e.g. job title words or a location. Workday, SmartRecruiters and Workable sites are included when you give job title words.

## `directoryAts` (type: `array`):

Optional: search only the directory companies on these systems. Empty = all.

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

Keep jobs whose title contains any of these words or phrases (case-insensitive), e.g. 'data engineer', 'product manager', 'ML'. Short words like 'AI' or 'QA' match whole words only. Empty = all jobs.

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

Match the keywords in the description too, not only the title (e.g. a skill like 'Kubernetes').

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

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

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

Keep jobs in any of these places: a city, region or country ('Berlin', 'California', 'Germany', 'US', 'UK'), or 'Remote'. Matched against every location of the job. Empty = anywhere.

## `workplace` (type: `string`):

Keep only remote, hybrid or on-site jobs. Jobs whose board says nothing about it count as unknown and are dropped by this filter.

## `employmentTypes` (type: `array`):

Keep only these types. Jobs whose board does not state a type are kept.

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

Keep jobs whose department or team contains any of these, e.g. 'Engineering', 'Sales'. Jobs without a department are kept.

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

Only jobs posted in the last N days. 0 = any time. Jobs on boards that show no posting date (Pinpoint) are dropped by this filter.

## `onlyNew` (type: `boolean`):

For schedules: skip jobs that an earlier run with the same companies and filters already delivered, so you get — and pay for — new postings only. The first run returns all current jobs. The memory is kept in the key-value store 'ats-jobs-incremental' in your account.

## `incrementalName` (type: `string`):

Optional: your own name for the 'only new jobs' memory, e.g. to share it between tasks or start over with a fresh name. Empty = one memory per combination of companies and filters.

## `descriptionFormat` (type: `string`):

Plain text, HTML, both, or none. 'None' is fastest on Workday, SmartRecruiters, Workable and Breezy HR, which need one extra request per job for the description and exact posting date.

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

Newest first. 0 = no limit.

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

Stop after this many saved jobs. 0 = no limit.

## `concurrency` (type: `integer`):

How many requests run at once (up to 8 per job board and 3 boards at a time; more when searching all companies).

## Actor input object example

```json
{
  "companies": [
    "OpenAI",
    "https://jobs.lever.co/palantir",
    "greenhouse:figma"
  ],
  "searchAllCompanies": false,
  "searchInDescription": false,
  "workplace": "any",
  "postedWithinDays": 0,
  "onlyNew": false,
  "descriptionFormat": "text",
  "maxJobsPerCompany": 30,
  "maxItems": 100,
  "concurrency": 24
}
```

# Actor output Schema

## `overview` (type: `string`):

One row per open job: company, title, location, remote/hybrid, type, salary, posting date and link.

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

Full records with descriptions, all locations, apply links and requisition IDs.

## `summary` (type: `string`):

Which job board each company uses, open jobs, matched and saved counts, and any company that was not found.

# 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": [
        "OpenAI",
        "https://jobs.lever.co/palantir",
        "greenhouse:figma"
    ],
    "maxJobsPerCompany": 30,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("sports-odds-lab/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": [
        "OpenAI",
        "https://jobs.lever.co/palantir",
        "greenhouse:figma",
    ],
    "maxJobsPerCompany": 30,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("sports-odds-lab/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": [
    "OpenAI",
    "https://jobs.lever.co/palantir",
    "greenhouse:figma"
  ],
  "maxJobsPerCompany": 30,
  "maxItems": 100
}' |
apify call sports-odds-lab/ats-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sports-odds-lab/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/5NP9TkCA08xQ7BLHr/builds/VnMw36faNBPXiiOjU/openapi.json
