# Job Board Scraper: Greenhouse, Lever, Ashby & Workday (`glitchbound/job-board-scraper`) Actor

Pull open roles straight from companies' own career boards across five applicant tracking systems: Greenhouse, Lever, Ashby, SmartRecruiters and Workday. Title, location, department, remote flag, salary where published, posted date and a direct apply link, in one consistent shape.

- **URL**: https://apify.com/glitchbound/job-board-scraper.md
- **Developed by:** [glitchbound](https://apify.com/glitchbound) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Features:** Limited permissions
- **Stats:** 5 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.30 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Job Board Scraper: Greenhouse, Lever, Ashby, SmartRecruiters & Workday

Pull open roles **straight from companies' own career boards**. Give it a list of companies; it works out which of five systems each one uses and returns every job in a single consistent shape.

### Why these sources

All five publish **official public job-board APIs**: companies expose them deliberately so their openings can be syndicated. That means no blocking, no login, and no grey area, unlike scraping a job aggregator.

It also means the data is **first-party**: straight from the employer, before it's rewritten or delayed by an aggregator.

### Auto-detect

You rarely know which ATS a company uses. Enter the board name from their careers URL and the Actor works it out:

| Careers URL | Enter |
|---|---|
| `boards.greenhouse.io/stripe` | `stripe` |
| `jobs.lever.co/acme` | `acme` |
| `jobs.ashbyhq.com/ramp` | `ramp` |
| `jobs.smartrecruiters.com/Visa` | `Visa` |
| `nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite` | the whole URL |

### Filter before you pay

```json
{
  "companies": ["stripe", "ramp", "figma"],
  "titleKeywords": ["engineer"],
  "remoteOnly": true,
  "includeDescription": true
}
```

Filters run before billing, **you are charged only for jobs actually returned**, not for everything scanned.

### Do you need an API key? No. Is there a free tier? Yes.

The two things people search for in this category, measured, are **free** and
**API key**: `job board api free`, `job board api key`.

So, plainly:

- **No API key.** Nothing to register for, nothing to rotate, no key to leak in
  a repo. The source is a public API published deliberately by its owner.
- **No proxy setup.** The source does not bot-wall datacenter addresses, so the
  default works.
- **Pay per result, not per month.** There is no subscription and no minimum.
  Rows that error or that your filters drop are **not charged**.
- **Free to try.** Run it with the prefilled input and see real rows before
  deciding anything.

### What you get per job

Always: `company` · `ats` · `jobId` · `title` · `location` + `locations` · `remote` · `url` · `description` (clean text, HTML stripped)

Where the ATS publishes it: `department` + `departments` · `postedAt` · `updatedAt` · `employmentType` (Lever, Ashby, SmartRecruiters; Greenhouse does not expose it) · `compensation` (Ashby) · `seniority` (SmartRecruiters) · `postedAgo` (Workday, which publishes "Posted 3 Days Ago" rather than a date)

The split matters: a flat list reads as a guarantee, and a customer who writes code against `employmentType` will get null on every Greenhouse row.

### Use cases

- **Hiring-signal intelligence**: a company suddenly opening 12 sales roles is a growth signal; schedule this weekly and watch headcount plans
- **Job boards & aggregators**: build a niche board from first-party listings
- **Recruiting**: track which competitors are hiring the roles you're filling
- **Sales prospecting**: companies hiring for a stack are buying tools for it
- **LLM pipelines**: descriptions come through as clean text, ready to summarise or classify

### Which ATS, and how the board is found

Five applicant tracking systems, covering startups through to the largest
enterprises. Every one of these publishes its job board openly, because that is
how a company's own careers page renders its listings, so no key is involved
anywhere:

| ATS | Public board endpoint | Set `ats` to | Typical company |
|---|---|---|---|
| **Greenhouse** | `boards-api.greenhouse.io` job board API | `greenhouse` | startups and scale-ups |
| **Lever** | `api.lever.co` postings API | `lever` | startups and scale-ups |
| **Ashby** | Ashby's public job board API | `ashby` | newer startups |
| **SmartRecruiters** | `api.smartrecruiters.com` postings API | `smartrecruiters` | mid-market and enterprise |
| **Workday** | the career site's own `wday/cxs` endpoint | `workday` | large enterprises |

**Workday is the one that reaches the big companies.** Most of the Fortune 500
posts there rather than on a startup ATS, so a competitor-hiring watch that
skips Workday misses exactly the companies you most want to watch. NVIDIA alone
lists around 2,000 open roles through it.

Leave `ats` on `auto` and each company is tried against Greenhouse, Lever, Ashby
and SmartRecruiters, so a mixed list resolves without you knowing which system
anyone uses.

**Workday needs its careers URL, not a company name.** Its address carries three things
that a company name cannot produce: a host label, a data-centre number and a
career-site name, as in
`nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`. Guessing across those
would mostly generate 404s and bill you for the attempts, so instead you paste
the careers URL you already have and it is parsed for you.

You do not have to set `ats` for it, though. A Workday address identifies
itself, so `auto` recognises one on sight and routes it straight there. Mix
Workday URLs and plain board slugs in the same list and each is handled the
right way.

**A Greenhouse job board API key is not required.** The board endpoint is public
by design, since it is what the company's own careers page calls to render the
listings. The `companies` input takes the board token from the careers URL, so
`boards.greenhouse.io/stripe` means `stripe`.

Every job posting comes back with title, location, department, employment type,
remote flag, posted date, compensation when the company publishes it, and a
direct apply URL.

### Notes

- Descriptions are HTML-stripped into plain text, capped at 5,000 characters.
- Companies with no public board on any of the five systems return a clear `error` row naming the problem. **Error rows are never charged.**
- Public job postings only, no candidate data, no personal data.

### Related

- **[Company Career Page Jobs Scraper](https://apify.com/glitchbound/ats-jobs-scraper)**: any company's jobs by name or domain, on 24 career systems
- **[Workday Jobs Scraper](https://apify.com/glitchbound/workday-jobs-scraper)**: Workday career sites by company name
- **[Job Listings API](https://apify.com/glitchbound/ats-jobs-search)**: search every company at once, with a daily feed of new jobs

### Use it from an AI agent

This Actor is a ready-made tool for Claude, ChatGPT, Cursor or any other MCP
client, through Apify's MCP server. Add it as a connector at:

```
https://mcp.apify.com?tools=glitchbound/job-board-scraper
```

In Cursor or VS Code the same address goes in `mcp.json`:

```json
{ "mcpServers": { "apify": { "url": "https://mcp.apify.com?tools=glitchbound/job-board-scraper" } } }
```

The first call asks you to sign in to Apify, or takes an API token. From then
on the agent sees this Actor's input fields and calls it directly.

### Feedback

If this saved you time, a review on the Actor's Store page helps other people
find it. If something is missing or wrong, the Issues tab on the same page is
the fastest way to reach me, and it gets read.

# Actor input Schema

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

One per line. For Greenhouse, Lever and Ashby this is the board token from the careers URL, so boards.greenhouse.io/stripe means "stripe". For Workday, paste the whole careers URL, e.g. https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite. You can paste the URL instead of the identifier, e.g. https://boards.greenhouse.io/stripe works.

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

Only keep jobs whose title or department contains one of these (e.g. "engineer", "sales"). Leave empty for all. You are only charged for jobs actually returned.

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

Only keep jobs matching one of these locations (e.g. "london", "new york"). Leave empty for all.

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

Only return roles flagged remote.

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

Include the full job description as clean text (HTML stripped), ready for an LLM.

## `ats` (type: `string`):

Which applicant tracking system to read. Auto-detect tries Greenhouse, Lever and Ashby against each company. Workday is not auto-detected, because its address carries a tenant and site name that cannot be derived from a company name: pass the careers URL instead.

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

Upper limit of jobs RETURNED per company (after filters), so a small limit plus filters still gives you results. The form is prefilled with 50 so a first run costs cents; the cap when this field is left out entirely is 1000.

## `proxyConfiguration` (type: `object`):

Proxy settings.

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

A hard ceiling on rows for the entire run, across every target. The per-target limits above cap each one separately, so fifty targets at twenty each is still a thousand rows; this caps the total. The run stops cleanly when it is reached and nothing beyond that point is fetched or charged. Leave empty for no ceiling.

## Actor input object example

```json
{
  "companies": [
    "stripe"
  ],
  "remoteOnly": false,
  "includeDescription": true,
  "ats": "auto",
  "maxJobsPerCompany": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Open roles from company Greenhouse, Lever and Ashby boards.

# 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"
    ],
    "maxJobsPerCompany": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("glitchbound/job-board-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": ["stripe"],
    "maxJobsPerCompany": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("glitchbound/job-board-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": [
    "stripe"
  ],
  "maxJobsPerCompany": 50
}' |
apify call glitchbound/job-board-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,glitchbound/job-board-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/3cNHRmfh2urgdifbY/builds/ThrF8izw0J3e7SybM/openapi.json
