# Multi-ATS Career Jobs Scraper (Greenhouse, Lever, Ashby) (`kleioks/multi-ats-jobs-scraper`) Actor

Extract real-time verified job postings directly from Greenhouse, Lever, Ashby, and Workable public JSON APIs. Enriched with normalized salary data, remote status, and B2B tech stack signals.

- **URL**: https://apify.com/kleioks/multi-ats-jobs-scraper.md
- **Developed by:** [Akkouch Sofiane](https://apify.com/kleioks) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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

<div align="center">

## Multi-ATS Direct Career & Tech-Stack Intelligence API

**Real-time job postings, normalized compensation bands, and B2B technology signals extracted directly from Greenhouse, Lever, Ashby, and Workable.**

[![Apify Actor](https://img.shields.io/badge/Apify-Verified_Architecture-00C853?style=flat-square)](https://apify.com)
[![ATS Coverage](https://img.shields.io/badge/ATS-Greenhouse_%7C_Lever_%7C_Ashby_%7C_Workable-2563EB?style=flat-square)](https://apify.com)
[![Memory Footprint](https://img.shields.io/badge/Memory-256_MB_Default-0F172A?style=flat-square)](https://docs.apify.com)
[![Output Format](https://img.shields.io/badge/Output-JSON_%7C_CSV_%7C_Parquet-475569?style=flat-square)](https://docs.apify.com)

</div>

***

### Overview

Third-party job boards suffer from stale listings, reposted ghost roles, and aggressive anti-bot walls. **Multi-ATS Direct Career & Tech-Stack Intelligence API** bypasses aggregators entirely by querying the official public JSON endpoints of the four dominant Applicant Tracking Systems (**Greenhouse**, **Lever**, **Ashby**, and **Workable**).

Beyond raw job listings, the engine parses every job description to extract **normalized salary bands** and **40+ B2B software and engineering stack signals** (`Snowflake`, `Databricks`, `Kubernetes`, `Salesforce`, `HubSpot`, `LLM / GenAI`, etc.), turning hiring activity into actionable B2B buying intent.

#### Core Capabilities

| Capability | Technical Implementation | B2B Application |
| :--- | :--- | :--- |
| **Universal Target Resolution** | Accepts company slugs (`stripe`), domains (`mistral.ai`), or full ATS URLs | Query hundreds of target accounts without manually looking up which ATS they use |
| **Tech-Stack & Tool Detection** | Deterministic pattern matching across 40+ cloud, data, engineering, and GTM tools | Identify accounts actively investing in `Snowflake`, `HubSpot`, `Kubernetes`, or `GenAI` |
| **Compensation Normalization** | Reads native ATS salary objects + fallback regex parsing on job text | Benchmark competitor salary bands (`salary_min`, `salary_max`, `salary_currency`) |
| **Zero-Browser Execution** | Asynchronous `httpx` HTTP/2 requests directly against public ATS APIs | Extract 500+ roles in seconds with 256 MB RAM and zero residential proxy costs |

***

### Input Parameters

| Field | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `targets` | `string[]` | `["stripe", "palantir", "linear"]` | Company slugs, corporate domains, or direct ATS board URLs. |
| `atsPlatforms` | `string[]` | `["greenhouse", "lever", "ashby", "workable"]` | ATS platforms to probe when a generic company slug or domain is provided. |
| `keywords` | `string[]` | `[]` | Optional filter: keep only roles matching at least one keyword in title, department, or description. |
| `locations` | `string[]` | `[]` | Optional filter: keep only roles matching specific cities, countries, or `"Remote"`. |
| `remoteOnly` | `boolean` | `false` | When enabled, returns only remote-eligible positions. |
| `includeDescription` | `boolean` | `true` | Include full plain-text and HTML job descriptions in the output dataset. |
| `maxJobsPerCompany` | `integer` | `100` | Maximum jobs extracted per company (`1`–`5000`). |
| `maxTotalJobs` | `integer` | `500` | Maximum total jobs returned across the entire run (`1`–`50000`). |

#### Example Input (`INPUT.json`)

```json
{
  "targets": [
    "stripe",
    "palantir",
    "linear",
    "https://boards.greenhouse.io/cloudflare"
  ],
  "atsPlatforms": [
    "greenhouse",
    "lever",
    "ashby",
    "workable"
  ],
  "keywords": [
    "Engineer",
    "Data",
    "AI"
  ],
  "locations": [
    "Remote",
    "New York",
    "London"
  ],
  "remoteOnly": false,
  "includeDescription": true,
  "maxJobsPerCompany": 50,
  "maxTotalJobs": 500
}
```

***

### Output Dataset Schema

| Property | Type | Description |
| :--- | :--- | :--- |
| `jobTitle` | `string` | Standardized job title. |
| `companyName` | `string` | Hiring company name. |
| `location` | `string \| null` | Primary office or remote region. |
| `url` | `string` | Direct URL to the live job posting. |
| `ats_platform` | `string` | Source ATS (`greenhouse`, `lever`, `ashby`, `workable`). |
| `department` | `string \| null` | Department or business unit. |
| `workplace_type` | `string` | Normalized workplace policy (`Remote`, `Hybrid`, `On-site`, `Unspecified`). |
| `is_remote` | `boolean` | `true` if the role supports remote work. |
| `salary_min` | `number \| null` | Minimum annualized base salary when disclosed. |
| `salary_max` | `number \| null` | Maximum annualized base salary when disclosed. |
| `salary_currency` | `string \| null` | ISO currency code (`USD`, `EUR`, `GBP`). |
| `compensation_summary` | `string \| null` | Formatted compensation range string (e.g., `$180,000 - $240,000`). |
| `tech_stack` | `string[]` | Detected technologies, cloud providers, and B2B tools mentioned in the role. |
| `published_at` | `string \| null` | Original publication timestamp (ISO 8601). |
| `apply_url` | `string \| null` | Direct application submission URL. |
| `description_text` | `string \| null` | Clean plain-text job description. |

#### Sample Record

```json
{
  "jobTitle": "Senior / Staff Fullstack Engineer",
  "companyName": "Linear",
  "location": "Europe",
  "url": "https://jobs.ashbyhq.com/linear/d3bc1ced-3ce4-4086-a050-555055dbb1ff",
  "job_id": "ab_d3bc1ced-3ce4-4086-a050-555055dbb1ff",
  "ats_platform": "ashby",
  "company_slug": "linear",
  "company_name": "Linear",
  "title": "Senior / Staff Fullstack Engineer",
  "department": "Product",
  "team": "Engineering",
  "employment_type": "FullTime",
  "workplace_type": "Remote",
  "is_remote": true,
  "country": "European Union",
  "secondary_locations": [],
  "salary_min": null,
  "salary_max": null,
  "salary_currency": null,
  "salary_interval": null,
  "compensation_summary": null,
  "tech_stack": [
    "TypeScript",
    "JavaScript",
    "React",
    "Node.js",
    "GraphQL",
    "PostgreSQL",
    "Redis",
    "GCP",
    "Kubernetes",
    "LLM / GenAI"
  ],
  "published_at": "2026-10-15T20:13:45.158+00:00",
  "updated_at": "2026-10-15T20:13:45.158+00:00",
  "job_url": "https://jobs.ashbyhq.com/linear/d3bc1ced-3ce4-4086-a050-555055dbb1ff",
  "apply_url": "https://jobs.ashbyhq.com/linear/d3bc1ced-3ce4-4086-a050-555055dbb1ff/application"
}
```

***

### No-Code, Clay, n8n & AI Agent (MCP) Integrations

#### 1. Clay.com Hiring-Signal Waterfall

1. In your Clay table, click **Add Enrichment** → **Apify** → **Run Actor**.
2. Select `kleioks/multi-ats-jobs-scraper` and map your target company slugs into `targets` with `keyword_filter` set to your buyer persona (e.g., `"Security"`, `"RevOps"`, `"Data Engineer"`).
3. Map the returned `title`, `department`, `location`, and `apply_url` fields into your outbound copy to reference the exact open role in your cold email opener.

#### 2. n8n & Make.com Automated Job Signal Pipelines

- **n8n**: Use the official **Apify Node** (`Run an Actor and get dataset`) on a daily Cron schedule, followed by a **Slack** or **HubSpot** node to alert your SDR team whenever a target account opens a new technical or executive role.
- **Direct REST Webhook / Dataset Export**:
  ```
  https://api.apify.com/v2/acts/kleioks~multi-ats-jobs-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN
  ```

#### 3. Model Context Protocol (MCP) for Claude, Cursor & AI Agents

Expose this Actor directly as a live tool inside **Claude Desktop**, **Cursor**, or custom **LangChain / CrewAI** agents via the official Apify MCP server:

```json
{
  "mcpServers": {
    "apify-ats-jobs": {
      "command": "npx",
      "args": [
        "-y",
        "@apify/actors-mcp-server",
        "--actors",
        "kleioks/multi-ats-jobs-scraper"
      ],
      "env": {
        "APIFY_TOKEN": "YOUR_APIFY_API_TOKEN"
      }
    }
  }
}
```

***

### Frequently Asked Questions (FAQ)

#### How do I scrape Greenhouse, Lever, Ashby, and Workable job boards without getting blocked?

Unlike job aggregators (LinkedIn, Indeed, Glassdoor) that enforce strict login walls and residential proxy requirements, ATS platforms expose structured JSON APIs to power company career pages. This Actor queries those official JSON endpoints (`boards-api.greenhouse.io`, `api.lever.co`, `api.ashbyhq.com`, and `apply.workable.com`) directly over HTTP/2 with zero CAPTCHAs and zero proxy costs.

#### Can I use job postings as a B2B buying intent signal in Clay or Apollo?

Yes. Hiring activity is one of the highest-converting B2B intent triggers. When a company posts openings for *SOC 2 Compliance*, *Snowflake Data Engineer*, or *HubSpot Administrator*, it confirms active budget allocation and tech-stack adoption before any press release.

#### How fast is this Multi-ATS scraper compared to browser-based job scrapers?

Because it bypasses headless browsers entirely and runs on asynchronous `httpx` inside a `128 MB`–`256 MB` container, it extracts **500 to 1,500 normalized job listings in under 4 seconds**.

***

### Complete B2B Intelligence Suite by Kleioks

Combine this Actor with our specialized B2B data engines on the Apify Store to build end-to-end GTM, RevOps, and market research pipelines:

| Actor | Primary B2B Use Case | Store Link |
| :--- | :--- | :--- |
| **Multi-ATS Career Jobs API** | Track real-time hiring intent & tech-stack signals across Greenhouse, Lever, Ashby & Workable | [Open on Apify Store](https://apify.com/kleioks/multi-ats-jobs-scraper) |
| **Google Maps B2B Lead Machine** | High-speed local business lead extractor (phone, website, rating & missing-website signals) | [Open on Apify Store](https://apify.com/kleioks/google-maps-b2b-lead-machine) |
| **Reddit B2B Buying Intent Scraper** | Monitor competitor churn, software recommendations & high-intent buyer threads on Reddit | [Open on Apify Store](https://apify.com/kleioks/reddit-b2b-scraper) |
| **B2B Social Leads & Intent Extractor** | Discover SaaS founders, developers & decision-makers across Bluesky, GitHub & Hacker News | [Open on Apify Store](https://apify.com/kleioks/b2b-social-leads-scraper) |
| **Influencer & Creator Discovery API** | Extract TikTok, Instagram & YouTube creator profiles, engagement rates & verified PR emails | [Open on Apify Store](https://apify.com/kleioks/influencer-creator-discovery) |
| **Real Estate Market Intelligence API** | Normalized property listings, automated price/m² valuation, DPE ratings & agency contacts | [Open on Apify Store](https://apify.com/kleioks/real-estate-market-scraper) |

# Actor input Schema

## `targets` (type: `array`):

List of company slugs (e.g. 'stripe', 'palantir', 'linear'), company domains (e.g. 'airbnb.com', 'mistral.ai'), or direct ATS URLs (e.g. 'https://boards.greenhouse.io/cloudflare', 'https://jobs.lever.co/plaid').

## `atsPlatforms` (type: `array`):

ATS platforms to query when a company slug or domain is provided without an explicit ATS URL.

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

Only return job postings matching at least one of these keywords (case-insensitive) in title, department, or description.

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

Only return job postings matching at least one of these locations (e.g. 'Remote', 'New York', 'London', 'Paris').

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

If enabled, only returns job openings marked as Remote.

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

Include clean plain-text and HTML descriptions in each output item.

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

Maximum number of jobs to extract for each target company.

## `maxTotalJobs` (type: `integer`):

Maximum total number of job postings to return across the entire run.

## Actor input object example

```json
{
  "targets": [
    "stripe",
    "palantir",
    "linear"
  ],
  "atsPlatforms": [
    "greenhouse",
    "lever",
    "ashby",
    "workable"
  ],
  "keywords": [],
  "locations": [],
  "remoteOnly": false,
  "includeDescription": true,
  "maxJobsPerCompany": 100,
  "maxTotalJobs": 500
}
```

# Actor output Schema

## `dataset` (type: `string`):

All normalized job postings from Greenhouse, Lever, Ashby, and Workable.

# 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 = {
    "targets": [
        "stripe",
        "palantir",
        "linear"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kleioks/multi-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 = { "targets": [
        "stripe",
        "palantir",
        "linear",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("kleioks/multi-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 '{
  "targets": [
    "stripe",
    "palantir",
    "linear"
  ]
}' |
apify call kleioks/multi-ats-jobs-scraper --silent --output-dataset

```

## MCP server setup

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