# ATS Jobs Feed: Greenhouse, Lever, Ashby jobs API (`opendata-feeds/multi-ats-jobs-feed`) Actor

Every open job from any company on Greenhouse, Lever or Ashby, from their official public job-board APIs, in one clean schema. Salary where published, remote flag, only-new mode for daily monitoring. $1 per 1,000 jobs.

- **URL**: https://apify.com/opendata-feeds/multi-ats-jobs-feed.md
- **Developed by:** [OpenData Feeds](https://apify.com/opendata-feeds) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 job delivereds

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 Feed: every open job from Greenhouse, Lever and Ashby

Give it a list of companies. Get back every open job they have published, in **one clean schema**, no matter which applicant tracking system (ATS) each company uses.

- **3 ATS in one Actor:** Greenhouse, Lever and Ashby. Paste a careers-page URL, or just the company's slug and the Actor finds its board.
- **Official public APIs only.** The Actor reads the same public job-board endpoints that power each company's own careers page. No HTML scraping, no browser, no proxies, so runs take seconds and don't break when a page is redesigned.
- **Salary where the company publishes it** (min, max, currency, interval), a **remote** flag, departments, all locations, posted date, and apply link.
- **Only-new mode for monitoring.** Schedule it daily, and it returns (and charges for) only jobs it hasn't delivered before.
- **$1.00 per 1,000 jobs.** You pay only for jobs delivered. Jobs removed by your filters, or skipped as already seen, cost nothing.

#### Who uses it

- **Recruiting and staffing agencies** watching target companies for new openings.
- **Sales teams** using hiring as a buying signal ("they just opened 6 data-engineering roles").
- **Job boards and newsletters** that aggregate niche roles (remote, AI, climate, a city).
- **Analysts** tracking hiring trends at a set of companies.

#### Input

| Field | What it does |
|---|---|
| `companies` (required) | Careers URLs (`https://jobs.lever.co/acme`, `https://job-boards.greenhouse.io/acme`, `https://jobs.ashbyhq.com/acme`), `ats:slug` (`greenhouse:acme`), or a bare slug to auto-detect. |
| `titleKeywords` | Keep jobs whose title contains any of these words. |
| `locationKeywords` | Keep jobs with a location containing any of these (`Remote`, `Berlin`, `Canada`). |
| `remoteOnly` | Keep only remote jobs. |
| `postedWithinDays` | Keep only jobs first published in the last N days. |
| `onlyNew` + `stateKey` | Return only jobs not delivered by an earlier run of the same monitor. |
| `includeDescription` | Plain-text description (on by default). Email addresses, phone numbers, LinkedIn profile links and contact persons' names are removed. |
| `maxJobsPerCompany` | Cap per company. 0 = no cap. |

Example:

```json
{
  "companies": ["https://jobs.lever.co/acme-robotics", "greenhouse:example-labs", "northwind"],
  "titleKeywords": ["engineer", "data"],
  "remoteOnly": true,
  "onlyNew": true,
  "stateKey": "remote-eng-watch"
}
```

#### Output

One item per job. Example (fictional company):

```json
{
  "ats": "ashby",
  "companySlug": "acme-robotics",
  "company": "acme-robotics",
  "jobId": "3f0c1a52-9d7e-4b8a-a1c2-0d9e8f7a6b5c",
  "title": "Senior Data Engineer",
  "department": "Engineering",
  "team": "Data Platform",
  "location": "Remote (US)",
  "allLocations": ["Remote (US)", "Austin, TX"],
  "remote": true,
  "workplaceType": "Remote",
  "employmentType": "FullTime",
  "salary": { "min": 150000, "max": 185000, "currency": "USD", "interval": "1 YEAR" },
  "postedAt": "2026-10-28T14:02:11.000Z",
  "updatedAt": null,
  "url": "https://jobs.ashbyhq.com/acme-robotics/3f0c1a52-9d7e-4b8a-a1c2-0d9e8f7a6b5c",
  "applyUrl": "https://jobs.ashbyhq.com/acme-robotics/3f0c1a52-9d7e-4b8a-a1c2-0d9e8f7a6b5c/application",
  "description": "About Acme Robotics\n\nWe build warehouse robots...",
  "scrapedAt": "2026-10-30T07:54:01.120Z"
}
```

Export as JSON, CSV, Excel or HTML, or call it from the API, Make, Zapier, n8n or an AI agent (MCP).

A run log line and a `SUMMARY` record tell you how many boards were found, how many jobs were listed, matched, skipped as already seen, and delivered. Companies with no public board on these three ATS are listed in `boardsNotFound`.

#### Pricing

**Pay per event: $0.001 per job delivered ($1.00 per 1,000 jobs).**

| You run | You pay |
|---|---|
| 1 company with 250 open jobs, full list | $0.25 |
| 50 companies, daily, only-new (≈ 40 new jobs a day) | ≈ $0.04 a day, ≈ $1.20 a month |
| 500 companies, weekly full snapshot (≈ 60,000 jobs) | $60 per snapshot |

Set **Maximum cost per run** in the run options to cap spend; the Actor stops cleanly at your limit and tells you so in the log. Apify's free plan includes $5 of monthly usage, enough for about 5,000 jobs.

#### What this Actor does not do

- It does not log in anywhere, and it does not read candidate, applicant or employee data. It reads only job postings that companies publish for the public.
- It does not collect personal data. Email addresses, phone numbers and LinkedIn profile links inside descriptions are removed, and so is the name of a person the posting tells you to contact or report to (`reports to [name removed]`).
- It does not cover SmartRecruiters, Workday, iCIMS, Taleo, LinkedIn or Indeed. SmartRecruiters' API terms forbid third-party extraction, so it is left out on purpose.

#### FAQ

**How do I find a company's slug?** Open its careers page. If the URL is `jobs.lever.co/<slug>`, `job-boards.greenhouse.io/<slug>` or `jobs.ashbyhq.com/<slug>`, paste the whole URL.

**Why is `company` sometimes the slug?** Lever and Ashby don't publish a display name in their public API, so the slug is used.

**Why is `salary` empty?** The company didn't publish a range on that ATS. Ashby and Lever expose structured ranges when the employer sets them. Greenhouse usually keeps pay inside the description text.

**How fast is it?** It makes at most one request per second to each ATS, as Lever's API asks. A board is one request, so 50 companies take under a minute.

**Source and terms.** Data comes from the public job-board APIs that Greenhouse, Lever and Ashby document for employers' careers pages. Job postings belong to the employers who publish them. Every item links back to the original posting (`url`). This Actor is not affiliated with Greenhouse, Lever or Ashby. If you are an employer or a vendor and want a board left out, open an issue and it will be removed.

**Something broke or a board is missing?** Open an issue on the Issues tab with the company URL. Issues are answered within 24 hours.

# Actor input Schema

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

Careers-page URLs (https://jobs.lever.co/acme, https://job-boards.greenhouse.io/acme, https://jobs.ashbyhq.com/acme), or ats:slug (greenhouse:acme), or a bare slug to auto-detect the ATS.

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

Keep jobs whose title contains any of these words (case-insensitive). Empty keeps all.

## `locationKeywords` (type: `array`):

Keep jobs with any location containing any of these (for example: Remote, London, Germany). Empty keeps all.

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

Keep only jobs the ATS marks remote, or whose location says Remote or Anywhere.

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

Keep only jobs first published in the last N days. 0 keeps all.

## `onlyNew` (type: `boolean`):

For scheduled runs: remember delivered job IDs and return (and charge) only new postings.

## `stateKey` (type: `string`):

Name for the only-new memory, so different schedules keep separate lists.

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

Plain-text description. Email addresses, phone numbers, LinkedIn profile links and the names of contact persons (recruiters, hiring managers) are removed.

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

0 means no limit. Use the run's maximum-cost setting to cap spend overall.

## Actor input object example

```json
{
  "companies": [
    "https://job-boards.greenhouse.io/gitlab",
    "ashby:ramp"
  ],
  "titleKeywords": [],
  "locationKeywords": [],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "onlyNew": false,
  "stateKey": "default",
  "includeDescription": true,
  "maxJobsPerCompany": 0
}
```

# Actor output Schema

## `results` (type: `string`):

Jobs, one item per charged event, in the default dataset.

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

Counts for the run (found, delivered, skipped, errors, spending-limit stop) in the SUMMARY record.

# 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": [
        "https://job-boards.greenhouse.io/gitlab",
        "ashby:ramp"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("opendata-feeds/multi-ats-jobs-feed").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": [
        "https://job-boards.greenhouse.io/gitlab",
        "ashby:ramp",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("opendata-feeds/multi-ats-jobs-feed").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": [
    "https://job-boards.greenhouse.io/gitlab",
    "ashby:ramp"
  ]
}' |
apify call opendata-feeds/multi-ats-jobs-feed --silent --output-dataset

```

## MCP server setup

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

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/yg5YCpoK5j5c5Dgju/builds/bgP1Qkrd4lpzlKoVQ/openapi.json
