# Career Sites Jobs Feed: Workday, Greenhouse, Lever, Ashby +4 (`mersetti/ats-jobs-feed`) Actor

Live job listings from any company's careers site: Workday, Greenhouse, Lever, Ashby, Workable, Recruitee, Personio, SmartRecruiters. One unified format, salary, remote flags, full descriptions and new/closed job monitoring.

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

## Pricing

Pay per event

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

## Career Sites Jobs Feed — Workday, Greenhouse, Lever, Ashby, Workable, Recruitee, Personio, SmartRecruiters, Breezy, Teamtailor, Rippling

Get **live job listings straight from company career sites** in one clean, unified format.
Paste careers page URLs — the Actor detects the applicant tracking system (ATS) automatically and
returns every open position with title, location, remote/hybrid flag, employment type, salary,
posting date, full description and apply link.

**Monitor mode** remembers what it has already seen and outputs **only new jobs** (and optionally closed ones)
on every scheduled run — you pay only for fresh openings.

### Why this Actor

- **11 ATS in one Actor**: Workday, Greenhouse, Lever, Ashby, Workable, Recruitee, Personio, SmartRecruiters, Breezy, Teamtailor, Rippling.
- **Any company, live data**: no pre-built index — add any company that uses a supported ATS and get its jobs right now.
- **Auto-detection**: paste a company careers page (e.g. `https://company.com/careers`) and the embedded ATS is found for you.
- **Unified schema**: the same fields for every source, ready for spreadsheets, databases, job boards and AI agents.
- **Salary**: structured pay ranges from the ATS, plus ranges extracted from description text (`$150,000 – $200,000`, `€60k–80k`).
- **New / closed job monitoring** with a free silent baseline run.
- **Cheap**: pay per job result, no monthly rental.

### Use cases

- Niche job boards and newsletters (remote jobs, AI jobs, EU tech jobs…)
- Recruiting and sales intelligence: who is hiring, for which roles, where
- Hiring-trend and competitor research
- Personal job alerts: schedule daily, get only new matching roles
- Feeding AI agents / RAG with fresh, structured job data

### Input

| Field | Description |
|---|---|
| `companies` | Careers URLs or shorthands (see table below). Required. |
| `keywords` | Keep jobs whose title, department or team contains any keyword. |
| `excludeKeywords` | Drop jobs whose title contains any of these words. |
| `locations` | Keep jobs whose location/country contains any of these (`Berlin`, `Germany`, `US`, `remote`). |
| `remoteOnly` | Only remote jobs. |
| `postedWithinDays` | Only jobs posted in the last N days. |
| `includeDescription` | Full plain-text description (default on). |
| `maxJobsPerCompany` | Limit per company (default 1000). |
| `monitorMode` | Output only jobs not seen in previous runs. |
| `monitorId` | Separate saved state per watchlist. |
| `baselineOnFirstRun` | First monitor run saves state silently (no output, no cost). |
| `reportClosedJobs` | Also output jobs removed since last run. |

#### Supported URL formats

| ATS | Example URL | Shorthand |
|---|---|---|
| Workday | `https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite` | `workday:nvidia.wd5/NVIDIAExternalCareerSite` |
| Greenhouse | `https://boards.greenhouse.io/stripe` | `greenhouse:stripe` |
| Lever | `https://jobs.lever.co/palantir` | `lever:palantir` (`lever:eu/slug` for EU) |
| Ashby | `https://jobs.ashbyhq.com/openai` | `ashby:openai` |
| Workable | `https://apply.workable.com/huggingface` | `workable:huggingface` |
| Recruitee | `https://bunq.recruitee.com` | `recruitee:bunq` |
| Personio | `https://personio.jobs.personio.de` | `personio:personio` |
| SmartRecruiters | `https://jobs.smartrecruiters.com/BoschGroup` | `smartrecruiters:BoschGroup` |
| Breezy HR | `https://company.breezy.hr` | `breezy:company` |
| Teamtailor | `https://company.teamtailor.com` or a Teamtailor custom domain | `teamtailor:company` |
| Rippling | `https://ats.rippling.com/rippling/jobs` | `rippling:rippling` |

#### Example input

```json
{
  "companies": ["greenhouse:stripe", "https://jobs.ashbyhq.com/openai", "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"],
  "keywords": ["engineer", "data"],
  "locations": ["remote", "London", "Germany"],
  "postedWithinDays": 14
}
```

### Output

```json
{
  "company": "openai",
  "ats": "ashby",
  "jobId": "240d459b-696d-43eb-8497-fab3e56ecd9b",
  "title": "Research Engineer",
  "department": "Research",
  "team": "Research",
  "location": "San Francisco",
  "locations": ["San Francisco"],
  "country": "United States",
  "remote": null,
  "workplaceType": null,
  "employmentType": "FullTime",
  "seniority": null,
  "postedAt": "2025-04-05T00:03:20.653Z",
  "salary": { "min": 250000, "max": 445000, "currency": "USD", "period": "1 YEAR", "text": "$250K - $445K" },
  "descriptionText": "By applying to this role…",
  "applyUrl": "https://jobs.ashbyhq.com/openai/240d459b-…/application",
  "jobUrl": "https://jobs.ashbyhq.com/openai/240d459b-…",
  "firstSeenAt": "2026-10-14T08:00:00.000Z",
  "changeStatus": "new",
  "scrapedAt": "2026-10-14T08:00:00.000Z"
}
```

