# ATS Jobs Scraper — Greenhouse, Lever, Ashby, Workday & More (`actorworks/ats-jobs-scraper`) Actor

Normalized job listings from official public ATS endpoints — Greenhouse, Lever, Ashby, SmartRecruiters, Workday. One schema, per-company inputs, contact-scrubbed company-level data.

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

## Pricing

Pay per event

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?

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 Scraper — Greenhouse, Lever, Ashby, Workday & SmartRecruiters

**Scrape job listings from any company's career page — across eight major ATS platforms — into one clean, normalized JSON feed.** Give it company names; get back every open role with title, location, department, employment type, posting date, salary where published, and the full description.

| Job title | Company | ATS | Location | Compensation | Posted |
|---|---|---|---|---|---|
| Account Executive – Italy | gitlab | greenhouse | Remote, Italy | — | 2026-08-12 |
| Android Engineer – Advertising | spotify | lever | New York, NY | — | 2026-08-20 |
| Senior Fullstack Engineer | linear | ashby | Europe (Remote) | — | 2026-08-25 |
| Software Engineer – Hardware | nvidia | workday | Bengaluru, India | — | 2026-08-27 |

### Why this scraper

Most job scrapers parse career-page HTML that breaks whenever a site updates. This actor reads each ATS's **public JSON endpoints — the same data the career pages themselves load** — so results are complete, fast, and stable:

- ✅ **Eight ATS platforms, one schema** — Greenhouse, Lever, Ashby, SmartRecruiters, Workday, Recruitee, Workable, and Personio, with identical output fields across all of them
- ✅ **Official public APIs** for Greenhouse, Lever, Ashby, and SmartRecruiters — no brittle HTML parsing
- ✅ **Per-vendor isolation** — if one ATS changes, every other vendor in your run still delivers
- ✅ **Automated health checks** — every vendor adapter is exercised against live boards on a continuous schedule
- ✅ **Company-level data only** — stray recruiter emails and phone numbers are automatically scrubbed from descriptions

### What you get

One clean record per job:

```json
{
  "id": "greenhouse:gitlab:8503792002",
  "vendor": "greenhouse",
  "company": "gitlab",
  "title": "Account Executive - Italy",
  "absoluteUrl": "https://job-boards.greenhouse.io/gitlab/jobs/8503792002",
  "location": "Remote, Italy",
  "isRemote": true,
  "department": "Sales",
  "employmentType": "Full-time",
  "postedAt": "2026-08-12T09:14:02.000Z",
  "updatedAt": "2026-08-27T16:41:18.000Z",
  "compensation": "EUR 68000–102000 per year",
  "descriptionHtml": "<p>…full formatted description…</p>",
  "descriptionText": "…plain-text description…"
}
```

### How to scrape jobs from Greenhouse, Lever, Ashby, SmartRecruiters or Workday

List companies as vendor + identifier pairs, or paste career-page URLs (auto-detected):

```json
{
  "sources": [
    { "vendor": "greenhouse", "company": "gitlab" },
    { "vendor": "lever", "company": "spotify" },
    { "vendor": "ashby", "company": "linear" },
    { "vendor": "smartrecruiters", "company": "Devoteam" },
    { "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite" },
    { "url": "https://jobs.lever.co/anthropic" }
  ],
  "maxJobsPerSource": 500,
  "includeDescription": true
}
```

**Finding the identifier:** it's the slug in the company's career-page URL — `boards.greenhouse.io/{company}`, `jobs.lever.co/{company}`, `jobs.ashbyhq.com/{company}`, `careers.smartrecruiters.com/{Company}`. For Workday, pass the full careers URL.

### ATS coverage

| ATS | Endpoint type | Descriptions | Salary data | Notes |
|---|---|---|---|---|
| Greenhouse | Official public API | ✅ Full HTML + text | Where published | Single-call, all jobs |
| Lever | Official public API | ✅ Full HTML + text | ✅ Salary ranges where published | Remote/hybrid/onsite normalized |
| Ashby | Official public API | ✅ Full HTML + text | ✅ Structured compensation tiers | Multi-location support |
| SmartRecruiters | Official public API | ✅ Per-posting job ad | Where published | Department + employment type |
| Workday | Public career-site endpoints | ✅ Per-posting detail | Where published | Unofficial endpoints — repaired fast when they shift |
| Recruitee | Official public API | ✅ Full HTML + text | Where published | Description + requirements |
| Workable | Public widget API | ✅ Full HTML + text | Where published | Widget endpoint — repaired fast when it shifts |
| Personio | Official public XML feed | ✅ Per-position sections | Where published | EU-heavy install base |

Next up on the roadmap: Teamtailor, BambooHR, Jobvite. Need one sooner? Open an issue.

### Pricing

Pay only for results: **about $1.20 per 1,000 jobs** ($0.0012 per job + a fractional start fee) — less on paid Apify plans (down to $0.80/1,000 on higher tiers). No subscription, no minimum. Scraping 20 companies with ~2,000 total openings costs roughly **$2.50**.

### This actor vs the alternatives

