# Workday, Greenhouse & Lever Jobs Scraper: Any Company (`lx112/company-jobs-tracker`) Actor

Every open job for any list of companies from their own job boards: Workday, Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee, BambooHR, Personio and Teamtailor. Auto-detects the ATS, normalizes titles, locations, salary and dates, and can return only jobs new since the last run.

- **URL**: https://apify.com/lx112/company-jobs-tracker.md
- **Developed by:** [leo xing](https://apify.com/lx112) (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

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

## Company Jobs Tracker: Workday, Greenhouse, Lever, Ashby, BambooHR, Personio and more

Give it a list of companies and get back **every open job they have posted**, normalized into one
clean format. The data comes from the job boards companies publish on their applicant tracking
system (ATS): **Workday**, Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee,
**BambooHR**, **Personio** and **Teamtailor**. That covers most large enterprises (Workday), most
startups and tech companies, and many small and mid-sized companies in the US and Europe.

- **No logins, no proxies, no scraping of job aggregators.** Each ATS serves a public API or feed
  for its job boards (the one the company's own careers page uses), and the actor reads that. It's
  fast (a 700-job company takes about a second) and doesn't break when a website is redesigned.
- **Auto-detects the ATS.** Type `Stripe`, `notion.so` or paste a job-board URL. Workday boards
  need their careers URL (see below).
- **Only new jobs.** Schedule the actor daily with *Only jobs new since my last run* on, and you
  get just the jobs posted since the last run. You can use them for alerts, a job board, or hiring
  signals for sales.
- **Salary** where the company publishes it (Ashby, Lever, Recruitee, and BambooHR with
  descriptions on), plus remote/hybrid flags, departments and posting dates.

### Who uses this

- **Sales and lead gen:** know which target accounts are hiring for roles that need your
  product (e.g. "data engineer" at your ICP list).
- **Recruiters and job seekers:** track a watchlist of companies and get only new openings.
- **Job boards and newsletters:** a clean feed straight from the source.
- **Market research and AI agents:** hiring trends by company, team and location.

### Input

| Field | Example | Notes |
|---|---|---|
| Companies | `Stripe`, `openai.com`, `https://jobs.lever.co/palantir` | Job-board URLs are the most reliable |
| Look on this ATS first | `auto` | Optional speed-up for name lookups |
| Job title contains any of | `engineer`, `sales` | Case-insensitive |
| Job title contains none of | `intern` | |
| Location contains any of | `London`, `remote`, `US` | Matches location, country and workplace type |
| Remote only | `false` | |
| Posted within (days) | `7` | |
| Only jobs new since my last run | `false` | Remembers earlier runs in your account |
| Include job descriptions | `false` | Plain text |
| Max jobs per company / in total | `1000` / `1000` | |

If a name isn't found, paste the company's job-board URL (the page you land on from their
"Careers" link). Recognized URLs:

| ATS | Job-board URL | Found from a name? |
|---|---|---|
| Greenhouse | `boards.greenhouse.io/<company>`, `job-boards.greenhouse.io/<company>` | yes |
| Lever | `jobs.lever.co/<company>` | yes |
| Ashby | `jobs.ashbyhq.com/<company>` | yes |
| Workable | `apply.workable.com/<company>` | yes |
| SmartRecruiters | `jobs.smartrecruiters.com/<company>` | yes |
| Recruitee | `<company>.recruitee.com` | yes |
| BambooHR | `<company>.bamboohr.com/careers` | yes |
| Personio | `<company>.jobs.personio.de` (or `.com`) | yes |
| Teamtailor | `<company>.teamtailor.com/jobs` | yes |
| Workday | `<tenant>.wd<N>.myworkdayjobs.com/<site>`, e.g. `nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite` | no: the URL holds a server number and site name that can't be guessed |

Teamtailor companies on their own careers domain still have a `<company>.teamtailor.com` address;
paste that if the name isn't found. Workday boards on a company's own domain aren't supported yet.

### Output (one dataset item per job)

```json
{
  "company": "openai",
  "ats": "ashby",
  "board": "openai",
  "jobId": "dd9c7c04-7181-4c65-9c6a-0e04313e3707",
  "title": "Principal Software Engineer, Productivity",
  "department": "Applied AI",
  "team": "Applied AI",
  "employmentType": "FullTime",
  "location": "San Francisco",
  "locations": ["San Francisco"],
  "country": "United States",
  "remote": null,
  "workplaceType": null,
  "salary": { "min": 459000, "max": 536000, "currency": "USD", "interval": "1 YEAR", "text": "$459K - $536K" },
  "postedAt": "2026-10-22T22:35:52.950Z",
  "updatedAt": null,
  "url": "https://jobs.ashbyhq.com/openai/dd9c7c04-7181-4c65-9c6a-0e04313e3707",
  "applyUrl": "https://jobs.ashbyhq.com/openai/dd9c7c04-7181-4c65-9c6a-0e04313e3707/application",
  "input": "https://jobs.ashbyhq.com/openai",
  "scrapedAt": "2026-10-22T22:48:32.381Z"
}
```

Fields an ATS doesn't publish are `null`. Some systems publish less in their job lists:

- **Workday** shows only a relative age ("Posted 3 Days Ago"), so `postedAt` is that day and is
  `null` for "30+ Days Ago"; jobs in several places list just "2 Locations". Turn on descriptions
  for exact dates and every location (one extra request per job).
- **BambooHR** lists no posting dates; turn on descriptions to get them and the pay range.
- **Personio** and **Teamtailor** don't flag remote work in a field; `remote` is set when a
  location says "Remote" (Teamtailor's hybrid/remote status is used when the feed has it).

The run's **SUMMARY** record (key-value store) lists, for each company, which board was found, how
many jobs are open and any error.

### Pricing

Pay per event: charged per **job** returned. Companies that aren't found and jobs filtered out
cost nothing.

### Notes

Job postings are published by the companies themselves for public display. This actor isn't
affiliated with any of the ATS vendors.

# Actor input Schema

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

Company names ("Stripe"), websites ("openai.com") or job-board URLs ("https://jobs.lever.co/palantir"). A job-board URL is the most reliable; for names the actor tries each supported ATS. Workday boards need their careers URL, e.g. "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite".

## `atsHint` (type: `string`):

Speeds up detection for plain company names if you know which ATS most of them use. Workday isn't listed because Workday boards are found only from their careers URL.

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

Keep jobs whose title contains at least one of these (case-insensitive), e.g. "engineer", "sales". Leave empty for all jobs.

## `excludeTitleKeywords` (type: `array`):

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

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

Keep jobs whose location, country code or workplace type contains one of these, e.g. "London", "Canada", "remote".

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

Keep only jobs the ATS marks as remote (or whose location says remote).

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

Keep only jobs first published in the last N days. Leave empty for all. Jobs without a posting date are dropped: Workday lists only 'Posted 30+ Days Ago' for older jobs, and BambooHR dates jobs only when descriptions are included.

## `onlyNewJobs` (type: `boolean`):

Remembers the jobs each company had open on earlier runs (in a key-value store in your account) and returns only new ones. Ideal with a daily schedule.

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

Adds the full job description as plain text. Makes the dataset much larger, and on Workday, SmartRecruiters and BambooHR it takes one extra request per job (which also fills in exact posting dates and all locations).

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

Upper limit of jobs returned for each company.

## `maxItems` (type: `integer`):

The run stops after this many jobs across all companies.

## Actor input object example

```json
{
  "companies": [
    "stripe",
    "huggingface",
    "https://jobs.lever.co/palantir"
  ],
  "atsHint": "auto",
  "remoteOnly": false,
  "onlyNewJobs": false,
  "includeDescription": false,
  "maxJobsPerCompany": 1000,
  "maxItems": 1000
}
```

# Actor output Schema

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

Open jobs matching the filters, one item per job, newest first within each company.

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

Which job board was found for each company, how many jobs are open, and any errors.

# 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": [
        "stripe",
        "huggingface",
        "https://jobs.lever.co/palantir"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lx112/company-jobs-tracker").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": [
        "stripe",
        "huggingface",
        "https://jobs.lever.co/palantir",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("lx112/company-jobs-tracker").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": [
    "stripe",
    "huggingface",
    "https://jobs.lever.co/palantir"
  ]
}' |
apify call lx112/company-jobs-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lx112/company-jobs-tracker"
        }
    }
}
```

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/7nwCKzQyzFboIprgu/builds/DgFPond4nPApbsgtw/openapi.json
