# ATS Jobs Scraper (Greenhouse, Lever, Ashby) (`themineworks/ats-jobs`) Actor

Scrape job listings directly from Greenhouse, Lever and Ashby employer ATS boards. Clean structured data, no anti-bot. Pay only per job returned.

- **URL**: https://apify.com/themineworks/ats-jobs.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Jobs, Lead generation, Developer tools
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, NaN 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/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Job Boards

Scrape job listings directly from employer ATS systems — no anti-bot fight, no consumer-board flakiness. Get clean structured job data from any company using Greenhouse, Lever, or Ashby.

Point the actor at a list of company slugs (`stripe`, `spotify`, `discord`, …), it auto-detects which ATS each company runs on, fetches every open role, and returns a unified schema across all three providers. Pay only for jobs returned — failed lookups and filtered-out jobs are free.

### Why scrape ATS boards instead of Indeed/LinkedIn

Job aggregators like Indeed, LinkedIn, Glassdoor and ZipRecruiter all sit downstream of the employer's real source of truth — the ATS (applicant tracking system) the company actually publishes openings into. There are four reasons to skip the aggregator and go straight to the source:

- **Employer-owned data, not scraped from a scrape.** Greenhouse, Lever and Ashby publish official, employer-controlled job boards. The data you pull is what the company itself shows on `jobs.company.com`. No middleman, no missing fields, no aggregator-mangled descriptions.
- **No anti-bot wall.** These ATS providers expose public read-only JSON APIs intended for embedding company career sites. There is no CAPTCHA, no fingerprinting, no IP block — clean HTTP gets clean JSON back.
- **Cleaner schema out of the box.** Job ID, title, department, location, employment type, posting date, full HTML and plain-text description, canonical apply URL. None of the “Apply on LinkedIn / Apply on company site” redirect chains.
- **Freshness.** ATS feeds update the moment the recruiter opens or closes a req. Aggregators lag by hours to days, and many never remove closed roles.

If your use case depends on knowing **what a specific list of companies is hiring for, right now**, ATS scraping beats aggregator scraping on every axis — accuracy, freshness, completeness, and cost.

### Supported sources

- **Greenhouse** — the largest enterprise ATS. Used by Discord, Stripe, OpenAI, Airbnb, Anthropic, Coinbase, Robinhood, Pinterest, Reddit, Squarespace, DoorDash, Instacart, Notion, and thousands of mid-to-late-stage companies. API: `boards-api.greenhouse.io`.
- **Lever** — popular with growth-stage SaaS and consumer companies. Used by Spotify, Netflix, Figma, Box, KAYAK, Quora, Eventbrite, Mixpanel, Cruise. API: `api.lever.co`.
- **Ashby** — newer ATS that has become the default among Y Combinator startups and modern Series A–C SaaS companies. Used by HackerOne, Linear, Vanta, Modal, Ramp, Mercury, and a long list of YC alumni. API: `api.ashbyhq.com`.

The actor tries Greenhouse → Lever → Ashby in order for any slug you provide and uses the first one that returns jobs. You can also skip auto-detect by supplying explicit `boards` entries.

### Use cases

- **Sales intelligence.** Track which companies in your ICP are hiring, what roles they’re hiring for, and how their team is growing month over month. A spike in “VP of Sales” or “Director of Demand Gen” postings is a buying signal for half of B2B SaaS.
- **Recruiting agencies.** Build a real-time pipeline of active openings across your target accounts. Map roles → candidates from your bench. Trigger outreach automations the moment a relevant role goes live.
- **Investors and equity research.** Headcount growth and the composition of new hires are leading indicators of execution. Pull weekly snapshots of every portfolio (or watchlist) company’s ATS and chart hiring velocity by department.
- **Job aggregators and niche boards.** Build a “jobs at YC companies,” “climate-tech jobs,” or “AI infra jobs” board cheaply, with first-party data instead of scraping ten consumer aggregators.
- **Competitive intelligence.** What is your competitor hiring for? Infra rebuild, new product line, international expansion — it’s all visible in the job titles and descriptions.
- **Workforce / labor-market research.** Compare hiring composition (engineering vs sales vs ops) across cohorts of companies, regions, or funding stages.

