# Career Site Jobs Scraper: Greenhouse, Lever, Ashby & more (`augmentedhuman/career-site-jobs-scraper`) Actor

Scrape job postings straight from company career sites on 6 ATS platforms incl. EU-favourite Personio & Recruitee. One clean schema, salary when published, only-new-jobs mode for daily feeds. No login, no proxies, GDPR-minded.

- **URL**: https://apify.com/augmentedhuman/career-site-jobs-scraper.md
- **Developed by:** [Augmented Human](https://apify.com/augmentedhuman) (community)
- **Categories:** Jobs, Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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

## Career Site Jobs Scraper – Greenhouse, Lever, Ashby, Workable, Recruitee & Personio jobs API

**Scrape job postings directly from company career sites** – the original source, before they reach LinkedIn or Indeed. One Actor covers **6 applicant-tracking systems (ATS)** used by tens of thousands of startups and scale-ups, including the European favourites **Personio** and **Recruitee**. You get clean, normalised JSON / CSV / Excel, salary ranges when the company publishes them, and an **only-new-jobs mode** for daily job feeds and job alerts.

Built and maintained by **Augmented Human**.

✅ No login, no cookies, no proxies · ✅ Official public job-board endpoints · ✅ Fast (≈1,000 jobs in ~10 s) · ✅ GDPR-minded: recruiter names, e-mails and phone numbers are removed · ✅ Ready for AI agents (MCP / API)

### What does the Career Site Jobs Scraper do?

- 🔎 **Extracts every open job** from a company's Greenhouse, Lever, Ashby, Workable, Recruitee or Personio careers page
- 🧭 **Auto-detects the ATS** from a bare company slug or a careers URL (`https://jobs.lever.co/spotify`, `https://job-boards.greenhouse.io/figma`…)
- 🧹 **One unified schema** across all ATS: title, department, team, location, city, country, remote / hybrid, employment type, seniority, salary min/max/currency, posted date, job & apply URLs, description (text or HTML)
- 🎯 **Filters** by title keywords, excluded keywords, locations, remote-only and "posted within N days"
- 🔔 **Only new jobs since the previous run** – schedule it daily and receive only fresh postings
- 🤖 Plain-text descriptions ready for **LLM / RAG / AI agents** and job-matching pipelines

### Use cases

| Who | How they use it |
|---|---|
| Job boards & aggregators | Daily feed of new jobs from hundreds of target companies |
| Recruiters & staffing agencies | See which companies are hiring for your niche as soon as the role is posted |
| Sales / RevOps (hiring signals, lead generation) | "Company X opened 5 data-engineering roles" = buying intent for your product |
| VC & market research | Track headcount plans and team growth of portfolio or competitor companies |
| Job seekers & career coaches | Alerts for "remote + backend + Europe" across a list of dream companies |
| AI agents | Fetch structured, current openings for a company on demand |

### How to scrape career sites (step by step)

1. Click **Try for free**.
2. In **Companies**, add one company per line: `greenhouse:stripe`, `lever:spotify`, `ashby:linear`, `workable:huggingface`, `recruitee:bunq`, `personio:personio`, or simply paste the careers URL.
3. (Optional) Add title keywords such as `engineer`, `data`, and locations such as `Paris`, `Germany`, `Remote`.
4. Click **Start** and download your jobs as JSON, CSV, Excel or via the API.
5. For a daily feed: turn on **Only new jobs since previous run**, then create a **Schedule** in Apify Console.

**Where do I find the slug?** It is the company part of the careers URL: `jobs.lever.co/`**`spotify`**, `boards.greenhouse.io/`**`stripe`**, `jobs.ashbyhq.com/`**`linear`**, `apply.workable.com/`**`huggingface`**, **`bunq`**`.recruitee.com`, **`personio`**`.jobs.personio.de`.

### Input example

```json
{
  "companies": ["greenhouse:stripe", "lever:spotify", "ashby:linear", "https://apply.workable.com/huggingface"],
  "titleKeywords": ["engineer", "data"],
  "locations": ["France", "Germany", "Remote"],
  "onlyNewJobs": true,
  "stateKey": "eu-engineering"
}
```

### Output example

Real row from a test run (description shortened):

```json
{
  "id": "workable:huggingface:81B46579FE",
  "ats": "workable",
  "company": "Hugging Face",
  "companySlug": "huggingface",
  "title": "Open-Source Machine Learning Engineer - EMEA Remote",
  "department": "Open Source",
  "location": "Paris, Île-de-France, France",
  "city": "Paris", "country": "France", "countryCode": "FR",
  "remote": true,
  "employmentType": "Full-time",
  "salaryMin": null, "salaryMax": null, "salaryCurrency": null,
  "postedAt": "2026-05-29T00:00:00+00:00",
  "jobUrl": "https://apply.workable.com/j/81B46579FE",
  "applyUrl": "https://apply.workable.com/j/81B46579FE/apply",
  "descriptionText": "At Hugging Face, we're on a journey to democratize good AI. …",
  "isNew": true
}
```

Run statistics (companies found / not found, errors) are saved as `RUN_STATS` in the key-value store.

### Supported ATS & tips

| ATS | Input | Salary | Notes |
|---|---|---|---|
| Greenhouse | `greenhouse:slug` | – | US/EU tech companies |
| Lever | `lever:slug` | ✅ when published | EU-hosted boards supported |
| Ashby | `ashby:slug` | ✅ when published | Fast-growing startups |
| Workable | `workable:slug` | – | SMEs worldwide |
| Recruitee | `recruitee:slug` | ✅ when published | Popular in NL/BE/FR/DE |
| Personio | `personio:slug` | – | #1 HR suite in DACH |

SmartRecruiters is **not** supported because its API's robots.txt disallows automated access – we respect it.

### How much does it cost?

See the **Pricing** tab for the current price. The Actor is HTTP-only and very light: a cloud test fetched 864 jobs from 6 companies in ~50 seconds using ~0.0035 compute units. With **only new jobs** on, a scheduled daily feed only returns (and only costs you for) fresh postings. Apify's free plan credits are enough to try it.

### How an AI agent can call it

- **Apify MCP server**: add `augmentedhuman/career-site-jobs-scraper` as a tool in any MCP client (Claude, Cursor, ChatGPT connectors, etc.) via `https://mcp.apify.com`. The agent passes `companies` and optional filters and gets jobs back as JSON.
- **One HTTP call** (synchronous, returns the dataset):

```bash
curl -X POST "https://api.apify.com/v2/acts/augmentedhuman~career-site-jobs-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"companies":["ashby:linear"],"titleKeywords":["engineer"],"maxJobs":50}'
```

- **Python**: `ApifyClient(token).actor("augmentedhuman/career-site-jobs-scraper").call(run_input={...})`
- Also works from Make, Zapier, n8n and LangChain through the standard Apify integrations.

### How does it compare to other job scrapers?

Honest note: Apify Store has strong alternatives. Single-ATS scrapers (e.g. Greenhouse-only or Lever-only) can go deeper on one platform, and aggregated job databases cover far more companies without you having to list them. Pick this Actor when you **know which companies you care about** and want **one schema across 6 ATS**, **only-new-jobs** daily feeds, and **European ATS (Personio, Recruitee)**. If you need LinkedIn/Indeed search results or Workday/iCIMS/SmartRecruiters companies, use a different tool.

### FAQ

**Is scraping career sites legal?** This Actor only reads public job-board endpoints that companies publish so their jobs can be syndicated. It does not log in or bypass any protection, honours robots.txt and rate limits, and strips personal data (recruiter names, e-mails, phone numbers). You remain responsible for how you use the data (GDPR, site terms). Not legal advice.

**A company is "not found".** Check the slug, or prefix the ATS (`lever:acme`). If the company uses another ATS (Workday, iCIMS, Teamtailor…), open an issue – new ATS are added based on demand.

**Can I get only remote jobs, or only jobs posted this week?** Yes: `remoteOnly: true` and `postedWithinDays: 7`.

**Can I use it from Make, Zapier, n8n, Python or an AI agent?** Yes – via the Apify API, integrations, or the Apify MCP server (see above).

**Something broke?** Open an issue on the **Issues** tab – the Actor is health-checked daily.

# Actor input Schema

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

One company per line. Use 'ats:slug' (e.g. greenhouse:stripe, lever:spotify, ashby:linear, workable:huggingface, recruitee:bunq, personio:personio), a careers-page URL (e.g. https://jobs.lever.co/spotify), or a bare slug to auto-detect the ATS (slower).

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

Keep only jobs whose title contains at least one of these words (case-insensitive). Empty = all jobs.

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

Drop jobs whose title contains any of these words, e.g. 'intern', 'senior'.

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

Keep jobs whose location/city/country contains one of these strings, e.g. 'Paris', 'France', 'FR', 'Berlin'.

## `includeRemoteInLocationFilter` (type: `boolean`):

If on, remote jobs pass the location filter even if their location does not match.

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

Keep only jobs flagged as remote by the ATS.

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

0 = no date filter. Not every ATS publishes a posting date; jobs without one are kept.

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

Perfect for scheduled daily runs: outputs (and charges) only jobs not seen in previous runs with the same State key.

## `stateKey` (type: `string`):

Name of the 'seen jobs' memory used by 'Only new jobs'. Use different keys for different watch-lists.

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

Include the full job description. Turn off for faster, smaller runs.

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

Plain text is best for LLM / RAG pipelines; HTML keeps formatting.

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

Upper bound of jobs taken from a single company board.

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

0 = unlimited. The run also stops gracefully when your maximum cost per run is reached.

## `maxConcurrency` (type: `integer`):

Kept low on purpose to be polite to ATS servers.

## `minDelaySecs` (type: `number`):

Rate limit per host.

## Actor input object example

```json
{
  "companies": [
    "greenhouse:stripe",
    "lever:spotify",
    "ashby:linear",
    "workable:huggingface",
    "recruitee:bunq",
    "personio:personio"
  ],
  "titleKeywords": [],
  "excludeTitleKeywords": [],
  "locations": [],
  "includeRemoteInLocationFilter": true,
  "remoteOnly": false,
  "postedWithinDays": 0,
  "onlyNewJobs": false,
  "stateKey": "default",
  "includeDescription": true,
  "descriptionFormat": "text",
  "maxJobsPerCompany": 1000,
  "maxJobs": 0,
  "maxConcurrency": 4,
  "minDelaySecs": 0.5
}
```

# Actor output Schema

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

No description

## `stats` (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": [
        "greenhouse:stripe",
        "lever:spotify",
        "ashby:linear",
        "workable:huggingface",
        "recruitee:bunq",
        "personio:personio"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("augmentedhuman/career-site-jobs-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": [
        "greenhouse:stripe",
        "lever:spotify",
        "ashby:linear",
        "workable:huggingface",
        "recruitee:bunq",
        "personio:personio",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("augmentedhuman/career-site-jobs-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": [
    "greenhouse:stripe",
    "lever:spotify",
    "ashby:linear",
    "workable:huggingface",
    "recruitee:bunq",
    "personio:personio"
  ]
}' |
apify call augmentedhuman/career-site-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,augmentedhuman/career-site-jobs-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/mXxfDJhFjYXkYiDJy/builds/dDIgJhN9thOYFyEzw/openapi.json
