# ATS Jobs Scraper: Greenhouse, Lever, Ashby, Workable and 5 more (`keelandcharter/ats-jobs-feed`) Actor

Scrape every open job from a company's Greenhouse, Lever, Ashby, Workable, Recruitee, Personio, Teamtailor, BambooHR or Breezy HR board in one format: title, department, location, remote flag, salary when published, posted date and apply link. $1.50 per 1,000 jobs.

- **URL**: https://apify.com/keelandcharter/ats-jobs-feed.md
- **Developed by:** [Keel & Charter](https://apify.com/keelandcharter) (community)
- **Categories:** Jobs, Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 job returneds

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: Greenhouse, Lever, Ashby, Workable, Recruitee, Personio, Teamtailor, BambooHR and Breezy HR

Every open role from a company's own job board, in one tidy format. Built by Keel & Charter.

Paste a company name or board link. The Actor reads the public job board API that the company publishes through its applicant tracking system and hands back one clean record per job. Same fields for every platform, so you can mix boards in a single run and drop the results straight into a spreadsheet, a database or an AI agent.

### What you get

| Field | Example |
|---|---|
| ats | ashby |
| company | ramp |
| title | Security Engineer, Cloud |
| department, team | Engineering, Backend |
| location, all_locations | New York, NY (HQ); Remote (US) |
| workplace_type, is_remote | Hybrid, true |
| employment_type | FullTime |
| salary_min, salary_max, salary_currency, salary_text | 211400, 290600, USD |
| posted_at, updated_at | ISO 8601, UTC |
| job_url, apply_url | direct links to the posting |
| description_text | plain text, optional |
| scraped_at | when this run read the board |

Salary fields are filled when the company publishes pay on the board (common on Ashby, Lever and Breezy HR, required in many US states). Full descriptions are available on every platform except Workable and Breezy HR.

### How to use it

1. Add boards to **Company job boards**, one per line. Any of these work:
   - `ramp` (tried on all nine platforms; the board with the most roles wins)
   - `greenhouse:airbnb`, `lever:spotify`, `ashby:ramp`, `workable:huggingface`
   - `recruitee:bunq`, `personio:personio`, `teamtailor:career`, `bamboohr:canopy`, `breezy:duolingo`
   - a board link such as `https://jobs.lever.co/spotify`, `https://bunq.recruitee.com`, `https://personio.jobs.personio.com` or `https://duolingo.breezy.hr`

#### Supported platforms

| Platform | Prefix | Board address it reads |
|---|---|---|
| Greenhouse | `greenhouse:` | boards.greenhouse.io/\<company> |
| Lever | `lever:` | jobs.lever.co/\<company> |
| Ashby | `ashby:` | jobs.ashbyhq.com/\<company> |
| Workable | `workable:` | apply.workable.com/\<company> |
| Recruitee | `recruitee:` | \<company>.recruitee.com |
| Personio | `personio:` | \<company>.jobs.personio.com (or .de) |
| Teamtailor | `teamtailor:` | \<company>.teamtailor.com |
| BambooHR | `bamboohr:` | \<company>.bamboohr.com/careers |
| Breezy HR | `breezy:` | \<company>.breezy.hr |

Teamtailor and Recruitee boards on a custom domain need the platform address, for example `career.teamtailor.com` or `bunq.recruitee.com`.
2\. Optional filters: title keywords, location keywords, remote only, posted within N days.
3\. Turn on **Include full description** if you want the job text.
4\. Run, then export as JSON, CSV or Excel, or call it from the API, Make, Zapier, n8n or an MCP client.

### Example input

```json
{
  "companies": [
    "greenhouse:airbnb",
    "lever:spotify",
    "ashby:ramp",
    "workable:huggingface"
  ],
  "titleKeywords": [
    "engineer"
  ],
  "remoteOnly": false,
  "postedWithinDays": 30,
  "includeDescription": false,
  "maxJobsPerCompany": 50
}
```

### Example output

One row per result. A row from a real run:

```json
{
  "ats": "lever",
  "company": "spotify",
  "company_name": null,
  "job_id": "2a55d6c9-c564-443a-be3e-a3851db5a93b",
  "title": "Account Executive - Commercial, Spotify Technology",
  "department": "Operations and Business Support",
  "team": "Platform",
  "location": "New York, NY",
  "all_locations": [
    "New York, NY"
  ],
  "country": "US",
  "workplace_type": "hybrid",
  "is_remote": false,
  "employment_type": "Permanent",
  "salary_min": 87069.0,
  "salary_max": 124385.0,
  "salary_currency": "USD",
  "salary_text": "The United States base range for this position is $87,069-$124,385 plus equity. The benefits available for this position include health insurance, six...",
  "posted_at": "2026-10-23T15:00:40.768000+00:00",
  "updated_at": null,
  "job_url": "https://jobs.lever.co/spotify/2a55d6c9-c564-443a-be3e-a3851db5a93b",
  "apply_url": "https://jobs.lever.co/spotify/2a55d6c9-c564-443a-be3e-a3851db5a93b/apply",
  "description_text": null,
  "scraped_at": "2026-10-26T02:44:08.222166+00:00"
}
```

### Pricing

Pay per event, no subscription and no separate compute charge:

| Event | Price |
|---|---|
| Job returned | $0.0015 per job ($1.50 per 1,000 jobs) |
| Actor start | $0.00005 per run |

Example: a run that returns 400 jobs from 10 boards costs about $0.60. Boards that cannot be found are skipped and never charged. Set a maximum cost per run in the run options and the Actor stops cleanly when it is reached.

Pricing may change; any change follows Apify's notice rules.

### Good to know

- Only public, documented job board endpoints are used. Every path called is allowed by the platform's robots.txt, and Lever's one second crawl delay is honored.
- No personal data. The Actor never reads applicants, recruiters or employee profiles.
- Typical speed: a 200 role board takes a second or two. BambooHR boards read one extra page per job to get the posted date and description, so they run a little slower.
- Missing a platform? Tell us in the Issues tab. For Workday career sites use the Workday Jobs Scraper by Keel & Charter. Other platforms are added only where their terms and robots.txt allow it.

Keel & Charter builds small, dependable data tools. Questions or a board that will not load? Open an issue and we will look at it.

### FAQ

**Which companies use Greenhouse, Lever, Ashby or Workable?**
Thousands of tech and growth companies, for example Airbnb (Greenhouse), Spotify (Lever), Ramp (Ashby) and Hugging Face (Workable). Recruitee, Personio and Teamtailor are popular with European companies (bunq, Personio, Teamtailor itself), and BambooHR and Breezy HR with small and mid-sized US businesses (Duolingo posts some roles on Breezy HR). If you only know the company name, enter it bare and the Actor tries all nine.

**Can I track new jobs every day?**
Yes. Schedule the Actor in Apify with postedWithinDays set to 1 and send the results to Google Sheets, Slack, a webhook or your database.

**Do I need an API key or proxy?**
No. Each board's public job API is used directly.

### More from Keel & Charter

- [Workday Jobs Scraper](https://apify.com/keelandcharter/workday-jobs-feed)
- [Bulk WHOIS and Domain Lookup (RDAP, DNS, SPF, DMARC)](https://apify.com/keelandcharter/domain-rdap-dns-lookup)
- [Wayback Machine Domain History](https://apify.com/keelandcharter/wayback-domain-history)
- [South Carolina Short Term Rental Regulations](https://apify.com/keelandcharter/sc-short-term-rental-rules)

# Actor input Schema

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

One per line. Use the board name ('ramp'), a prefixed name ('greenhouse:airbnb', 'lever:spotify', 'ashby:ramp', 'workable:huggingface', 'recruitee:bunq', 'personio:personio', 'teamtailor:career', 'bamboohr:canopy', 'breezy:duolingo') or a board URL ('https://jobs.lever.co/spotify'). A bare name is tried on all nine platforms.

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

Keep jobs whose title contains any of these words, for example 'engineer' or 'sales'. Leave empty to keep all.

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

Keep jobs whose location contains any of these, for example 'New York', 'Remote' or 'Germany'.

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

Keep only jobs the board marks as remote.

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

Keep only jobs posted in the last N days. 0 keeps everything.

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

Add the plain text job description to each record (all platforms except Workable and Breezy HR).

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

0 means no limit.

## `maxJobs` (type: `integer`):

0 means no limit. You are charged only for jobs returned.

## Actor input object example

```json
{
  "companies": [
    "greenhouse:airbnb",
    "lever:spotify",
    "ashby:ramp",
    "workable:huggingface"
  ],
  "titleKeywords": [],
  "locationKeywords": [],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "includeDescription": false,
  "maxJobsPerCompany": 0,
  "maxJobs": 0
}
```

# Actor output Schema

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

All jobs returned by the run, in the default dataset.

# 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:airbnb",
        "lever:spotify",
        "ashby:ramp",
        "workable:huggingface"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("keelandcharter/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": [
        "greenhouse:airbnb",
        "lever:spotify",
        "ashby:ramp",
        "workable:huggingface",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("keelandcharter/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": [
    "greenhouse:airbnb",
    "lever:spotify",
    "ashby:ramp",
    "workable:huggingface"
  ]
}' |
apify call keelandcharter/ats-jobs-feed --silent --output-dataset

```

## MCP server setup

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