# Greenhouse, Lever, Ashby & Workable Jobs API - Personio (`digivibetech/greenhouse-lever-jobs-feed`) Actor

Get every open job from company career pages on Greenhouse, Lever, Ashby, Workable and Personio via their public job feeds: title, location, remote, department, salary, dates, description. Filter by keyword, location, salary; only-new-jobs mode for alerts. $0.0008 per job. Built with AI assistance.

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

## Pricing

$0.80 / 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, Lever, Ashby & Workable Jobs API - Personio

Get **every open job** from company career boards hosted on **Greenhouse**, **Lever** (global and EU), **Ashby**, **Workable** and **Personio** (popular with European companies), using their **public job-board APIs and feeds**. One clean, consistent JSON schema for all five: `title`, `location`, all `locations`, `remote`, `workplaceType`, `department`, `team`, `employmentType`, `salary` (min/max/currency/interval when the company publishes it), `postedAt`/`updatedAt` (ISO 8601, UTC), `url`, `applyUrl` and a plain-text `descriptionText`.

**$0.0008 per job delivered** (1,000 jobs = $0.80), no start fee. Boards that are unknown, fail or are disallowed are **free**. Filters are applied **before** you are charged.

### Quick start: example input, output and cost

Company job listings from Greenhouse, Lever, Ashby, Workable and Personio public feeds as JSON: salary, remote, filters, only new jobs. $0.80 per 1,000 jobs.

**Example input**

```json
{
  "companies": [
    "https://job-boards.greenhouse.io/gitlab",
    "https://jobs.lever.co/palantir"
  ]
}
```

**Cost example:** 20 companies with ~1,500 open jobs x $0.0008 = **$1.20**.

### Highlights

- **Paste board URLs as you see them**: `https://job-boards.greenhouse.io/gitlab`, `https://boards.greenhouse.io/acme/jobs/123`, `https://jobs.lever.co/palantir`, `https://jobs.eu.lever.co/...`, `https://<company>.jobs.personio.de`, or `greenhouse:<board>` / `lever:<board>` / `personio:<company>`.
- **Only new jobs** (`onlyNewJobs` or `monitorName`): schedule it daily and receive, and pay for, only jobs you have not seen yet. Ideal for job alerts, hiring-signal tracking and recruiting dashboards via Apify integrations (Slack, email, Google Sheets, webhooks).
- **Filters**: title keywords (include/exclude), location keywords (city, country, country code, "Remote"), remote only, posted within N days, max jobs per company (newest first).
- **Minimum salary** filter (`minSalary`, optionally `keepJobsWithoutSalary`), **posted before** a date (`postedBefore`) and **merge duplicate posts** of the same role in several cities (`mergeDuplicates`).
- `yearsExperienceMin`: the smallest "N years of experience" requirement found in the description (or `null`).
- Description text with HTML removed; email addresses and phone numbers are redacted.

### Input

`companies` (required), `titleKeywords`, `excludeTitleKeywords`, `locationKeywords`, `remoteOnly`, `postedWithinDays`, `postedBefore`, `minSalary`, `keepJobsWithoutSalary`, `mergeDuplicates`, `maxJobsPerCompany` (default 1,000), `includeDescription` (default true), `personioLanguage` (default en), `onlyNewJobs`, `monitorName`.

### Output (one item per job)

`ats, company, companyName, jobId, jobKey, title, url, applyUrl, location, locations[], country, remote, workplaceType, department, team, employmentType, salary{min,max,currency,interval}, postedAt, updatedAt, language, yearsExperienceMin, descriptionText, duplicateJobIds (when merging), input, fetchedAt`

Not every field exists on every platform (for example `country` and `salary` come from Lever/Greenhouse, `companyName` from Greenhouse/Workable/Personio; salary also from Ashby); missing values are `null`. Failed boards and reasons are in **ERRORS**; totals in **SUMMARY**.

### Which job boards are supported?

Greenhouse and Lever publish these APIs for public use: Greenhouse states that job-board data "is publicly available" without authentication, Lever states that published postings are publicly viewable and may be read by third parties, and Personio documents its career-site XML feed as public, without credentials, for integrating jobs into other websites. Workable boards are read from the public careers-widget feed at apply.workable.com, which is what Workable's own embeddable careers page uses (no login, no key); its robots.txt allows all paths. Only company and job fields are returned: no recruiter or hiring-manager names, and e-mail addresses and phone numbers in descriptions are redacted. Ashby boards are read from Ashby's officially documented public Job Postings API (developers.ashbyhq.com), with compensation when the company publishes it; unlisted postings are skipped. SmartRecruiters is not supported because its API robots.txt disallows automated access. Other applicant-tracking systems are not included where their robots.txt does not allow automated access.

