# Workday, Greenhouse & Lever Jobs Scraper - 6 ATS (`sbr35/ats-jobs-aggregator`) Actor

Search live jobs across 789 verified company boards on Workday, Greenhouse, Lever, Ashby, SmartRecruiters and Workable - no company slugs needed. Filter by keyword, location, department, remote and date. Includes Workday, which the other ATS scrapers do not cover.

- **URL**: https://apify.com/sbr35/ats-jobs-aggregator.md
- **Developed by:** [Alexandre de La Fayette](https://apify.com/sbr35) (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

from $2.00 / 1,000 job listings

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?

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

## ATS Jobs Aggregator

Pull job listings from **five applicant tracking systems** in a single run and get back one
clean, normalised table.

Most companies publish their open roles through an ATS — Greenhouse, Lever, Ashby, Workable or
SmartRecruiters. Each one exposes a different shape of data at a different URL. This Actor reads
all five and returns identical fields for every job, whatever system it came from.

### What you get

One row per job, with the same fields every time:

| Field | Description |
|---|---|
| `title` | Job title |
| `company` | Company slug you supplied |
| `platform` | Which ATS it came from |
| `location` | Location string as published |
| `department` | Team or department |
| `employmentType` | Full-time, contract, etc. where the ATS provides it |
| `remote` | Boolean, inferred from location and workplace type |
| `url` | Direct link to the posting |
| `postedAt` | ISO 8601 timestamp |
| `scrapedAt` | When this row was collected |

### Input

Give it a list of boards in the form `platform:slug`:

```json
{
  "boards": [
    "greenhouse:stripe",
    "lever:palantir",
    "ashby:ramp",
    "workable:blueground",
    "smartrecruiters:SmartRecruiters"
  ],
  "keywords": ["engineer", "designer"],
  "locationFilter": "Remote",
  "maxJobsPerBoard": 500
}
```

| Option | Default | What it does |
|---|---|---|
| `boards` | required | One entry per company board |
| `keywords` | empty | Keep only titles containing one of these (case-insensitive) |
| `locationFilter` | empty | Keep only locations containing this text |
| `maxJobsPerBoard` | 500 | Safety cap per board |

#### Finding a company's slug

Look at their careers page URL:

| URL you see | Entry to use |
|---|---|
| `boards.greenhouse.io/stripe` | `greenhouse:stripe` |
| `jobs.lever.co/palantir` | `lever:palantir` |
| `jobs.ashbyhq.com/ramp` | `ashby:ramp` |
| `apply.workable.com/blueground` | `workable:blueground` |
| `jobs.smartrecruiters.com/Acme` | `smartrecruiters:Acme` |

Unknown platforms and bad slugs are skipped with a warning — one bad entry never fails the run.

### Who this is for

- **Recruiting agencies** tracking which companies are hiring, and for what
- **Job boards** sourcing listings across many employers
- **Sales teams** using hiring activity as a buying signal (a company hiring five sales reps is expanding)
- **Market researchers** measuring headcount growth by function
- **Anyone** who wants one schema instead of five

### Pricing

Pay per event. You are charged only for job rows actually delivered — a board that returns
nothing costs nothing.

### Where the data comes from

Every endpoint used is public, unauthenticated, and published by the ATS vendor specifically so
job boards and aggregators can consume it. This Actor:

- reads only public job-board APIs
- bypasses no login and solves no CAPTCHA
- collects no personal data — job postings only, never applicants

### Notes and limits

- A board returning zero jobs usually means the slug is wrong, or the company has no open roles.
- `employmentType` is only populated where the ATS supplies it; Greenhouse frequently omits it.
- SmartRecruiters paginates in 100s and is fetched to a 1,000-job ceiling per board.
- Field availability varies by platform. Every row always has `title`, `url`, `company` and `platform`.

### Changelog

**1.0** — First release. Greenhouse, Lever, Ashby, Workable and SmartRecruiters.

# Actor input Schema

## `boards` (type: `array`):

OPTIONAL. Leave empty to search across every company in the bundled index (789 verified boards, 57,000+ live jobs). Supply entries like "greenhouse:stripe" or "lever:palantir" only if you want specific companies.

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

Only keep jobs whose title contains one of these, e.g. "engineer", "designer". Leave empty for all roles.

## `locationFilter` (type: `string`):

Only keep jobs whose location contains this text, e.g. "Toronto", "Remote", "London".

## `maxJobsPerBoard` (type: `integer`):

Cap per company, so one huge employer cannot dominate the results.

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

Only return roles the company has flagged as remote.

## `departmentFilter` (type: `string`):

Only keep jobs whose department contains this text, e.g. "Engineering", "Sales".

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

ISO date, e.g. 2026-08-01. Only keep jobs posted on or after it.

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

Hard cap on how many jobs the run returns, and therefore what it costs you.

## `maxCompanies` (type: `integer`):

How many indexed companies to search, largest employers first. Raise for wider coverage.

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

How many company boards to fetch at once. 12 is a good balance of speed and politeness.

## Actor input object example

```json
{
  "boards": [
    "greenhouse:stripe"
  ],
  "keywords": [],
  "maxJobsPerBoard": 500,
  "remoteOnly": false,
  "maxJobs": 1000,
  "maxCompanies": 150,
  "concurrency": 12
}
```

# Actor output Schema

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

Every job found, with identical fields regardless of which ATS it came from.

## `jobsCsv` (type: `string`):

The same listings as a spreadsheet-ready CSV.

## `runSummary` (type: `string`):

Which boards succeeded, which failed, and how many jobs each returned.

# 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 = {
    "boards": [
        "greenhouse:stripe",
        "lever:palantir",
        "ashby:ramp"
    ],
    "keywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("sbr35/ats-jobs-aggregator").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 = {
    "boards": [
        "greenhouse:stripe",
        "lever:palantir",
        "ashby:ramp",
    ],
    "keywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("sbr35/ats-jobs-aggregator").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 '{
  "boards": [
    "greenhouse:stripe",
    "lever:palantir",
    "ashby:ramp"
  ],
  "keywords": []
}' |
apify call sbr35/ats-jobs-aggregator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sbr35/ats-jobs-aggregator"
        }
    }
}

```

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/ClEkTcFe4y5aPGirF/builds/nd0v3uQalvmrLZgnN/openapi.json
