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

ATS Jobs Scraper - Greenhouse, Lever, Ashby

- **URL**: https://apify.com/martin10291/ats-jobs-aggregator.md
- **Developed by:** [Martin Petrov](https://apify.com/martin10291) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 results

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?

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

Collect job postings straight from the public job-board APIs of **Greenhouse, Lever, Ashby, Workable and SmartRecruiters**: thousands of tech companies and startups, one clean schema. Get title, department, location, remote flag, employment type, **salary range**, posting date, apply link and full description for every open role.

Because the actor uses the official public job-board APIs instead of scraping protected pages, it is **fast, cheap and reliable**: no login, no CAPTCHAs, no browser.

### Why use it

- **5 ATS platforms in one actor.** Mix Greenhouse, Lever, Ashby, Workable and SmartRecruiters companies in a single run.
- **Normalized output.** Every platform returns the same fields, so your spreadsheet, database or pipeline works without per-platform code.
- **Salary data.** Structured salary ranges from Lever and Ashby, and salary ranges detected in the text for other platforms (USD, EUR, GBP).
- **Smart filters.** Title keywords, excluded words, locations, remote only, departments, posted within N days, minimum salary.
- **Only new jobs mode.** Schedule the actor daily and get only jobs that appeared since the last run. Perfect for alerts.
- **Auto-detection.** Paste a job-board URL or just a company slug; the actor finds which ATS the company uses.

### Use cases

- **Job seekers and job boards**: aggregate openings from target companies
- **Recruiters and agencies**: track hiring at clients and prospects
- **Sales and lead generation**: find companies hiring for a role as a buying signal
- **Market research**: analyze hiring trends, salaries and remote work by company
- **Investors**: monitor team growth at portfolio and competitor companies

### Input

| Field | Type | Description |
|---|---|---|
| `companies` | array | Job-board URLs, `ats:slug` (e.g. `greenhouse:stripe`) or a company slug. **Required.** |
| `titleKeywords` | array | Keep jobs whose title contains any of these words. |
| `excludeKeywords` | array | Drop jobs whose title contains any of these words. |
| `locations` | array | Keep jobs whose location contains any of these. |
| `includeRemoteWithLocations` | boolean | Keep remote jobs when filtering by location. Default `true`. |
| `remoteOnly` | boolean | Only remote jobs. Default `false`. |
| `departments` | array | Keep jobs in these departments or teams. |
| `postedWithinDays` | integer | Only jobs posted in the last N days. `0` = any date. |
| `minSalary` | integer | Only jobs whose listed salary reaches this amount. |
| `onlyNewJobs` | boolean | Return only jobs not seen in previous runs. Default `false`. |
| `includeDescription` | boolean | Include the plain-text description. Default `true`. |
| `maxJobsPerCompany` | integer | Limit jobs saved from each company. `0` = no limit. |
| `maxItems` | integer | Hard limit on jobs saved (and paid for). |

#### Supported company inputs

| ATS | Example |
|---|---|
| Greenhouse | `https://boards.greenhouse.io/stripe` or `greenhouse:stripe` |
| Lever | `https://jobs.lever.co/palantir` or `lever:palantir` |
| Ashby | `https://jobs.ashbyhq.com/ramp` or `ashby:ramp` |
| Workable | `https://apply.workable.com/company` or `workable:company` |
| SmartRecruiters | `https://jobs.smartrecruiters.com/Company` or `smartrecruiters:Company` |

#### Example input

```json
{
  "companies": ["greenhouse:stripe", "lever:palantir", "https://jobs.ashbyhq.com/ramp"],
  "titleKeywords": ["engineer"],
  "remoteOnly": false,
  "postedWithinDays": 30,
  "onlyNewJobs": false
}
```

### Output

One row per job:

```json
{
  "id": "ashby:ramp:7f3c...",
  "ats": "ashby",
  "company": "Ramp",
  "title": "Software Engineer, Backend",
  "department": "Engineering",
  "location": "New York, NY",
  "locations": ["New York, NY"],
  "isRemote": false,
  "workplaceType": "hybrid",
  "employmentType": "FullTime",
  "salaryMin": 150000,
  "salaryMax": 210000,
  "salaryCurrency": "USD",
  "salaryInterval": "year",
  "postedAt": "2026-10-20T00:00:00Z",
  "url": "https://jobs.ashbyhq.com/ramp/...",
  "description": "About the role ...",
  "scrapedAt": "2026-10-26T14:00:00Z"
}
```

*Values above are illustrative.* The `RUN_SUMMARY` record lists every company with the number of open and saved jobs.

### Pricing

Pay per job saved. Filters are applied before saving, so you never pay for jobs you filtered out. Companies whose job board cannot be found cost nothing.

### FAQ

**Which companies are supported?** Any company that hosts its careers page on Greenhouse, Lever, Ashby, Workable or SmartRecruiters, which covers a large share of tech companies and startups.

**Does it cover Indeed or LinkedIn?** No. It reads company job boards directly, which gives fresher and more complete data for those companies.

**How does "only new jobs" work?** The actor remembers job IDs per company list in a key-value store in your account and skips them in later runs.

### More Actors by Martin Petrov

Pair with **Remote Jobs Scraper** to cover both company career pages and remote job boards.

- **[Remote Jobs Scraper (8 Job Boards)](https://apify.com/martin10291/remote-jobs-aggregator-pro)**: Remote jobs from RemoteOK, Remotive, We Work Remotely, HN Who is Hiring and more, deduplicated.
- **[Google Trends Scraper](https://apify.com/martin10291/google-trends-explorer)**: Interest over time, regions and related queries for many keywords, compared on one scale.
- **[YouTube Transcript & Subtitles Scraper](https://apify.com/martin10291/youtube-transcript-bulk-extractor)**: Transcripts from videos, playlists and whole channels, any language, with translation.
- **[YouTube Channel Monitor (New Videos & Shorts)](https://apify.com/martin10291/youtube-channel-monitor)**: Only new videos, Shorts and streams from many channels, with exact date, views and likes.
- **[Reddit Scraper (Posts, Comments & Search)](https://apify.com/martin10291/reddit-posts-comments-extractor)**: Posts and comments from subreddits, search and users, with an only-new mode for brand monitoring.
- **[Local Business Leads Finder (Emails, Phones)](https://apify.com/martin10291/local-business-leads-osm)**: Local businesses by category and city with company emails, phones and websites, MX-checked.

### Legal

This actor reads publicly available job postings from the official public job-board APIs. It does not log in or collect personal data of candidates. Use the data in line with the terms of each platform and applicable law.

# Actor input Schema

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

One per line: a job-board URL (boards.greenhouse.io/stripe, jobs.lever.co/palantir, jobs.ashbyhq.com/ramp, apply.workable.com/x, jobs.smartrecruiters.com/x), 'ats:slug' (greenhouse:stripe) or just a company slug (auto-detected).

## `titleKeywords` (type: `array`):

Keep only jobs whose title contains any of these words (e.g. engineer, sales). Empty = all jobs.

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

Drop jobs whose title contains any of these words (e.g. senior, intern).

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

Keep jobs whose location contains any of these (e.g. London, Germany, New York).

## `includeRemoteWithLocations` (type: `boolean`):

When a location filter is set, still include remote jobs.

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

Keep only remote jobs.

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

Keep jobs whose department or team contains any of these (e.g. Engineering, Marketing).

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

Keep only jobs posted in the last N days. 0 = any date.

## `minSalary` (type: `integer`):

Keep jobs whose maximum listed salary is at least this amount (jobs without salary are dropped). 0 = no filter.

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

Remember jobs from previous runs with the same company list and return only new ones. Ideal for scheduled monitoring.

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

Add the full plain-text job description.

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

Limit jobs saved from each company. 0 = no limit.

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

Hard limit on jobs saved (and paid for).

## Actor input object example

```json
{
  "companies": [
    "greenhouse:stripe",
    "lever:palantir",
    "ashby:ramp"
  ],
  "includeRemoteWithLocations": true,
  "remoteOnly": false,
  "postedWithinDays": 0,
  "minSalary": 0,
  "onlyNewJobs": false,
  "includeDescription": true,
  "maxJobsPerCompany": 5,
  "maxItems": 50
}
```

# Actor output Schema

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

One row per job in a normalized schema.

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

Jobs found and saved per company.

# 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": [
        "greenhouse:stripe",
        "lever:palantir",
        "ashby:ramp"
    ],
    "maxJobsPerCompany": 5,
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("martin10291/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 = {
    "companies": [
        "greenhouse:stripe",
        "lever:palantir",
        "ashby:ramp",
    ],
    "maxJobsPerCompany": 5,
    "maxItems": 50,
}

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

```

## MCP server setup

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