### Input

```json
{
  "companies": ["stripe", "spotify", "discord"],
  "boards": [
    { "ats": "ashby", "slug": "linear" },
    { "ats": "greenhouse", "slug": "openai" }
  ],
  "maxJobsPerCompany": 500,
  "includeDescription": false,
  "locationFilter": "New York",
  "departmentFilter": "Engineering",
  "remoteOnly": false
}
````

- `companies` — list of slugs. The actor auto-detects which ATS each one uses (Greenhouse → Lever → Ashby).
- `boards` — explicit `{ats, slug}` entries. Use this when you already know which ATS a company is on; it skips auto-detect calls.
- `maxJobsPerCompany` — hard cap per company (default 500, max 2000). Fetching stops as soon as the cap is hit.
- `includeDescription` — when false (default), `description` is truncated to 500 characters and the raw HTML field is omitted. When true, you get the full plain text and the original `description_html`.
- `locationFilter`, `departmentFilter` — case-insensitive substring matches.
- `remoteOnly` — only return jobs whose location or title contains “remote”.

You must provide at least one of `companies` or `boards`. Empty input fails fast — you’re never charged for a no-op run.

### Output

Every successful job becomes one dataset item with this schema:

```json
{
  "ats": "greenhouse",
  "company_slug": "stripe",
  "job_id": "4567890",
  "title": "Senior Software Engineer, Payments",
  "location": "New York, NY",
  "department": "Engineering",
  "employment_type": "full-time",
  "remote": false,
  "url": "https://boards.greenhouse.io/stripe/jobs/4567890",
  "description": "Stripe builds economic infrastructure for the internet…",
  "posted_at": "2026-05-20T14:30:00Z",
  "updated_at": "2026-05-28T09:12:00Z",
  "scraped_at": "2026-06-08T12:00:00Z"
}
```

When `includeDescription: true`, an extra `description_html` field is included with the raw HTML.

A final `summary` item is always pushed:

```json
{
  "_type": "summary",
  "companies_attempted": 5,
  "companies_succeeded": 4,
  "companies_failed": 1,
  "jobs_scraped": 312,
  "jobs_filtered_out": 47,
  "charged_for": 312,
  "by_ats": { "greenhouse": 210, "lever": 60, "ashby": 42 },
  "scraped_at": "2026-06-08T12:00:00Z"
}
```

Companies that don’t resolve on any of the three ATSes appear as `{_type: "error", company, reason}` items.

### Pricing

**Your first 25 jobs are free — every Apify account, no card, no trial clock.** After that it is a flat **$0.002 per job** ($2 per 1,000), far below the premium ATS feeds charging $0.012/job.

- First 25 jobs free per account (lifetime), then $0.002/job
- You are never charged for a company that returned no results.
- You are never charged for jobs filtered out by `locationFilter`, `departmentFilter` or `remoteOnly`.
- You are never charged for failed HTTP calls, 429s, or unknown ATSes.

A run that hits 0 jobs ends with `Actor.fail` and zero PPE events charged.

### How to find a company’s board

If you’re not sure which ATS a company uses, the URL of their public career page is the giveaway:

- **Greenhouse.** Either `boards.greenhouse.io/<slug>` or a custom domain like `jobs.<company>.com` that proxies Greenhouse. View source on the careers page and search for `greenhouse.io`. The slug is the last URL segment on `boards.greenhouse.io/<slug>`.
- **Lever.** `jobs.lever.co/<slug>`. Slug is the last URL segment.
- **Ashby.** `jobs.ashbyhq.com/<slug>` or `<slug>.ashbyhq.com`.

If you don’t know, just pass the company name as a slug under `companies` — the actor will probe all three and use whichever responds.

***

**Keywords:** ATS scraper, Greenhouse jobs scraper, Lever postings API, Ashby jobs API, company hiring data, job board API, sales intelligence jobs feed, recruiting data API, candidate pipeline data, hiring signals, B2B sales triggers, headcount growth tracking, YC startup jobs.

# Actor input Schema

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

List of company slugs. The actor tries Greenhouse → Lever → Ashby in order and uses the first one that returns jobs. Use this when you don't know which ATS a company is on.

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

Explicit board specs in the form {ats: 'greenhouse'|'lever'|'ashby', slug: 'stripe'}. Use this when you already know each company's ATS — it skips auto-detect calls.

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

Hard cap on jobs returned for any single company. Stops fetching once reached, even if more jobs/pages exist.

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

If true, return the full job description (plain text + raw HTML). If false, plain text is truncated to 500 characters and `description_html` is omitted.

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

Only return jobs whose location contains this substring (case-insensitive). Leave blank for no filter.

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

Only return jobs whose department contains this substring (case-insensitive). Leave blank for no filter.

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

If true, only return jobs whose location or title contains 'remote' (case-insensitive).

## Actor input object example

```json
{
  "companies": [
    "stripe",
    "spotify",
    "discord"
  ],
  "boards": [],
  "maxJobsPerCompany": 500,
  "includeDescription": false,
  "remoteOnly": false
}
```

# 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": [
        "stripe",
        "spotify",
        "discord"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/ats-jobs").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": [
        "stripe",
        "spotify",
        "discord",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("themineworks/ats-jobs").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "stripe",
    "spotify",
    "discord"
  ]
}' |
apify call themineworks/ats-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=themineworks/ats-jobs",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "ATS Jobs Scraper (Greenhouse, Lever, Ashby)",
        "description": "Scrape job listings directly from Greenhouse, Lever and Ashby employer ATS boards. Clean structured data, no anti-bot. Pay only per job returned.",
        "version": "0.1",
        "x-build-id": "nhbegpKKKkixs26Dl"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/themineworks~ats-jobs/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-themineworks-ats-jobs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/themineworks~ats-jobs/runs": {
            "post": {
                "operationId": "runs-sync-themineworks-ats-jobs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/themineworks~ats-jobs/run-sync": {
            "post": {
                "operationId": "run-sync-themineworks-ats-jobs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "companies": {
                        "title": "Company slugs (auto-detect ATS)",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "List of company slugs. The actor tries Greenhouse → Lever → Ashby in order and uses the first one that returns jobs. Use this when you don't know which ATS a company is on.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "boards": {
                        "title": "Explicit boards",
                        "type": "array",
                        "description": "Explicit board specs in the form {ats: 'greenhouse'|'lever'|'ashby', slug: 'stripe'}. Use this when you already know each company's ATS — it skips auto-detect calls.",
                        "default": []
                    },
                    "maxJobsPerCompany": {
                        "title": "Max jobs per company",
                        "minimum": 1,
                        "maximum": 2000,
                        "type": "integer",
                        "description": "Hard cap on jobs returned for any single company. Stops fetching once reached, even if more jobs/pages exist.",
                        "default": 500
                    },
                    "includeDescription": {
                        "title": "Include full job description",
                        "type": "boolean",
                        "description": "If true, return the full job description (plain text + raw HTML). If false, plain text is truncated to 500 characters and `description_html` is omitted.",
                        "default": false
                    },
                    "locationFilter": {
                        "title": "Location filter (substring, case-insensitive)",
                        "type": "string",
                        "description": "Only return jobs whose location contains this substring (case-insensitive). Leave blank for no filter."
                    },
                    "departmentFilter": {
                        "title": "Department filter (substring, case-insensitive)",
                        "type": "string",
                        "description": "Only return jobs whose department contains this substring (case-insensitive). Leave blank for no filter."
                    },
                    "remoteOnly": {
                        "title": "Remote only",
                        "type": "boolean",
                        "description": "If true, only return jobs whose location or title contains 'remote' (case-insensitive).",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
