# ATS Jobs Scraper: Greenhouse, Lever, Workday, Oracle & 11 more (`mrtrelock/ats-jobs-scraper`) Actor

Get every open job from company career pages on Greenhouse, Lever, Ashby, Workday, Workable, SmartRecruiters, Recruitee and Breezy in one clean format. Paste careers URLs or just company names. Filter by keyword, location, remote and date. Salary included where published.

- **URL**: https://apify.com/mrtrelock/ats-jobs-scraper.md
- **Developed by:** [Nick R](https://apify.com/mrtrelock) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 jobs

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

### What does ATS Jobs Scraper do?

**ATS Jobs Scraper** collects every open job from company career pages on 15 widely used applicant tracking systems (ATS): **Greenhouse, Lever, Ashby, Workday, Oracle Cloud Recruiting, iCIMS, Workable, SmartRecruiters, Recruitee, Breezy HR, Teamtailor, Personio, BambooHR, Rippling and Gem**. It returns them in **one clean, consistent format**.

Paste careers page URLs, or **just type company names**. The scraper finds which ATS each company uses for you.

Every job comes straight from the company's own public job board, so the data is fresh, complete and free of the duplicates and stale reposts you get on job aggregators.

### Why use it?

- 🏢 **15 ATS platforms in one tool**, covering US tech, enterprise (Workday, Oracle Cloud, iCIMS) and European employers (Teamtailor, Personio, Recruitee), so you don't need a separate scraper per platform.
- 🔎 **Auto-detects the platform** from a bare company name like `ramp`, `airbnb` or `huggingface`.
- 💰 **Salary ranges** wherever the company publishes them (Ashby, Lever, Recruitee and others).
- 🌍 **Filters** by keyword, excluded words, location, remote-only and posting date.
- 📄 **Full job descriptions** as plain text and HTML, ready for AI, search or matching.
- 💸 **Pay only for jobs saved**. Filtered-out jobs cost nothing.
- 🔁 **No double charges**: if two inputs point to the same job board, it's scraped once.
- ⚡ **Fast and reliable**: it reads the same public job-board data each company's careers page loads, with no browser and no logins.

### Who uses it?

- **Job boards and aggregators** filling niche boards, like remote, AI, climate or a single city.
- **Recruiters and staffing agencies** tracking which companies are hiring for which roles.
- **Sales teams** using hiring as a buying signal ("they're hiring 5 data engineers, so they need our tool").
- **Investors and analysts** tracking headcount growth and new teams at portfolio or competitor companies.
- **Job seekers** getting alerts for new roles at their dream companies.
- **AI agents and RAG pipelines** that need structured, current job data.

### How to use it

1. Add companies in **Companies**, one per line. Any of these work:
   - `https://boards.greenhouse.io/airbnb`
   - `https://jobs.lever.co/plaid`
   - `https://jobs.ashbyhq.com/ramp`
   - `https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`
   - `https://jpmc.fa.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1001/requisitions` (Oracle Cloud Recruiting)
   - `https://polestar.teamtailor.com/jobs`, `https://acme.jobs.personio.de`, `https://acme.bamboohr.com/careers`, `https://careers-acme.icims.com/jobs`, `https://ats.rippling.com/acme/jobs`, `https://jobs.gem.com/acme`
   - `greenhouse:airbnb` (platform:slug)
   - `huggingface` (just the name: we try every platform and keep the biggest board)
2. Optionally add **keywords**, **locations**, **remote only** or **posted within N days**. Keywords and locations match whole words, so `intern` won't match "Internal" and `US` won't match "Sydney". `US` and `UK` also match "United States" and "United Kingdom".
3. Click **Start**. Download the results as JSON, CSV, Excel or HTML, or get them through the API.

**Tip:** run it on a **schedule** (daily or weekly) to monitor new openings automatically.

### Output example

```json
{
  "platform": "ashby",
  "company": "Ramp",
  "jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245",
  "title": "Security Engineer, Cloud",
  "department": "Engineering",
  "team": "Backend",
  "location": "New York, NY (HQ)",
  "locations": ["New York, NY (HQ)", "Remote (Canada)", "Remote (US)", "Miami, FL"],
  "country": "USA",
  "isRemote": true,
  "workplaceType": "Hybrid",
  "employmentType": "FullTime",
  "salaryMin": 211400,
  "salaryMax": 290600,
  "salaryCurrency": "USD",
  "salaryPeriod": "1 YEAR",
  "salaryText": "$211.4K – $290.6K • Offers Equity",
  "postedAt": "2026-04-07T17:12:35.753Z",
  "jobUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245",
  "applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application",
  "descriptionText": "About Ramp\n\nRamp is building the smart infrastructure for finance teams...",
  "scrapedAt": "2026-10-31T04:27:42.605Z"
}
```

`isRemote` is `true` when the job is fully remote **or** offers a remote option in one of its locations. In the example, Ramp's role is hybrid in New York but also open to "Remote (US)". Use `workplaceType` when you need the exact arrangement.

Each run also saves a **SUMMARY** record (in the run's key-value store). It lists every input, the platform found, how many jobs that board has open, how many were saved, and a plain-English reason for anything not found, skipped as a duplicate or skipped because a limit was reached.

### What does each platform provide?

| Field | Greenhouse | Lever | Ashby | Workday | Oracle Cloud | Workable | SmartRecruiters | Recruitee | Breezy | Teamtailor | Personio | BambooHR | iCIMS | Rippling | Gem |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Title, location, link | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Department | ✅ | when the company sets it | ✅ | – | job family | ✅ | when the company sets it | ✅ | ✅ | ✅ | ✅ | ✅ | category | ✅ | ✅ |
| Description | ✅ | ✅ | ✅ | – | ✅ | ✅ | ✅ | ✅ | – | ✅ | when the company publishes it in its feed | ✅ | ✅ | ✅ | ✅ |
| Salary | in description | ✅ when published | ✅ when published | – | in description | – | – | ✅ when published | text | – | – | text when published | ✅ when published | ✅ when published | in description |
| Posting date | ✅ | ✅ | ✅ | approximate | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |

### How much does it cost?

You pay a small fee **per job saved**, plus nothing for companies or jobs your filters skip. See the **Pricing** tab for the current rate. A typical run of 20 companies with about 1,000 jobs costs about $1.50. Big enterprise boards can hold thousands of jobs (JPMorgan has over 7,000 on Oracle Cloud), so use **Max jobs per company**, keywords or locations to keep costs where you want them. Apify's free plan includes monthly credit, enough for thousands of jobs.

### FAQ

**Is it legal?** The scraper only reads public job listings that companies publish so that anyone can see and apply. It doesn't log in or collect personal data about candidates or employees. As always, use the data in line with your local laws.

**A company isn't found by name. What now?** Some companies use a different slug than their name. Open their careers page, click any job and paste that page's link (or the job board's main link) instead.

**Does it collect recruiter names or emails?** No. Oracle Cloud job details name the recruiter and hiring manager; we leave those out on purpose and keep only the job itself.

**Why is Workday's description empty?** Workday's public list doesn't include descriptions. Use the `jobUrl` to open the full posting.

**Which inputs need a full link?** Workday, Oracle Cloud and iCIMS always need the careers page link, because their addresses don't match the company name (e.g. `careers-gdms.icims.com`). For Oracle, open the company's job list and copy the link: it contains `oraclecloud.com` and `/sites/`, e.g. `.../sites/CX_1001/requisitions`. Teamtailor companies on their own careers domain work too: paste the link (e.g. `https://jobs.acme.com`) or use `teamtailor:jobs.acme.com`.

**Why does a Personio job have a country?** Personio's feed lists only the office name, usually a city. We fill in the country for common European cities (e.g. München → Germany) so location filters like `Germany` work. Offices we don't recognise keep `country` empty, so filter by city name for those.

**What if I type a name that several companies share?** A bare name is matched to the biggest board with that exact name, which may not be the company you meant. The SUMMARY flags every name match. A careers page link is always exact.

**Can I use it through the API or with AI agents?** Yes. Use the Apify API, the official client libraries or integrations (Make, Zapier, n8n, Google Sheets). AI agents can also call it as a tool through Apify's MCP server.

**Found a bug, or want another ATS added?** Open an issue in the **Issues** tab. We read every one, and requests for new platforms are welcome.

# Actor input Schema

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

One per line. Any of these work:
• A careers page URL, e.g. https://boards.greenhouse.io/airbnb, https://jobs.lever.co/plaid, https://jobs.ashbyhq.com/ramp, https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite, https://polestar.teamtailor.com/jobs, https://acme.jobs.personio.de, https://acme.bamboohr.com/careers, https://careers-acme.icims.com/jobs, https://jpmc.fa.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1001, https://ats.rippling.com/acme/jobs, https://jobs.gem.com/acme
• platform:slug, e.g. greenhouse:airbnb
• Just a company name, e.g. ramp. We'll check Greenhouse, Lever, Ashby, Workable, Recruitee, Breezy, SmartRecruiters, Teamtailor, Personio, BambooHR, Rippling and Gem for you. Workday, Oracle Cloud and iCIMS always need the full URL.

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

Keep only jobs whose title, department or team contains at least one of these words. Leave empty to get every job.

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

Drop jobs containing any of these words, e.g. intern, senior.

## `searchInDescription` (type: `boolean`):

Slower, but catches jobs that mention your keyword only in the description.

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

Keep only jobs whose location contains one of these, e.g. London, Germany, US, Remote.

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

Keep only jobs marked remote, or whose location says remote.

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

0 means any date. Jobs with no published date are kept.

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

Adds the description as plain text and HTML. (Not available for Workday and Breezy job lists, and Personio only when the company publishes it in its feed.) Oracle Cloud, Rippling, SmartRecruiters, BambooHR and iCIMS need one extra request per job for this, so those runs take longer.

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

Stop after this many matching jobs from one company.

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

0 means no limit. You only pay for jobs saved.

## Actor input object example

```json
{
  "companies": [
    "https://boards.greenhouse.io/airbnb",
    "https://jobs.ashbyhq.com/ramp",
    "huggingface"
  ],
  "keywords": [],
  "excludeKeywords": [],
  "searchInDescription": false,
  "locations": [],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "includeDescription": true,
  "maxJobsPerCompany": 1000,
  "maxJobs": 0
}
```

# Actor output Schema

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

All jobs found, in one clean format.

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

What happened for each company you entered.

# 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://boards.greenhouse.io/airbnb",
        "https://jobs.ashbyhq.com/ramp",
        "huggingface"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrtrelock/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 = { "companies": [
        "https://boards.greenhouse.io/airbnb",
        "https://jobs.ashbyhq.com/ramp",
        "huggingface",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("mrtrelock/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 '{
  "companies": [
    "https://boards.greenhouse.io/airbnb",
    "https://jobs.ashbyhq.com/ramp",
    "huggingface"
  ]
}' |
apify call mrtrelock/ats-jobs-scraper --silent --output-dataset

```

## MCP server setup

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