| | This actor | Single-ATS scrapers | HTML-based job scrapers |
|---|---|---|---|
| ATS platforms in one run | **8** | 1 | varies |
| Workday + SmartRecruiters coverage | ✅ | rarely | rarely |
| Breaks when career-page design changes | No — JSON endpoints | No | Yes |
| Identical schema across vendors | ✅ | n/a | ✗ |
| Contact-scrubbed output | ✅ | ✗ | ✗ |
| Continuous automated health checks | ✅ | varies | varies |

Only need one ATS? We also publish focused single-vendor actors — see the family list below; same schema, same engine.

### Use cases

- **Job boards & aggregators** — fresh postings straight from the source, no stale intermediary feeds
- **Talent & labor-market intelligence** — track hiring by company, function, or location over time
- **Competitor hiring monitoring** — see who's scaling which teams, where, this week
- **Recruiting & staffing research** — full descriptions with salary data where companies publish it
- **AI agents & RAG pipelines** — normalized JSON via API and MCP; this actor supports agentic payments, so AI agents can call and pay for it directly

### Integrations

Run on a schedule with **Apify Schedules**; pipe results anywhere with **webhooks** or the **Apify API** — Google Sheets, n8n, Make, Zapier, LangChain, or your own database. AI agents can discover and run this actor through the **Apify MCP server**.

### FAQ

**How fresh is the data?** Live — every run reads each company's current public listings at that moment.

**How many companies can I scrape in one run?** Hundreds. Sources run concurrently with per-source isolation, so one failing company never blocks the rest.

**Do I get full job descriptions?** Yes — formatted HTML and plain text, unless you set `includeDescription: false` for a faster, lighter run.

**Does it include salaries?** Wherever the company publishes them: Lever salary ranges, Ashby compensation tiers, and pay data embedded by Greenhouse/SmartRecruiters/Workday employers.

**Can it monitor for new jobs?** Yes — schedule it hourly or daily and diff against your previous dataset, or trigger webhooks on each run.

**Is this legal and ethical?** The actor reads public, logged-out job-board data — exactly what each company chooses to publish to attract applicants — via official or public endpoints, with no login, no circumvention. Recruiter contact details embedded in descriptions are automatically removed; output is company-level data only.

**Why did a Workday or Workable company return fewer fields?** Workday and Workable are the two vendors without officially documented public APIs; we use the same public endpoints their career sites load, and repair fast when they shift. The other six vendors are official public APIs.

**A company I need doesn't work?** Check the identifier matches the career-page URL slug. Still stuck? **Open an issue on this actor — it goes straight to the maintainer.**

### More data actors from ActorWorks

**Jobs & hiring**

- [ATS Jobs Scraper](https://apify.com/actorworks/ats-jobs-scraper) — 8 ATS platforms in one run
- [Ashby](https://apify.com/actorworks/ashby-jobs-scraper) · [Lever](https://apify.com/actorworks/lever-jobs-scraper) · [SmartRecruiters](https://apify.com/actorworks/smartrecruiters-jobs-scraper) · [Recruitee](https://apify.com/actorworks/recruitee-jobs-scraper) · [Workable](https://apify.com/actorworks/workable-jobs-scraper) · [Personio](https://apify.com/actorworks/personio-jobs-scraper) — single-vendor versions
- [Remote Jobs Scraper](https://apify.com/actorworks/remote-jobs-aggregator) — six remote-job boards in one feed

**Web & market intelligence**

*Greenhouse, Lever, Ashby, SmartRecruiters, Workday and all company names are trademarks of their respective owners. This actor is an independent tool and is not affiliated with or endorsed by any of them.*

# Actor input Schema

## `sources` (type: `array`):

Companies to fetch jobs from. Each entry is either a career-page URL (auto-detected) or an object like {"vendor": "greenhouse", "company": "gitlab"}. Supported vendors: greenhouse, lever, ashby, smartrecruiters, workday, recruitee, workable, personio (for Workday pass the full careers URL).

## `maxJobsPerSource` (type: `integer`):

Cap on jobs fetched per company (protects your budget on large boards).

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

Fetch full job descriptions (HTML + plain text). Turn off for a faster, lighter run with listing fields only.

## Actor input object example

```json
{
  "sources": [
    {
      "vendor": "greenhouse",
      "company": "gitlab"
    },
    {
      "vendor": "lever",
      "company": "spotify"
    },
    {
      "vendor": "ashby",
      "company": "linear"
    },
    {
      "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    }
  ],
  "maxJobsPerSource": 500,
  "includeDescription": true
}
```

# Actor output Schema

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

The scraped job listings.

# 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 = {
    "sources": [
        {
            "vendor": "greenhouse",
            "company": "gitlab"
        },
        {
            "vendor": "lever",
            "company": "spotify"
        },
        {
            "vendor": "ashby",
            "company": "linear"
        },
        {
            "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("actorworks/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 = { "sources": [
        {
            "vendor": "greenhouse",
            "company": "gitlab",
        },
        {
            "vendor": "lever",
            "company": "spotify",
        },
        {
            "vendor": "ashby",
            "company": "linear",
        },
        { "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite" },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("actorworks/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 '{
  "sources": [
    {
      "vendor": "greenhouse",
      "company": "gitlab"
    },
    {
      "vendor": "lever",
      "company": "spotify"
    },
    {
      "vendor": "ashby",
      "company": "linear"
    },
    {
      "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    }
  ]
}' |
apify call actorworks/ats-jobs-scraper --silent --output-dataset

```

## MCP server setup

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