# Company Jobs Feed for Greenhouse, Lever & Ashby (`ethical_acumen/company-jobs-feed`) Actor

Open jobs from the public job boards of the companies you list (Greenhouse, Lever and Ashby boards) in one normalized table, with published salary ranges and an optional new-jobs-since-last-run mode.

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

## Pricing

from $1.00 / 1,000 job results

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 for Greenhouse, Lever & Ashby

Track new openings at the companies you choose: schedule this Actor with *Only jobs new since the last run* for a daily or weekly feed from their Greenhouse, Lever or Ashby job boards. Companies that aren't found, are blocked or are invalid aren't charged.

Get the open jobs of the companies you choose in one clean table. Give it a list of companies whose careers pages run on Greenhouse, Lever or Ashby job boards, and it returns each currently published job with title, department, locations, remote/hybrid/on-site, employment type, the salary range when the employer publishes one, posting date, and the job and apply links.

Run it once for a snapshot, or schedule it with **Only jobs new since the last run** to get a daily or weekly feed of new openings at the companies you track.

### What you can use it for

- Track hiring at a list of target accounts (sales and market intelligence).
- Feed a niche job board or newsletter with roles from the employers you cover (see "Your responsibilities" below).
- Watch competitors' or portfolio companies' open roles and salary ranges over time.

### Input

| Field | What it does |
|---|---|
| **Companies** (required) | One per line. Use a board URL (`https://boards.greenhouse.io/figma`, `https://jobs.lever.co/palantir`, `https://jobs.ashbyhq.com/ramp`), a prefixed slug (`greenhouse:figma`, `lever:palantir`, `lever-eu:slug`, `ashby:ramp`), or the company's own careers page URL. |
| Default platform for bare slugs | Lets you list plain slugs such as `figma` when they are all on one platform. Without it, a plain slug is rejected (not charged), because the Actor never guesses which platform a company uses. |
| Keyword filter | Keeps jobs whose title, department or team contains any of the words. Turn on *Also match keywords in descriptions* to search the description too. |
| Location filter | Keeps jobs where any listed location, or the country code, contains one of the strings (e.g. `London`, `New York`, `Remote`). |
| Remote jobs only | Keeps jobs the employer marks remote, or whose location says "Remote". |
| Department filter | Keeps jobs whose department or team contains one of the strings. |
| Include description | On by default. Turn off for smaller, faster output. |
| Description format | `text` (HTML tags removed, wording unchanged) or `html` (markup as published). |
| Only jobs new since the last run | Outputs only jobs not delivered by an earlier run that used the same state store. The first run for each company outputs all matching jobs and records them. |
| State store name | The named key-value store in **your** Apify account that remembers delivered job IDs (IDs and dates only). Use one name per schedule or filter set. |
| Max jobs per run | Optional cap on delivered jobs (0 = no cap). |

**How careers-page detection works.** For a careers page URL, the Actor reads that one page (respecting its robots.txt) and looks for a Greenhouse, Lever or Ashby board link in the HTML. A bare domain also tries `/careers`. In our tests this found the board on 5 of 10 well-known careers pages (one more was closed to automated readers by its robots.txt). Pages that build their job list with JavaScript, or embed it differently, are reported as `invalid_input` and not charged; paste the board URL instead.

### Output

One dataset row per job:

