# Greenhouse & Ashby Jobs Scraper (`leafy_herb/live-job-feed`) Actor

Get live jobs from Greenhouse and Ashby company boards in one consistent feed. Filter titles and locations, remove duplicate postings, and export direct application links, departments, descriptions, and available Ashby salary data. No API keys or proxies required.

- **URL**: https://apify.com/leafy_herb/live-job-feed.md
- **Developed by:** [Ryan Mohnach](https://apify.com/leafy_herb) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 job delivereds

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 & Ashby Jobs Scraper — Export Jobs to CSV or JSON

Collect current public jobs from specific employers into one consistent JSON or CSV feed. Supply Greenhouse and Ashby board URLs, optionally filter by job title or primary location, and receive deduplicated postings with direct application links and source URLs.

Useful for niche job boards, employer watchlists, recruiting research, and scheduled automation workflows. This Actor reads the boards you specify live on each run. It does not search all employers or maintain a global jobs database.

### Quick start

```json
{
  "boards": ["https://job-boards.greenhouse.io/airbnb", "https://jobs.ashbyhq.com/Ashby"],
  "maxResults": 100,
  "titleIncludes": "engineer",
  "includeDescription": false
}
```

Click Start and export the resulting dataset as JSON, CSV, or Excel. For recurring collection, save your input as an Apify task and schedule it. Each run produces a fresh snapshot; it does not suppress jobs seen in earlier runs.

### Tutorial: export Greenhouse and Ashby jobs to CSV

Build a small employer watchlist for a niche job board or hiring research, without copying openings by hand.

1. Choose **Try for free** on this listing. An Apify account is required; runs use the listed pricing or available account credits.
2. Paste 1–10 public company board URLs, such as the two in the quick-start example. Use a board page rather than an individual job URL.
3. For a small trial, set **Maximum jobs** to **10**, **Title contains** to **engineer**, and leave the location filter empty. Keep memory at **256 MB** and set a **$0.03 maximum run charge**. Ten delivered jobs cost **$0.025** at the published price. Fewer matches cost less, with a startup charge even for zero matches.
4. Start the run. Inspect titles, locations, source boards, and direct job links in the **Jobs** output table. Export as CSV or Excel for a spreadsheet, or JSON for an application.
5. Replace the title filter with **sales**, **designer**, or your own substring. Clear it to collect all roles up to your cap. Filters match literal text, not natural-language requests.

#### Example workflows

| Need | Input choice | Result |
| --- | --- | --- |
| Engineering job-board feed | Selected employers + title engineer | Matching openings with application links |
| Hiring research | Selected employers + no title filter | Current openings across those boards, up to the cap |
| Location watchlist | Selected employers + location substring | Jobs whose primary location contains that text |

#### Keep a recurring employer watchlist

Save your input as an Apify task and schedule it at the frequency you need. Each scheduled run incurs the listed charges and produces a fresh snapshot. This Actor does not identify new or closed jobs across runs; keep exports separately if you want to compare dates.

#### Common questions

**Do I need Greenhouse or Ashby API keys?** No. The Actor reads public employer postings. Your Apify account runs and pays for the tool.

**Does this search every company?** No. You supply company board URLs. This is a selected-employer feed, not a global jobs search engine.

**Does it include salary?** Available Ashby compensation is included when published by the employer. Missing compensation stays null.

**Why are there no results?** There may be no open roles or no filter matches. Check the RUN_SUMMARY record for failed boards before broadening filters.

**Are these live vacancies?** The public board is fetched at run time. Employers control the source and listings can change afterward. Check the job link before applying or republishing.

### Returned fields

Each row contains `id`, `source`, `companyBoard`, `title`, `location`, `departments`, `workplaceType`, `employmentType`, `publishedAt`, `updatedAt`, `compensation`, `jobUrl`, `applyUrl`, `boardUrl`, `sourceUrl`, and `fetchedAt`. Optional `description` contains up to 20,000 characters and includes `descriptionTruncated`.

Unavailable fields are null. Greenhouse does not supply a normalized workplace type or publication date in this feed, so those values are not inferred. Ashby compensation is included only when the source publishes it. A remote label does not establish eligibility to work from a particular country. `companyBoard` is the employer's board identifier, not a verified legal company name.

### Limits and error behavior

- 1–10 board URLs and 1–5,000 results per run. Only supported HTTPS board hosts are accepted.
- Boards are processed in input order. A global result cap can prevent later boards from being read.
- Duplicate source IDs and repeated board URLs are removed within a run. Different IDs across ATS providers are not assumed to describe the same job.
- Title and primary-location filters use case-insensitive substring matching before per-job charging.
- Hidden/unlisted Ashby postings are excluded.
- Requests have a 15-second timeout, at most one retry for HTTP 429/5xx, and a 15 MiB response cap. No browser, proxy, credentials, or paid AI API is needed.
- Failed boards appear in the `RUN_SUMMARY` key-value-store record. Valid boards can still return results. If every board fails, the run fails. Empty valid boards and filters that match nothing produce zero jobs.
- Source outages and employer migrations can affect availability. This tool does not bypass logins or access applicant data.

### Billing

The price is $0.002 per delivered job ($2 per 1,000), plus a $0.005 Actor startup event. Apify bills startup events per GB of allocated memory, with a minimum of one event; the recommended 256 MB configuration uses one startup event. Platform usage is included. A 100-job run at 256 MB costs $0.205. Empty or failed runs still incur the startup event.

The billable event is `job-delivered`: one event per delivered job. Filtered jobs, duplicates, and failed-board diagnostics do not incur that event. The Apify Pricing tab is authoritative for the current price, startup charge, and whether platform usage is included. Set a maximum run charge when starting a run.

### Support

Report reproducible issues through this Actor's Issues tab. Include the public board URL and run ID; do not include passwords or private applicant information.

### Local development

Requires Node.js 22. Run `npm install`, then `npm test`. Run on Apify using the included Actor configuration and Dockerfile. The test suite uses simulated API responses; cloud runs are needed to verify live upstream access and billing.

# Actor input Schema

## `boards` (type: `array`):

One to ten full public board URLs. Use the board root, not individual job links. Supported: job-boards.greenhouse.io, boards.greenhouse.io, jobs.ashbyhq.com.

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

Maximum delivered jobs across all boards. Boards run in input order; increase this to reach later boards. Each delivered job is a billable event when monetization is enabled.

## `titleIncludes` (type: `string`):

Optional case-insensitive phrase. Filters apply before delivery and per-job charging.

## `locationIncludes` (type: `string`):

Optional case-insensitive phrase matched against the source's primary location text. This is not a remote-work eligibility filter.

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

Include up to 20,000 characters per job, with a truncation flag. No AI enrichment.

## Actor input object example

```json
{
  "boards": [
    "https://job-boards.greenhouse.io/airbnb",
    "https://jobs.ashbyhq.com/Ashby"
  ],
  "maxResults": 100,
  "titleIncludes": "",
  "locationIncludes": "",
  "includeDescription": false
}
```

# Actor output Schema

## `jobs` (type: `string`):

Filtered public job postings.

## `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 = {
    "boards": [
        "https://job-boards.greenhouse.io/airbnb",
        "https://jobs.ashbyhq.com/Ashby"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("leafy_herb/live-job-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 = { "boards": [
        "https://job-boards.greenhouse.io/airbnb",
        "https://jobs.ashbyhq.com/Ashby",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("leafy_herb/live-job-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 '{
  "boards": [
    "https://job-boards.greenhouse.io/airbnb",
    "https://jobs.ashbyhq.com/Ashby"
  ]
}' |
apify call leafy_herb/live-job-feed --silent --output-dataset

```

## MCP server setup

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