# Company Jobs Feed: Greenhouse, Lever and Ashby Job Listings (`stromation/company-jobs-feed`) Actor

Paste company names, careers pages or domains and get their current job openings in one uniform table, read from the official public Greenhouse, Lever and Ashby job-board APIs. Filters, salary when published, monitor mode for new jobs only. Companies with no job board found are free.

- **URL**: https://apify.com/stromation/company-jobs-feed.md
- **Developed by:** [Stromation LLC](https://apify.com/stromation) (community)
- **Categories:** Jobs, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## Company Jobs Feed: Greenhouse, Lever and Ashby Job Listings

Paste a list of companies and get their **current job openings in one uniform table**. You can give a company name, a job-board link, a careers page or just a website domain. The actor finds which job board the company uses (Greenhouse, Lever or Ashby) and returns clean rows: title, department, location, remote or not, pay when the company publishes it, posting date, links and the job description as plain text.

Built for recruiters and sourcers, sales teams that sell to hiring companies, job-market researchers and anyone who wants a daily "what is new" feed for a list of employers.

It reads **only the official public JSON job-board APIs** that these three vendors publish for exactly this purpose. It does not scrape job pages, does not log in and collects no personal data. A company's own website is opened only to look for a link to its job board, and only where that site's `robots.txt` allows it.

Try it: press **Try for free**. The prefilled input fetches up to 30 jobs from Airbnb, Palantir and OpenAI.

### What you can paste

Any mix, one per line:

| You paste | What happens |
|---|---|
| `airbnb` or `Palo Alto Networks` | Tries likely board names on Greenhouse, Ashby and Lever. |
| `https://boards.greenhouse.io/airbnb`, `https://job-boards.greenhouse.io/stripe`, `https://jobs.lever.co/palantir`, `https://jobs.eu.lever.co/...`, `https://jobs.ashbyhq.com/openai` | Uses that board directly. |
| `https://www.notion.so/careers` | Opens the page, looks for a Greenhouse, Lever or Ashby link or embed, then falls back to name guesses. |
| `stripe.com` | Same, starting from the home page, `/careers` and `/jobs`. |

Companies where no board is found are listed in a summary and **never charged**.

### What you get per job

One row per opening, the same fields for all three boards:

`company`, `board`, `board_slug`, `job_id`, `title`, `department`, `team`, `location`, `locations` (all of them), `remote` (true, false or null when the board does not say), `workplace_type` (remote, hybrid, onsite or null), `employment_type`, `posted_at`, `updated_at`, `compensation` (min, max, currency, interval, text, when published), `job_url`, `apply_url`, `description`, `description_truncated`, `source_api`.

A **COMPANIES** record in the run's key-value store lists every input with `status` (`found`, `not_found`, `error` or `skipped`), the board and slug found, how it was found, how many jobs the board has, how many matched your filters and how many were delivered.

### Pricing

Pay per event. **$0.0015 per job delivered** (about $1.50 per 1,000 jobs), plus a tiny flat start fee of $0.00005 per run. You are charged only for job rows that are saved to the dataset. Companies with no board found, errors, and (in monitor mode) jobs you already received are free.

Cap your spend with the run's maximum cost setting and with **Max jobs** (default 1,000, hard limit 20,000). When the cap is reached the run stops cleanly and the COMPANIES record shows which companies were not reached.

### Input

```json
{
  "companies": ["airbnb", "palantir", "openai"],
  "keywords": ["engineer"],
  "locations": ["Remote", "New York"],
  "postedWithinDays": 14,
  "maxItems": 30
}
```

| Field | Meaning |
|---|---|
| `companies` | Required. Names, board links, careers pages or domains. |
| `keywords` / `excludeKeywords` | Keep or drop jobs whose title (and description, when included) contains any of the words. |
| `locations` | Keep jobs where any location contains one of the texts. |
| `remoteOnly` | Only jobs the board marks as remote. |
| `departments` | Match on department or team. |
| `postedWithinDays` | 0 = any. Uses the board's own date (Greenhouse first published, Lever created, Ashby published). Jobs without a date are left out when set. |
| `onlyNew` | Monitor mode: skip jobs this same input delivered before (free). Schedule it daily. |
| `includeDescription`, `descriptionMaxChars` | Plain-text description, cut at 4,000 characters by default; 0 leaves it out. |
| `maxJobsPerCompany` | Newest first, default 500. |
| `maxItems` | Hard cap per run, default 1,000, maximum 20,000. |
| `concurrency` | Companies in parallel, 1 to 10, default 5. |

### Real run (30 October 2026, from a laptop)

Input: `airbnb`, `palantir`, `openai`, `stripe.com`, `https://www.notion.so/careers` and one invented name. No filters.

| Input | Result | Jobs | Time |
|---|---|---|---|
| `airbnb` | Greenhouse `airbnb` | 202 | 0.6 s |
| `palantir` | Lever `palantir` | 299 | 1.6 s |
| `openai` | Ashby `openai` | 813 | 0.5 s |
| `stripe.com` | Greenhouse `stripe` (name guess) | 746 | 1.6 s |
| `https://www.notion.so/careers` | Ashby `notion` (link found on the page) | 148 | 0.7 s |
| `qzxv-nonsense-corp-81` | not found, free | 0 | 13 s |

Together: 2,208 jobs in about 8.6 s with 5 companies in parallel. Of those rows, 648 carried published pay and 303 were marked remote.

Summary record (shortened):

```json
[
  { "input": "https://www.notion.so/careers", "status": "found", "board": "ashby", "slug": "notion", "company": "Notion", "found_via": "page_link", "jobs_on_board": 148, "jobs_matched": 148, "jobs_delivered": 148, "note": null },
  { "input": "qzxv-nonsense-corp-81", "status": "not_found", "board": null, "slug": null, "company": null, "found_via": null, "jobs_on_board": 0, "jobs_matched": 0, "jobs_delivered": 0, "note": "No Greenhouse, Lever or Ashby job board found." }
]
```

Job row from Ashby (description shortened):

```json
{
  "company": "Openai",
  "board": "ashby",
  "board_slug": "openai",
  "job_id": "36a746ab-66a6-4f3e-b164-3ca8fa9e0658",
  "title": "Senior Counsel, AI Product",
  "department": "Legal",
  "team": "Legal",
  "location": "Washington, DC",
  "locations": ["Washington, DC", "San Francisco"],
  "remote": false,
  "workplace_type": "hybrid",
  "employment_type": "Full-time",
  "posted_at": "2026-10-30T23:14:07.007Z",
  "updated_at": null,
  "compensation": { "min": 330000, "max": 366000, "currency": "USD", "interval": "year", "text": "$330K – $366K • Offers Equity" },
  "job_url": "https://jobs.ashbyhq.com/openai/36a746ab-66a6-4f3e-b164-3ca8fa9e0658",
  "apply_url": "https://jobs.ashbyhq.com/openai/36a746ab-66a6-4f3e-b164-3ca8fa9e0658/application",
  "description": "About the Team\n\nOpenAI's Legal team plays a crucial role in furthering OpenAI's mission by tackling innovative, fundamental legal issues in AI. If you're passio…",
  "description_truncated": true,
  "source_api": "api.ashbyhq.com"
}
```

Job row from Greenhouse (description shortened):

```json
{
  "company": "Airbnb",
  "board": "greenhouse",
  "board_slug": "airbnb",
  "job_id": "8337229",
  "title": "Senior Manager, Community Policy",
  "department": "Public Policy",
  "team": null,
  "location": "United States",
  "locations": ["United States"],
  "remote": true,
  "workplace_type": "remote",
  "employment_type": null,
  "posted_at": "2026-10-30T19:19:06.000Z",
  "updated_at": "2026-10-30T19:19:06.000Z",
  "compensation": null,
  "job_url": "https://careers.airbnb.com/positions/8337229?gh_jid=8337229",
  "apply_url": "https://careers.airbnb.com/positions/8337229?gh_jid=8337229",
  "description": "Airbnb was born in 2007 when two hosts welcomed three guests to their San Francisco home, and has since grown to over 5 million hosts who ha…",
  "description_truncated": true,
  "source_api": "boards-api.greenhouse.io"
}
```

The results table in the Apify console shows company, title, department, location, remote, workplace, type, pay, posted date, board and links. The dataset downloads as JSON, CSV or Excel.

### Use cases

**Recruiting and sourcing.** Build a list of target employers, filter by role words and location, and get fresh openings with direct apply links.

**Sales to hiring companies.** A company hiring five data engineers has a data problem. Filter by department or keyword and use the openings as a buying signal.

**Job-market research.** Count openings by department, location, remote share or published pay range across a peer group.

**Daily new-jobs feed.** Turn on `onlyNew`, schedule the actor every morning and send each run's dataset to Slack, email or a sheet. You pay only for jobs you have not seen.

### FAQ

**Which job boards are supported?** Greenhouse, Lever (US and EU) and Ashby. These are the three with official public job-board APIs that allow this use. Workday, SmartRecruiters, Workable and company-built career sites are not supported. A company on any of those is reported as "not found" and costs nothing.

**How does it find the board?** In order: a board link you pasted; links, scripts and embeds on the company's page (including the Greenhouse embed); then guesses from the name or domain (for example `acme`, `acmeinc`, `acme-inc`). The COMPANIES record says which route worked. A name guess can in rare cases land on an unrelated company with the same name, so check the `board_slug` and links for common names, or paste the board link.

**Does it respect robots.txt and rate limits?** Yes. The three APIs are public and meant to be read. For company pages it identifies itself as `StromationJobsFeed`, checks that site's `robots.txt` first, and skips pages it disallows. Lever asks for a one-second crawl delay, so requests to Lever are limited to one per second across the whole run. That is why a name that has to be tried on Lever takes a few seconds.

**Is `remote` always filled?** No. It is true or false only when the board says (workplace type, a "Remote" location, or Ashby's remote flag). Otherwise it is `null`, and `remoteOnly` leaves those jobs out. On Ashby a "Hybrid" job is `false` even when the company also flags it as remote-friendly.

**Is pay always there?** No. Only when the company publishes it: Ashby compensation, Lever salary range, Greenhouse pay ranges when the company turns them on. `compensation` is `null` otherwise.

**Why is the company name sometimes capitalised oddly ("Openai")?** Greenhouse sends the real company name. Lever and Ashby do not, so the actor uses what you typed, or the board name with a capital letter.

**What happens if a board changes its format?** Unknown shapes are never turned into empty fields silently. The run logs a clear warning and marks that company as an error. A daily automatic check of all three board APIs runs on the author's side and logs any format change. A health check can be run against one known board per API.

**Does it return personal data?** No. Job postings are about roles. Recruiter or hiring-manager names are not extracted.

**Can I run it from code or an AI agent?** Yes, through the Apify API, client libraries or any Apify integration.

### Limits

Up to 2,000 companies and 20,000 jobs per run. Descriptions are plain text converted from the board's HTML; pictures and formatting are dropped. Jobs a board marks as unlisted are not returned.

### More from the same author

- **Bulk Website Audit** (stromation/bulk-website-audit): scored audit of a list of websites.
- **Weak-Website Local Lead Finder** (stromation/weak-website-local-leads): local businesses whose websites are missing or weak.
- **SAM.gov Federal Bids Feed** (stromation/samgov-bids-feed): new federal contract opportunities filtered by keyword, NAICS and set-aside.
- **Company Dossier** (stromation/company-dossier): a business's identity, location and website quality in one row.

# Actor input Schema

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

One per line. Any mix of: a company name or board name (airbnb), a job-board link (boards.greenhouse.io/airbnb, jobs.lever.co/palantir, jobs.ashbyhq.com/openai), a careers page link, or a website domain (stripe.com). Duplicates are removed.

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

Keep a job if its title, or its description when descriptions are included, contains any of these words. Not case sensitive. Empty means all jobs.

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

Drop a job if its title or description contains any of these words.

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

Keep a job if any of its locations contains one of these texts, for example London or Canada. Not case sensitive.

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

Keep only jobs the board itself marks as remote. Jobs where the board does not say are left out.

## `departments` (type: `array`):

Keep a job if its department or team contains one of these texts, for example Engineering or Sales.

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

Only jobs posted in the last N days. 0 means any age. Uses the date the board gives (first published on Greenhouse, created on Lever, published on Ashby). Jobs with no date are left out when this is set.

## `onlyNew` (type: `boolean`):

Skip jobs this same input already delivered in an earlier run. Skipped jobs are free. Schedule the actor daily to get an alert-style feed of new openings. Changing the companies or filters starts a fresh memory.

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

Add the job description as plain text with line breaks. Turn off for a smaller, faster run.

## `descriptionMaxChars` (type: `integer`):

Cut descriptions at this many characters (the row says when it was cut). 0 leaves the description out.

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

Keep at most this many matching jobs per company, newest first.

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

Hard limit on jobs delivered in this run. The run stops cleanly when it is reached. Maximum 20,000.

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

How many companies are processed in parallel (1 to 10). Lever is always limited to 1 request per second, as its robots.txt asks.

## Actor input object example

```json
{
  "companies": [
    "airbnb",
    "https://jobs.lever.co/palantir",
    "stripe.com",
    "https://www.notion.so/careers"
  ],
  "keywords": [
    "engineer",
    "data"
  ],
  "excludeKeywords": [
    "intern",
    "contractor"
  ],
  "locations": [
    "New York",
    "Remote"
  ],
  "remoteOnly": false,
  "departments": [
    "Engineering"
  ],
  "postedWithinDays": 0,
  "onlyNew": false,
  "includeDescription": true,
  "descriptionMaxChars": 4000,
  "maxJobsPerCompany": 500,
  "maxItems": 30,
  "concurrency": 5
}
```

# Actor output Schema

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

No description

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

No description

## `companies` (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",
        "palantir",
        "openai"
    ],
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("stromation/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",
        "palantir",
        "openai",
    ],
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("stromation/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",
    "palantir",
    "openai"
  ],
  "maxItems": 30
}' |
apify call stromation/company-jobs-feed --silent --output-dataset

```

## MCP server setup

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