### Limits

- Only public job boards on the listed ATS platforms. Company career pages on other systems, LinkedIn and Indeed are not covered.
- Salary and experience fields are only as good as the posting: many jobs publish no salary, and `yearsExperienceMin` is read from the text.
- `onlyNewJobs` remembers job ids per monitor; a new `monitorName` starts from scratch.

### Responsible use

One API request per company board, at most about one request per second per host, Crawl-delay honoured, honest User-Agent (`JobsFeed/1.0`). We never log in, never use the application endpoints and never bypass bot protection. The output contains company job posts only, with no applicant or recruiter fields. Job descriptions belong to the companies: link back to the original post when you republish them.

### Pricing

| Event | Price |
|---|---|
| Job delivered (`job-listed`) | $0.0008 |

Set a maximum cost per run in Apify and the actor stops delivering jobs before it would exceed it.

*Built with AI assistance and maintained by DigiVibeTech. Not affiliated with Greenhouse Software, Lever, Ashby, Workable or Personio. Questions or bugs: use the Issues tab; we reply within 2 working days.*

# Actor input Schema

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

Greenhouse, Lever, Ashby, Workable or Personio board URLs (https://job-boards.greenhouse.io/gitlab, https://jobs.lever.co/palantir, https://jobs.eu.lever.co/..., https://jobs.ashbyhq.com/<company>, https://apply.workable.com/<company>, https://<company>.jobs.personio.de) or 'greenhouse:<board>' / 'lever:<board>' / 'ashby:<board>' / 'workable:<account>' / 'personio:<company>'. Up to 2,000 per run.

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

Case-insensitive. Empty = all jobs.

## `excludeTitleKeywords` (type: `array`):

Case-insensitive, e.g. 'intern', 'senior'.

## `locationKeywords` (type: `array`):

Matches location, all locations and country code, e.g. 'Berlin', 'Germany', 'DE', 'Remote'.

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

Keep only jobs marked remote (workplace type or 'Remote' in the location/title).

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

Optional. Jobs without a posting date are skipped when this is set.

## `postedBefore` (type: `string`):

Optional date (YYYY-MM-DD): only jobs first posted before this date (e.g. to find long-open roles). Jobs without a posting date are skipped when this is set.

## `minSalary` (type: `integer`):

Keep jobs whose published salary range reaches at least this amount (same currency/interval as the post; most posts are yearly). Jobs without a published salary are skipped unless 'Keep jobs without salary' is on.

## `keepJobsWithoutSalary` (type: `boolean`):

With a minimum salary set: also keep jobs that publish no salary.

## `mergeDuplicates` (type: `boolean`):

One job per company + title + department: posts of the same role in several cities are merged (all locations kept, other post IDs in duplicateJobIds). You pay per merged job.

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

Newest first, after filters.

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

Plain-text job description (HTML removed, max 20,000 characters, emails/phone numbers redacted).

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

For scheduled monitoring: remembers delivered jobs in a named key-value store and returns only new ones. You pay only for new jobs.

## `monitorName` (type: `string`):

Use different names to keep separate 'seen jobs' lists (lowercase letters, digits, dashes). Setting it turns on 'only new jobs'.

## `personioLanguage` (type: `string`):

Language of Personio job texts (if the company publishes that language).

## Actor input object example

```json
{
  "companies": [
    "https://job-boards.greenhouse.io/gitlab",
    "https://jobs.lever.co/palantir"
  ],
  "remoteOnly": false,
  "keepJobsWithoutSalary": false,
  "mergeDuplicates": false,
  "maxJobsPerCompany": 1000,
  "includeDescription": true,
  "onlyNewJobs": false,
  "personioLanguage": "en"
}
```

# Actor output Schema

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

All result items (overview view)

## `errors` (type: `string`):

Inputs that could not be processed, with the reason

## `summary` (type: `string`):

Counts of processed, billed and failed items

# 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://job-boards.greenhouse.io/gitlab",
        "https://jobs.lever.co/palantir"
    ]
};

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

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

```

## MCP server setup

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