# Greenhouse, Lever, Ashby & Workday Jobs — ATS Job Board Scraper (`signalloom/company-jobs-feed`) Actor

Get every open job from company career sites and ATS job boards (Greenhouse, Lever, Ashby, Workday, Workable, Recruitee, Teamtailor, Personio) from a company name or careers URL. Output: one clean job schema, only new/closed jobs since the last run, or hiring signals. $2 per 1,000 jobs.

- **URL**: https://apify.com/signalloom/company-jobs-feed.md
- **Developed by:** [Signalloom](https://apify.com/signalloom) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.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

## Greenhouse, Lever, Ashby & Workday Jobs: ATS Job Board Scraper

Get **every open job from any company's career page** in one clean, consistent format. Paste company names or careers-page URLs, and the Actor detects which hiring platform the company uses and pulls its jobs from that platform's public job-board data (official public APIs for 7 of the 8; see Limitations for Workday).

**Supported platforms:** Workday · Greenhouse · Lever · Ashby · Workable · Recruitee · Teamtailor · Personio

- **Auto-detection**: give `stripe`, `https://www.notion.com/careers` or `https://jobs.lever.co/palantir`, and it finds the right board
- **One schema for all platforms**: title, department, location, workplace type (remote, hybrid or on-site), employment type, posted date, apply link, and salary where the company publishes it
- **New-job alerts**: schedule it daily and get only the jobs posted since the last run, plus jobs that closed
- **Workday without the 2,000-job cap**: Workday career sites stop at 2,000 jobs. This Actor lists them one job category at a time, so large employers (NVIDIA: 2,796 jobs) come back complete, each with its department, all locations and the exact posting date
- **Company directory, no names needed**: browse 8,000+ companies with open roles on Greenhouse, Ashby and Lever, and find out who is hiring for a role you care about
- **Fast and reliable**: uses public job-board data, with no browser, no proxies and no logins. Workday job details are cached, so scheduled runs only fetch what's new

**Price: $2 per 1,000 jobs**, plus $0.001 per company checked. The prefilled example (3 companies on Greenhouse, Ashby and Workday, 10 jobs each, one found from just its name) finishes in seconds for about $0.06.

### Use this when…

- you need **Greenhouse jobs**, **Lever jobs**, **Ashby jobs** or **Workday jobs** from specific companies in one format
- you're building a **job board** or job alerts and need a **job board scraper** for company career pages (ATS jobs)
- you want only **new and closed jobs** since the last run, on a schedule
- you want **hiring signals**: which companies are growing a team, ranked by hiring growth
- an AI agent or automation needs structured job postings from a company name or careers-page URL

### For AI agents

- **Run** `signalloom/company-jobs-feed` (Apify MCP server `call-actor`, or the Apify API) with input like `{"companies": ["airbnb", "https://jobs.ashbyhq.com/ramp"], "maxJobsPerCompany": 10}`
- **Returns** one JSON row per job in the run's default dataset: `company`, `platform`, `title`, `department`, `location`, `workplaceType`, `employmentType`, `postedAt`, `url`, `salary` (or `null`), `changeType`. With `"outputMode": "companies"`: one row per company with `openJobs`, `postedLast30Days`, `hiringTrend`, `growthRank`.
- **Typical cost:** 2 companies × 10 jobs = 20 jobs ≈ **$0.04** ($0.002 per job + $0.001 per company found). Unfound companies are free.

### What can I use it for?

- **Job seekers and job boards**: a daily feed of new openings at the companies you care about
- **Recruiters and sales teams**: hiring signals. A company opening 10 new sales roles is a warm lead.
- **Market and competitor research**: see which teams competitors are growing, where, and at what salary
- **HR and compensation analytics**: published salary ranges across companies
- **AI agents and automations**: structured job data for Make, Zapier, n8n or your own pipeline

### How to use it

1. Add companies in any of these forms:
   - a name: `stripe`, `Hugging Face`
   - a job-board URL: `https://jobs.ashbyhq.com/ramp`
   - a Workday career site: `https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`
   - a careers page: `https://www.figma.com/careers/`
   - an explicit board: `greenhouse:airbnb`
2. Optionally filter by title keywords, location, workplace type or posting date.
3. Click **Start**.
4. To monitor, **schedule** the Actor (daily is typical) and set **Output → Only new and closed jobs**.

Names are matched by trying each platform in turn. If a name finds the wrong company or nothing at all, use the job-board URL instead, which is always exact. The detected board is remembered, so later runs go straight to it.

### Company directory: find who is hiring, without a company list

Don't have a list of companies? Turn on **Browse the company directory**. The Actor picks companies from our directory of **8,000+ public Greenhouse, Ashby and Lever job boards with open roles**. We found them in the public Common Crawl web archive and checked each one against the platform's public job-board API.

- **Minimum open jobs**: only companies with at least this many open roles (default 5)
- **Company name contains**: narrow by name, e.g. `ai`, `health`, `bank`
- **Max directory companies**: a cost cap; the largest boards come first (default 100)
- **Platforms to search**: limits the directory to the platforms you pick

**Recipe: "who is hiring ML engineers right now".** Leave Companies empty, turn on the directory, set Title keywords to `machine learning`, `ml engineer`, set Output to **Hiring signals** and Max directory companies to 300. You get a ranked list of companies building ML teams. 300 companies cost $0.30 for the checks plus $0.01 per company summary.

The directory is refreshed regularly. It lists company job boards only, with no information about people.

### Hiring signals mode (for sales teams)

Set **Output → Hiring signals** to get **one row per company**, **ranked by hiring growth** (top growers first). Combine it with title keywords to see who is building a team you sell to:

- `growthRank`: 1 = the company hiring fastest in your list
- `hiringTrend`: `surging`, `growing`, `steady` or `slowing` (more roles closing than opening)
- `growthScore`: weights jobs posted in the last 7 days most, then the last 30 days, then net new jobs since your last run

**Recipe: weekly "who's scaling sales" lead list.** Add your target accounts, set Title keywords to `account executive`, `sales`, `SDR`, set Output to Hiring signals and schedule it weekly. The top of the list is who to call this week.

```json
{
  "company": "Ramp",
  "growthRank": 1,
  "hiringTrend": "surging",
  "growthScore": 137,
  "openJobs": 23,
  "newJobsSinceLastRun": 4,
  "closedJobsSinceLastRun": 1,
  "postedLast7Days": 2,
  "postedLast30Days": 6,
  "remoteShare": 0.09,
  "byDepartment": { "Sales": 22, "Engineering": 1 },
  "topLocations": { "New York, NY (HQ)": 16, "San Francisco, CA": 2, "London, UK": 2 },
  "newJobTitles": ["Account Executive, Mid-Market", "..."]
}
```

**Recipe: sales prospecting.** Add your target accounts, set keywords to `sales`, `account executive` and `sdr`, set Output to Hiring signals, and schedule weekly. A company that suddenly opens many sales roles is expanding and buying.

### Output

```json
{
  "company": "Ramp",
  "platform": "ashby",
  "boardSlug": "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)"],
  "country": "USA",
  "workplaceType": "hybrid",
  "isRemote": true,
  "employmentType": "Full-time",
  "postedAt": "2026-04-07T17:12:35.753Z",
  "url": "https://jobs.ashbyhq.com/ramp/34413f8d-...",
  "applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-.../application",
  "salary": { "min": 211400, "max": 290600, "currency": "USD", "interval": "year", "text": "$211.4K - $290.6K" },
  "changeType": "NEW_JOB",
  "firstSeenAt": "2026-11-10T15:26:02.886Z"
}
```

- `changeType` is `NEW_JOB` (first seen this run), `REMOVED` (closed since the last run) or `null`.
- `firstSeenAt` is when this Actor first saw the job, useful for "days open".
- `description` is added when **Include job descriptions** is on.
- Fields a platform doesn't publish are `null`. Salary is published mostly on Ashby, Lever and Recruitee, and only by some companies.

A per-company summary (detected platform, board URL, job counts, new and removed counts, errors) is saved to the run's key-value store as `OUTPUT`.

### Data handling

Job postings come from each company's public job board. Records describe **jobs and companies, not people**: no recruiter or hiring-manager names or emails are output. Each platform's robots.txt was checked for the endpoints used.

### Pricing

- **$2.00 per 1,000 jobs** output
- **$0.001 per company** successfully checked (companies that can't be found are free)
- **$0.01 per company summary** in Hiring signals mode (no per-job charge in that mode)

With **Only new and closed jobs**, a daily check of 50 companies typically costs a few cents a day. Companies that can't be found are never charged.

### Limitations

- Only **public** job boards on the 8 supported platforms. Companies using iCIMS, Taleo or a fully custom system aren't covered yet.
- **Workday** boards can't be found from a company name alone, because each company picks its own site address. Use the Workday career-site URL, or a careers page that links to it. The first Workday run for a large company takes a few minutes (it fetches each job's details once); later runs are much faster.
- Teamtailor boards on custom domains need the `company.teamtailor.com` address.
- Closed-job (`REMOVED`) detection only runs when all of a company's jobs are fetched (`maxJobsPerCompany` = 0).
- Workday has no official public jobs API. This Actor reads the same JSON data that Workday career sites load in your browser. Workday could change it, so the Actor is tested against live career sites every day.
- The first run per company and monitor name only saves a baseline.

### FAQ

**How do I scrape all jobs from a company's Greenhouse, Lever or Ashby job board?**

Put the company name (`airbnb`) or the board URL (`https://jobs.lever.co/palantir`) in **Companies** and run. The Actor detects the platform and returns every open job in one format, using the platform's public job-board API.

**How can I get an alert when a company posts a new job?**

Schedule the Actor (daily is typical) with **Output → Only new and closed jobs** (`"outputMode": "newOnly"`). Each run returns only jobs posted since the previous run, plus the ones that closed. Connect the run to Slack, email, Make, Zapier or n8n.

**How do I find which ATS a company uses?**

Run it with the company name. Each job row's `platform` field (and the `OUTPUT` summary in the key-value store) shows the detected platform and board URL.

**How do I find companies that are hiring for a specific role?**

Leave Companies empty, turn on **Browse the company directory**, add title keywords (e.g. `data engineer`) and set Output to **Hiring signals**. You get companies ranked by hiring growth for that role.

**Does it return salaries?**

Yes, when the company publishes them (common on Ashby, Lever and Recruitee): `salary` has `min`, `max`, `currency` and `interval`. Otherwise it is `null`.

### Feedback

Want another platform added, or found a company that isn't detected? Open an issue on the **Issues** tab.

# Actor input Schema

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

Company names ("stripe"), job-board URLs ("https://jobs.lever.co/palantir"), company careers pages ("https://www.notion.com/careers"), Workday career-site URLs, or explicit "platform:slug" ("greenhouse:airbnb"). Leave empty and turn on "Browse the company directory" to pick companies for you. Workday boards need the career-site URL or a careers page that links to it. Example: \["airbnb", "https://jobs.ashbyhq.com/ramp"]. Needed unless useDirectory is true.

## `useDirectory` (type: `boolean`):

Add companies from our directory of 8,000+ public Greenhouse, Ashby and Lever job boards with open roles (checked against each platform’s public API). Use it to discover who is hiring without knowing company names. Combine with Title keywords and Hiring signals mode to find companies hiring for a role. Uses the "Platforms to search" setting. Each company checked is billed as usual. Example: true with keywords \["machine learning"] and outputMode "companies".

## `directoryMinOpenJobs` (type: `integer`):

Only directory companies with at least this many open jobs at the last directory check.

## `directoryNameContains` (type: `array`):

Only directory companies whose name or board slug contains one of these, e.g. "ai", "health", "bank".

## `directoryMaxCompanies` (type: `integer`):

Upper limit on companies taken from the directory (largest boards first). Keeps cost predictable: each company checked costs $0.001 plus its jobs.

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

Only jobs whose title contains at least one of these (case-insensitive), e.g. "engineer", "sales". Example: \["engineer", "account executive"].

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

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

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

Only jobs whose location or country contains one of these, e.g. "London", "Germany", "US", "remote".

## `workplaceTypes` (type: `array`):

Only these workplace types. When set, jobs that don't state a workplace type are excluded. Example: \["remote"].

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

Only jobs posted in the last N days. 0 = any time. Example: 7 = last week.

## `trackChanges` (type: `boolean`):

Remember each company's jobs and flag NEW_JOB / REMOVED on later runs, plus a firstSeenAt date. Schedule the Actor (e.g. daily) to get a feed of new openings.

## `outputMode` (type: `string`):

"All jobs" outputs every open job each run. "Only new and closed jobs" outputs just the changes since the last run. "Hiring signals" outputs one row per company: open jobs, new and closed since last run, jobs posted in the last 7/30 days, and counts by department, location and workplace type. Great for sales prospecting. Filters apply to all modes. API values: "all", "newOnly", "companies".

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

Change history is kept per monitor name. Use different names for separate schedules. Example: "sales-accounts-weekly".

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

Add the full job description as plain text (larger output, slower runs).

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

Keep only the N most recently posted jobs per company. 0 = all. Closed-job detection only runs when all jobs are fetched. Example: 10 for a cheap sample (about $0.02 per company).

## `platforms` (type: `array`):

Which job-board platforms to try when detecting a company by name. Leave all on unless you know where your companies post. Example: \["greenhouse", "ashby"].

## `maxConcurrency` (type: `integer`):

How many companies to fetch at the same time.

## Actor input object example

```json
{
  "companies": [
    "airbnb",
    "https://jobs.ashbyhq.com/ramp",
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "useDirectory": false,
  "directoryMinOpenJobs": 5,
  "directoryMaxCompanies": 100,
  "postedWithinDays": 0,
  "trackChanges": true,
  "outputMode": "all",
  "monitorId": "default",
  "includeDescription": false,
  "maxJobsPerCompany": 10,
  "platforms": [
    "greenhouse",
    "lever",
    "ashby",
    "workable",
    "recruitee",
    "teamtailor",
    "personio",
    "workday"
  ],
  "maxConcurrency": 4
}
```

# Actor output Schema

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

No description

## `runSummary` (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": [
        "airbnb",
        "https://jobs.ashbyhq.com/ramp",
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    ],
    "maxJobsPerCompany": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("signalloom/company-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": [
        "airbnb",
        "https://jobs.ashbyhq.com/ramp",
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    ],
    "maxJobsPerCompany": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("signalloom/company-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": [
    "airbnb",
    "https://jobs.ashbyhq.com/ramp",
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "maxJobsPerCompany": 10
}' |
apify call signalloom/company-jobs-feed --silent --output-dataset

```

## MCP server setup

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