| Field | Notes |
|---|---|
| `employer` | Company name from Greenhouse; for Lever and Ashby, which don't publish a name in their job feed, the board slug. |
| `title`, `department`, `team` | As published. |
| `location`, `locations`, `country` | Primary location, all listed locations, country code when published. |
| `workplaceType`, `isRemote` | `remote`, `hybrid` or `onsite` when the employer sets it; `isRemote` is also true when a location says "Remote". |
| `employmentType` | e.g. `full-time`, `contract` (Lever and Ashby; Greenhouse's job feed doesn't include it). |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryInterval`, `salaryText` | Only when the employer publishes a pay range. Otherwise empty. In our test about 47% of jobs had one, varying a lot by employer and location. |
| `postedAt`, `updatedAt` | ISO 8601 UTC. `updatedAt` is Greenhouse only. |
| `description` | Employer's description (if included). |
| `source`, `sourceHost`, `platform`, `sourceBoard`, `apiUrl` | Where the row came from: the job-board platform, its public endpoint, and the board slug. |
| `sourceUrl` | The job's own public page. |
| `applyUrl` | The employer's apply link, unchanged. |
| `retrievedAt` | When this run read the board. |
| `isNew`, `firstSeenAt` | Only in new-jobs mode. |

A **Run summary** record lists every company with its status (`ok`, `not_found`, `blocked`, `rate_limited`, `invalid_input`, `excluded`, `duplicate`, `skipped`), job counts and notes.

#### Example output

3 rows from our 2026-10-19 test run, unedited except that each `description` is cut to one line.

```json
[
  {
    "source": "Greenhouse",
    "sourceHost": "boards-api.greenhouse.io",
    "platform": "greenhouse",
    "sourceBoard": "figma",
    "apiUrl": "https://boards-api.greenhouse.io/v1/boards/figma/jobs?content=true&pay_transparency=true",
    "employer": "Figma",
    "jobId": "5426468004",
    "title": "Account Executive, Enterprise",
    "department": "Sales",
    "team": null,
    "location": "San Francisco, CA • New York, NY • United States",
    "locations": [
      "San Francisco, CA • New York, NY • United States",
      "US"
    ],
    "workplaceType": null,
    "isRemote": false,
    "employmentType": null,
    "salaryMin": 165000,
    "salaryMax": 190000,
    "salaryCurrency": "USD",
    "salaryInterval": "year",
    "salaryText": "Annual Base Salary Range: USD 165,000-190,000",
    "postedAt": "2025-01-28T23:57:29Z",
    "updatedAt": "2026-07-22T09:37:08Z",
    "sourceUrl": "https://boards.greenhouse.io/figma/jobs/5426468004?gh_jid=5426468004",
    "applyUrl": "https://boards.greenhouse.io/figma/jobs/5426468004?gh_jid=5426468004",
    "country": null,
    "description": "Figma is growing our team of passionate creatives and builders on a mission to make design accessible to all. Figma’s p…",
    "retrievedAt": "2026-10-19T18:02:50Z"
  },
  {
    "source": "Lever",
    "sourceHost": "api.lever.co",
    "platform": "lever",
    "sourceBoard": "palantir",
    "apiUrl": "https://api.lever.co/v0/postings/palantir?mode=json",
    "employer": "palantir",
    "jobId": "6ed76ce8-4156-4b60-b120-403538bd66cd",
    "title": "Administrative Business Partner",
    "department": "Administrative",
    "team": "Administrative",
    "location": "Singapore, Singapore",
    "locations": [
      "Singapore, Singapore"
    ],
    "workplaceType": "hybrid",
    "isRemote": false,
    "employmentType": "full-time",
    "salaryMin": null,
    "salaryMax": null,
    "salaryCurrency": null,
    "salaryInterval": null,
    "salaryText": null,
    "postedAt": "2026-08-11T17:38:11.368000Z",
    "updatedAt": null,
    "sourceUrl": "https://jobs.lever.co/palantir/6ed76ce8-4156-4b60-b120-403538bd66cd",
    "applyUrl": "https://jobs.lever.co/palantir/6ed76ce8-4156-4b60-b120-403538bd66cd/apply",
    "country": "SG",
    "description": "A World-Changing Company Palantir builds the world’s leading software for data-driven decisions and operations. By brin…",
    "retrievedAt": "2026-10-19T18:05:34Z"
  },
  {
    "source": "Ashby",
    "sourceHost": "api.ashbyhq.com",
    "platform": "ashby",
    "sourceBoard": "ramp",
    "apiUrl": "https://api.ashbyhq.com/posting-api/job-board/ramp?includeCompensation=true",
    "employer": "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)",
      "Miami, FL"
    ],
    "workplaceType": "hybrid",
    "isRemote": true,
    "employmentType": "full-time",
    "salaryMin": 211400,
    "salaryMax": 290600,
    "salaryCurrency": "USD",
    "salaryInterval": "year",
    "salaryText": "$211.4K - $290.6K",
    "postedAt": "2026-04-07T17:12:35.753000Z",
    "updatedAt": null,
    "sourceUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245",
    "applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application",
    "country": "USA",
    "description": "ABOUT RAMP Ramp is building the smart infrastructure for finance teams, embedded in the transaction flow of every dolla…",
    "retrievedAt": "2026-10-19T18:05:35Z"
  }
]
```

### Pricing (pay per event)

- **Job result: $0.001** per job row delivered to your dataset, after your filters. In new-jobs mode, only new jobs are charged.
- **Company checked: $0.001** per company whose board was read successfully.
- Not charged: companies that are not found, blocked, rate-limited, invalid or duplicated; jobs removed by your filters; jobs already delivered in new-jobs mode.
- No separate per-item or start fee. Your *max charge per run* is respected: the run stops cleanly when it is reached.

Examples: 1,000 jobs from about 6 companies ≈ $1.01. A daily new-jobs run over 100 companies that finds 20 new jobs ≈ $0.12.

### How it reads the data

- Only the platforms' public, unauthenticated job-board endpoints that serve currently published postings. No logins, cookies, API keys or accounts.
- One request at a time per host, never more than one per second, and an identifying User-Agent (`CompanyJobsFeed/1.0 (Apify Actor by ethical_acumen; …)`). No proxies.
- If a board host answers "blocked" or "too many requests", the Actor backs off, marks that company `blocked` or `rate_limited`, and doesn't charge for it. It does not retry through other IPs or identities.
- Ashby postings marked as unlisted are never output.

### Limits (tested 2026-10-19)

- Supports Greenhouse, Lever (US and EU) and Ashby boards only. Other job-board platforms are not supported.
- You bring the company list. This Actor doesn't search a jobs database or discover companies for you.
- Results are what each board publishes at run time. Jobs can close or change at any time, and boards differ in which fields they fill in.
- Large lists take time because of the one-request-per-second pacing. In our 50-company test, about 8,200 jobs took about 4.5 minutes of run time across three runs.

### Your responsibilities

Users are responsible for complying with applicable law, including privacy, anti-spam and employment-advertising rules, and any rights of the employers, in how they use, store or republish the output.

### Notices

- Not affiliated with, endorsed by, or sponsored by Greenhouse Software, Inc., Lever, Inc. (Employ), or Ashby, Inc. Greenhouse, Lever and Ashby are trademarks of their respective owners and are named only to identify supported data sources.
- Retrieves only currently published, publicly listed job postings from each employer's public job-board endpoint. No logins, private or unlisted jobs, or applicant data.
- Job postings, including descriptions, are the content of the hiring employer. They are provided as-is and may change or close at any time. Always use the included source URL to view or apply.
- **Employers:** to have your board excluded, or your descriptions omitted, open an Issue on this Actor's page. We act within 5 business days.

Questions or problems: open an Issue on the Actor page. We answer within 14 days.

# Actor input Schema

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

One company per line. Accepted forms: a job-board URL (https://boards.greenhouse.io/figma, https://jobs.lever.co/palantir, https://jobs.ashbyhq.com/ramp), a prefixed slug (greenhouse:figma, lever:palantir, lever-eu:slug, ashby:ramp), or the company's own careers page URL, which is scanned once (robots.txt respected) for a Greenhouse, Lever or Ashby board link. A bare slug needs a prefix or the Default platform setting; slugs are never guessed. Companies that can't be resolved are listed in the run summary and not charged.

## `defaultPlatform` (type: `string`):

Platform used for lines that are just a slug with no prefix, such as 'figma'. Leave empty to require a prefix or URL.

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

Keep only jobs whose title, department or team contains any of these words (case-insensitive). Leave empty for all jobs.

## `searchDescriptions` (type: `boolean`):

Also match keywords against the job description text (requires Include description).

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

Keep only jobs where any listed location (or the country code) contains one of these strings, e.g. 'New York', 'London', 'Remote'.

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

Keep only jobs marked remote by the employer, or whose location says 'Remote'.

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

Keep only jobs whose department or team contains one of these strings, e.g. 'Engineering', 'Sales'.

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

Include the employer's job description. Turn off for smaller, faster output.

## `descriptionFormat` (type: `string`):

Plain text removes HTML tags but keeps the employer's wording; HTML returns the description markup as published.

## `onlyNewJobs` (type: `boolean`):

Output only jobs not delivered by a previous run that used the same state store. The first run for each company outputs all matching jobs and records them. Use with a schedule to get a daily or weekly new-jobs feed.

## `stateStoreName` (type: `string`):

Name of the key-value store in your account that remembers which job IDs were already delivered (IDs and dates only). Use a different name per schedule or filter set. Lowercase letters, digits and hyphens.

## `maxJobs` (type: `integer`):

Stop after delivering this many jobs in total. 0 = no cap (your max charge per run still applies).

## `requestTimeoutSecs` (type: `integer`):

Timeout for each HTTP request.

## Actor input object example

```json
{
  "companies": [
    "https://boards.greenhouse.io/figma",
    "lever:palantir",
    "ashby:ramp"
  ],
  "defaultPlatform": "none",
  "keywords": [
    "engineer"
  ],
  "searchDescriptions": false,
  "remoteOnly": false,
  "includeDescription": true,
  "descriptionFormat": "text",
  "onlyNewJobs": false,
  "stateStoreName": "company-jobs-feed-state",
  "maxJobs": 200,
  "requestTimeoutSecs": 30
}
```

# Actor output Schema

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

One dataset item per open job that matched your filters.

## `runSummary` (type: `string`):

Per-company status (ok, not_found, blocked, rate_limited, excluded), job counts and notes. Companies that did not return a board are not charged.

# 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/figma",
        "lever:palantir",
        "ashby:ramp"
    ],
    "keywords": [
        "engineer"
    ],
    "maxJobs": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("ethical_acumen/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": [
        "https://boards.greenhouse.io/figma",
        "lever:palantir",
        "ashby:ramp",
    ],
    "keywords": ["engineer"],
    "maxJobs": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("ethical_acumen/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": [
    "https://boards.greenhouse.io/figma",
    "lever:palantir",
    "ashby:ramp"
  ],
  "keywords": [
    "engineer"
  ],
  "maxJobs": 200
}' |
apify call ethical_acumen/company-jobs-feed --silent --output-dataset

```

## MCP server setup

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