# Job Boards Scraper: Greenhouse, Lever and Ashby Jobs (`variegated_binturong/job-boards-scraper`) Actor

Get the open jobs of the companies you list from their public Greenhouse, Lever and Ashby job boards: title, department, location, remote flag, date and link, one row per job. Filter by keyword and location to see who is hiring, and for what, before you reach out.

- **URL**: https://apify.com/variegated_binturong/job-boards-scraper.md
- **Developed by:** [Luigi Fiano](https://apify.com/variegated_binturong) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 job postings

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

## Job Boards Scraper: Greenhouse, Lever and Ashby Jobs

Paste a list of companies and get every open job from their public Greenhouse, Lever and Ashby job boards, one row per job: company, title, department, location, remote or not, publication date, link and platform. Filter by keyword and location, and see in one table who is hiring, for which team and where.

The data comes from the public JSON endpoints that these platforms provide for careers pages, the same ones the companies' own careers pages read. No login, no cookies, no browser.

### What it is for

- **B2B sales and prospecting**: a company hiring SDRs is building a sales team, one hiring a "Head of Data" is about to buy data tools. Job openings are a reason to reach out, at the right moment, to the right team.
- **Account-based marketing**: watch a list of target accounts and keep only the jobs that mention your keywords, for example `Salesforce`, `HubSpot`, `Kubernetes` or `warehouse`.
- **Recruiting and staffing agencies**: see which companies are hiring for the roles you place, where, and since when.
- **Market research**: hiring by department, location and remote share across a list of companies.
- **Monitoring**: schedule it weekly with `postedWithinDays: 7` and get only the new jobs.

### What you can put in

One line per company, in any of these forms:

| Line | What happens |
|---|---|
| `https://boards.greenhouse.io/acme`, `https://job-boards.greenhouse.io/acme` | Greenhouse board `acme` |
| `https://jobs.lever.co/acme` (also `jobs.eu.lever.co`) | Lever board `acme` |
| `https://jobs.ashbyhq.com/acme` | Ashby board `acme` |
| `greenhouse:acme`, `lever:acme`, `ashby:acme` | that board |
| `https://www.acme.com/careers` | the careers page is read and the Greenhouse, Lever or Ashby board it embeds or links is scraped |
| `Acme Labs, Inc.` or `acme.com` | the board name is guessed (`acmelabs`, `acme-labs`, `acme`) and tried on Greenhouse, Lever and Ashby: the first board with jobs wins |

### Input

| Field | What it does | Default |
|---|---|---|
| `companies` | One company, board URL or careers page per line | required |
| `platform` | Where to try company names and domains: `auto`, `greenhouse`, `lever` or `ashby` | `auto` |
| `keywords` | Keep jobs with at least one of these words in the title, department, team or description | all jobs |
| `searchDescription` | Also match keywords in the description (searched, never stored) | true |
| `locations` | Keep jobs whose location or country contains one of these words; `Remote` also keeps remote jobs | all locations |
| `remoteOnly` | Keep only remote jobs | false |
| `postedWithinDays` | Keep jobs published in the last N days (0: any date) | 0 |
| `maxJobsPerCompany` | Keep only the newest N jobs of each company (0: no limit) | 0 |
| `includeErrorRows` | Add one row for each company without a public board | true |
| `concurrency`, `timeoutSecs`, `maxRetries` | Speed and resilience | 5, 20, 2 |
| `maxCompanies`, `maxResults` | Safety caps (0: no limit on rows) | 5000, 0 |

Keywords and locations match whole words, ignoring case and accents: `AI` does not match "maintenance", `node.js` and `c++` work as written.

Example:

```json
{
  "companies": ["https://boards.greenhouse.io/acme", "lever:globex", "https://www.initech.com/careers", "Umbrella Corp"],
  "keywords": ["sales", "account executive", "SDR"],
  "locations": ["London", "Remote"],
  "postedWithinDays": 30
}
```

### Output

One row per job:

```json
{
  "type": "job",
  "company": "globex",
  "title": "Senior Account Executive",
  "department": "Sales",
  "team": "Enterprise",
  "location": "London",
  "allLocations": ["London", "Manchester"],
  "country": "GB",
  "remote": false,
  "workplaceType": "hybrid",
  "employmentType": "Full-time",
  "salary": "GBP 60000-75000 per year",
  "salaryMin": 60000,
  "salaryMax": 75000,
  "salaryCurrency": "GBP",
  "publishedAt": "2026-10-20T09:00:00.000Z",
  "updatedAt": null,
  "url": "https://jobs.lever.co/globex/0000-example",
  "applyUrl": "https://jobs.lever.co/globex/0000-example/apply",
  "platform": "lever",
  "companySlug": "globex",
  "boardUrl": "https://jobs.lever.co/globex",
  "jobId": "0000-example",
  "matchedKeywords": ["sales", "account executive"],
  "input": "lever:globex",
  "error": null,
  "scrapedAt": "2026-10-27T08:00:00.000Z"
}
```

- `company` is the name the board gives (Greenhouse), otherwise the name or board name you entered.
- `remote` is true when the board marks the job remote or the location says so (Remote, Work from home, Anywhere...). Hybrid jobs have `remote: false` and `workplaceType: "hybrid"`.
- `workplaceType` is `remote`, `hybrid`, `onsite`, or null when the board does not say.
- `publishedAt` is the first publication date (Greenhouse first published, Lever creation date, Ashby published date). `updatedAt` is the last update when the board gives it.
- `salary` is filled only when the company publishes it (Lever salary range, Ashby compensation summary).
- Fields a platform does not provide are null. Rows of one company are sorted newest first.

A company without a public board gives one error row:

```json
{ "type": "error", "company": "Umbrella Corp", "platform": null, "companySlug": null, "input": "Umbrella Corp", "error": "no public job board found (tried umbrella on greenhouse, lever, ashby)", "scrapedAt": "2026-10-27T08:00:00.000Z" }
```

A `SUMMARY` record in the key-value store counts companies checked, with jobs and with errors, jobs found and delivered, companies per platform, and lists every company with its platform, board name, jobs found and delivered, and the error if any.

### Pricing

Pay per result: **$0.002 per row delivered** to the dataset ($2 per 1,000 jobs), plus the small Apify platform usage of the run. Jobs removed by your filters are not delivered and not charged. Each error row counts as one result: turn off `includeErrorRows` to get errors only in the summary.

### Notes

- Only public data: the job board endpoints that Greenhouse, Lever and Ashby offer for careers pages, and the careers page you give. No login, no cookies, no proxies, no CAPTCHA solving, nothing bypassed. A private or blocked board gives an error row.
- No personal data: rows contain job fields only. Names of recruiters or hiring managers are never stored: custom fields are not read, descriptions are searched for your keywords but not stored, and e-mail addresses are removed from every text field.
- A company name or domain is a guess. If a company uses a different board name, paste its board URL or careers page instead.
- Careers pages where the board link appears only after JavaScript runs, or that use another applicant tracking system, are reported as "no Greenhouse, Lever or Ashby job board found on this page".
- Not affiliated with Greenhouse, Lever or Ashby.

# Actor input Schema

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

One per line. A job board URL (boards.greenhouse.io/acme, jobs.lever.co/acme, jobs.ashbyhq.com/acme), a board name with its platform (greenhouse:acme, lever:acme, ashby:acme), a careers page URL that embeds or links one of these boards, or a company name or domain: the board name is guessed from it and tried on each platform.

## `platform` (type: `string`):

Where to look when a line is a company name or a domain. Board URLs and careers pages are not affected.

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

Keep only jobs with at least one of these words in the title, department, team or description (whole words; case and accents are ignored). Empty: every job.

## `searchDescription` (type: `boolean`):

Off: keywords are matched in the title, department and team only. The description is searched but never stored.

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

Keep only jobs whose location, other locations or country contain one of these words (for example London, Germany, US). "Remote" also keeps every remote job. Empty: every location.

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

Keep only jobs marked remote by the board, or with remote in the location.

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

0: any date. Jobs without a date are kept.

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

0: no limit. The newest jobs are kept.

## `includeErrorRows` (type: `boolean`):

One row with a plain error (no public board found, careers page unreachable...). Each error row counts as one result. Off: errors are listed only in the run summary.

## `concurrency` (type: `integer`):

How many companies are read at the same time.

## `timeoutSecs` (type: `integer`):

Give up on a request after this many seconds.

## `maxRetries` (type: `integer`):

How many times a request is retried after a timeout, a 429 or a 5xx response. Retry-After is honoured.

## `maxCompanies` (type: `integer`):

Safety cap on the number of input lines processed.

## `maxResults` (type: `integer`):

Stop after this many dataset rows. 0: no limit.

## Actor input object example

```json
{
  "companies": [
    "https://boards.greenhouse.io/airbnb",
    "https://jobs.lever.co/palantir",
    "https://jobs.ashbyhq.com/ramp"
  ],
  "platform": "auto",
  "keywords": [],
  "searchDescription": true,
  "locations": [],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "maxJobsPerCompany": 0,
  "includeErrorRows": true,
  "concurrency": 5,
  "timeoutSecs": 20,
  "maxRetries": 2,
  "maxCompanies": 5000,
  "maxResults": 0
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

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

// Run the Actor and wait for it to finish
const run = await client.actor("variegated_binturong/job-boards-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.lever.co/palantir",
        "https://jobs.ashbyhq.com/ramp",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("variegated_binturong/job-boards-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.lever.co/palantir",
    "https://jobs.ashbyhq.com/ramp"
  ]
}' |
apify call variegated_binturong/job-boards-scraper --silent --output-dataset

```

## MCP server setup

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