`changeStatus` is `new`, `seen` or `closed` (monitor mode). Fields the source ATS does not provide are `null`.
A per-company report (detected ATS, job count, errors) is saved to the `SUMMARY` record of the run's key-value store.

### Pricing

Pay per event: a small fee per run start plus a fee per job in the dataset. In monitor mode you pay only for new
(and closed, if enabled) jobs, so a daily watchlist of 50 companies typically costs cents per day.

### Tips

- **Monitoring**: enable `monitorMode`, then create a Schedule (e.g. daily 08:00) and an integration (email, Slack,
  Google Sheets, webhook) to get only new jobs.
- **Big Workday tenants** (thousands of jobs): use `keywords` — the Actor uses Workday's own search, which is much faster.
- **Speed**: switch off `includeDescription` if you only need titles and links (Workday and SmartRecruiters need one
  extra request per job for descriptions).
- A careers URL failed? Check the `SUMMARY` record — it tells you whether no supported ATS was found on the page.

### Legal

The Actor reads only public job-posting endpoints that the ATS vendors expose for publishing jobs on career sites and
job boards. It collects no personal data. Job descriptions remain the property of the employers.

### FAQ

**How do I find which ATS a company uses?** Just paste the company's careers page URL — the Actor scans it for an
embedded Greenhouse, Lever, Ashby, Workable, Recruitee, Personio, SmartRecruiters, Workday, Breezy, Teamtailor or
Rippling board. The detected ATS is shown in each result (`ats`) and in the `SUMMARY` record.

**Can I get only new job postings every day?** Yes — enable `monitorMode` and create a Schedule. The first run saves
a silent baseline (no charge for jobs); each later run outputs only jobs that appeared since the previous run.

**Is there a limit on companies?** No hard limit. 100+ companies per run is fine; use `maxJobsPerCompany` and filters
to control cost.

**Can I export to Google Sheets, Excel or CSV?** Yes — use the dataset export buttons or Apify integrations
(Google Sheets, Slack, Zapier, Make, webhooks). AI agents can call the Actor via the Apify MCP server.

**Is it legal?** The Actor reads public job-posting endpoints that ATS vendors provide for publishing jobs. No login,
no personal data.

### Related tools

- [Substack to Markdown for AI & RAG](https://apify.com/mersetti/substack-to-markdown)
- [Shopify Products & Price Monitor](https://apify.com/mersetti/shopify-products-monitor)
- Endpoint reference: [ATS Job Board APIs on GitHub](https://github.com/Mersetti/ats-job-board-apis)

# Actor input Schema

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

Careers page URLs or shorthands. Supported: Workday (https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite), Greenhouse (https://boards.greenhouse.io/stripe or greenhouse:stripe), Lever (jobs.lever.co/palantir or lever:palantir), Ashby (jobs.ashbyhq.com/openai), Workable (apply.workable.com/huggingface), Recruitee (bunq.recruitee.com), Personio (personio.jobs.personio.de), SmartRecruiters (jobs.smartrecruiters.com/BoschGroup), Breezy (company.breezy.hr), Teamtailor (company.teamtailor.com or a Teamtailor-powered custom domain), Rippling (ats.rippling.com/rippling/jobs). Any other careers page URL is scanned for an embedded ATS automatically.

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

Keep jobs whose title, department or team contains ANY of these words (case-insensitive). Empty = all jobs.

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

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

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

Keep jobs whose location or country contains ANY of these, e.g. London, Germany, US. Add "remote" to also keep remote jobs.

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

Keep only jobs marked remote.

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

0 = any date.

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

Adds plain-text job description. For Workday and SmartRecruiters this needs one extra request per job (slower).

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

Maximum number of jobs returned for each company (after filters).

## `monitorMode` (type: `boolean`):

Remembers jobs between runs and outputs only jobs not seen before. Schedule the Actor (e.g. daily) to get a feed of new openings. You pay only for new jobs.

## `monitorId` (type: `string`):

Name of the saved state. Use different IDs for different watchlists.

## `baselineOnFirstRun` (type: `boolean`):

On the first monitor run only save current jobs (no output, no cost), so later runs report truly new jobs.

## `reportClosedJobs` (type: `boolean`):

Also output jobs that disappeared since the previous run (changeStatus = closed).

## Actor input object example

```json
{
  "companies": [
    "greenhouse:stripe",
    "https://jobs.ashbyhq.com/openai",
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "keywords": [
    "engineer"
  ],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "includeDescription": true,
  "maxJobsPerCompany": 1000,
  "monitorMode": false,
  "monitorId": "default",
  "baselineOnFirstRun": true,
  "reportClosedJobs": false
}
```

# Actor output Schema

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

No description

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

No description

# 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",
        "https://jobs.ashbyhq.com/openai",
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    ],
    "keywords": [
        "engineer"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mersetti/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:stripe",
        "https://jobs.ashbyhq.com/openai",
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    ],
    "keywords": ["engineer"],
}

# Run the Actor and wait for it to finish
run = client.actor("mersetti/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:stripe",
    "https://jobs.ashbyhq.com/openai",
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "keywords": [
    "engineer"
  ]
}' |
apify call mersetti/ats-jobs-feed --silent --output-dataset

```

## MCP server setup

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