# Job Search API: Career Site Jobs (Greenhouse, Lever, Ashby) (`saadhazz/career-site-job-search`) Actor

Search 400,000+ jobs straight from 13,000+ company career sites (Greenhouse, Lever, Ashby, Workable, Recruitee, Personio) by keyword, country, remote and date. Live-verified, salary where published, new-job alerts. Official public APIs, $2 per 1,000 jobs.

- **URL**: https://apify.com/saadhazz/career-site-job-search.md
- **Developed by:** [saad hazz](https://apify.com/saadhazz) (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

$2.00 / 1,000 jobs

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

## Job Search API: Career Site Jobs from Greenhouse, Lever, Ashby, Workable & more

**Search 400,000+ open jobs posted directly on 13,000+ company career sites, and filter by job title, country, remote, date and ATS platform.** Results come back in one clean, consistent JSON schema with salary (where the employer publishes it), apply links and optional full descriptions. Each match is **verified live** against the company's career site, so closed jobs are dropped. Alert mode returns **only jobs that are new since your last run**.

You get first-party jobs from the employer's own applicant tracking system (ATS), so there are no reposts, no aggregator spam and no LinkedIn or Indeed scraping. The price is **$2 per 1,000 jobs**, and you pay only for jobs returned.

### What you can do with it

- **Job boards and niche job sites:** fill your board with fresh, original postings, e.g. "remote Python jobs in Europe posted this week".
- **Job alerts and newsletters:** schedule the Actor daily with alert mode on, and send only the new jobs.
- **Recruiting and sales intelligence:** see which companies are hiring for a role or in a country right now.
- **Labor-market research:** track hiring by title, country, salary range and platform.
- **AI job-matching apps and agents:** feed structured job data into your pipeline through the Apify API or MCP.

### Greenhouse jobs API, Lever jobs API and Ashby jobs API in one search

Greenhouse, Lever, Ashby, Workable, Recruitee, Personio and SmartRecruiters each publish a free public job-board API, but every API is per company: you need to know the company's board slug first, and each one returns a different JSON format. This Actor does the hard part for you. It keeps a daily index of 13,000+ company boards, normalizes every job into one schema, and lets you **search all of them at once by job title, country, remote and posting date**, like a job search engine with an API. Use it as a job postings API, a hiring-data feed, or a LinkedIn-jobs alternative built only on first-party employer postings.

### Coverage

| ATS / career-site platform | Career sites indexed | Open jobs (index of Oct 2026) |
|---|---|---|
| Greenhouse | ~4,850 | ~180,000 |
| Workable | ~1,750 | ~83,000 |
| Lever | ~1,700 | ~72,000 |
| Ashby | ~3,000 | ~57,000 |
| Recruitee | ~990 | ~17,500 |
| Personio | ~830 | ~9,500 |
| SmartRecruiters | 7 large employers (Bosch, ServiceNow, AbbVie…) + any company via `extraCompanyBoards` | ~6,800 |

The index is rebuilt from the official public job-board APIs of each ATS. The `SEARCH_SUMMARY` record of every run shows the exact index date and size. Need a company that isn't covered? Add it as `greenhouse:airbnb`, `lever:company`, `smartrecruiters:Visa` and so on in **Extra company career sites**, and it is fetched live.

### How it works

1. **Search the index.** Your filters run against a compact index of every open job on the covered career sites. This takes a few seconds.
2. **Verify live.** The career sites behind the newest matches are re-fetched now through each ATS's public API. Closed jobs are removed, new ones are added, and salary and descriptions are filled in. Each row has `dataSource: "live"` or `"index"`.
3. **Alert mode (optional).** The Actor remembers which jobs it already returned for this search, in a named key-value store in *your* account, and returns only new ones.

### Input examples

**Remote data engineering jobs posted in the last 3 days:**

```json
{ "keywords": ["data engineer", "analytics engineer"], "remoteOnly": true, "postedWithinDays": 3, "maxJobs": 500 }
```

**Product manager jobs in Germany or the UK, with descriptions:**

```json
{ "keywords": ["product manager"], "locations": ["Germany", "United Kingdom"], "postedWithinDays": 14, "includeDescription": true }
```

**Daily job alert (schedule it in Apify; each run returns only the new jobs):**

```json
{ "keywords": ["machine learning engineer"], "locations": ["US"], "onlyNewSinceLastRun": true, "alertId": "ml-us", "postedWithinDays": 30, "maxJobs": 1000 }
```

**Everything a few companies have open (plus SmartRecruiters companies):**

```json
{ "keywords": [], "companies": ["stripe", "notion"], "extraCompanyBoards": ["smartrecruiters:Ubisoft2"], "postedWithinDays": 0 }
```

#### Filter rules

- `keywords`: a job matches if its **title** contains all words of any keyword, in any order. `"data engineer"` matches "Senior Engineer, Data Platform".
- `excludeKeywords`: drops titles containing any of these words, e.g. `intern`, `senior`, `manager`.
- `locations`: country names or ISO codes (`Germany`, `DE`, `USA`) match the detected country. Other text (`Berlin`, `EMEA`, `Remote - Europe`) matches the location string.
- `remoteOnly`, `postedWithinDays`, `companies`, `ats`, `employmentTypes` (`full-time`, `part-time`, `contract`, `intern`).

### Output example

```json
{
  "jobId": "33454cb1-a782-4412-887e-795259e0f7dc",
  "title": "Software Engineering Manager (Mission Ops)",
  "companyName": "Sift",
  "companySlug": "siftstack",
  "ats": "ashby",
  "location": "Marina Del Rey, CA",
  "country": "US",
  "countryName": "United States",
  "isRemote": false,
  "workplaceType": "hybrid",
  "employmentType": "FULL_TIME",
  "department": "Engineering",
  "salaryMin": 200000,
  "salaryMax": 265000,
  "salaryCurrency": "USD",
  "salaryPeriod": "YEAR",
  "salaryText": "$200K – $265K • Offers Equity • Offers Benefits",
  "postedAt": "2026-10-08T20:22:47Z",
  "jobUrl": "https://jobs.ashbyhq.com/siftstack/33454cb1-a782-4412-887e-795259e0f7dc",
  "applyUrl": "https://jobs.ashbyhq.com/siftstack/33454cb1-a782-4412-887e-795259e0f7dc/application",
  "boardUrl": "https://jobs.ashbyhq.com/siftstack",
  "descriptionText": null,
  "dataSource": "live",
  "isNew": null,
  "scrapedAt": "2026-10-09T06:35:31Z"
}
```

All dates are ISO 8601 UTC. `employmentType` is normalized to `FULL_TIME`, `PART_TIME`, `CONTRACT`, `TEMPORARY` or `INTERN` when it can be recognized, and otherwise keeps the employer's label. `salaryPeriod` is `YEAR`, `MONTH`, `WEEK`, `DAY` or `HOUR`. You can download the dataset as JSON, CSV, Excel or XML, or read it from the API.

### How it compares

| | This Actor | LinkedIn / Indeed scrapers | Per-company ATS scrapers | Premium career-site job APIs |
|---|---|---|---|---|
| Search by title and country across thousands of companies | ✅ | ✅ | ❌ (you supply company lists) | ✅ |
| Original employer postings, no reposts | ✅ | ❌ | ✅ | ✅ |
| Proxies, logins, CAPTCHAs | none | often | none | none |
| Live verification of matches | ✅ | n/a | ✅ | varies |
| Only-new-jobs alert mode | ✅ | rarely | ❌ | varies |
| Price per 1,000 jobs | **$2** | $1–$10 + proxy | ~$1 | often $10+ |

Need every job from a known list of companies, including SmartRecruiters? Use the sister Actor [ATS Jobs API](https://apify.com/saadhazz/ats-jobs-api). Looking for remote-only job boards (Himalayas, Remote OK, Jobicy, Arbeitnow)? See [Remote Jobs API](https://apify.com/saadhazz/remote-jobs-aggregator).

### Run it from code: API, Python, JavaScript or cURL

Every Apify Actor is also a REST API. Get your token in Apify Console under **Settings → API & Integrations**, then:

**cURL** (runs the Actor and returns the matching jobs in one call):

```bash
curl -X POST "https://api.apify.com/v2/acts/saadhazz~career-site-job-search/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keywords": ["data engineer"], "remoteOnly": true, "postedWithinDays": 3, "maxJobs": 100}'
```

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("saadhazz/career-site-job-search").call(run_input={"keywords": ["data engineer"], "remoteOnly": true, "postedWithinDays": 3, "maxJobs": 100})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript / Node.js** (`npm i apify-client`):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('saadhazz/career-site-job-search').call({"keywords": ["data engineer"], "remoteOnly": true, "postedWithinDays": 3, "maxJobs": 100});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Use it with AI agents (MCP), Make, Zapier, n8n and Google Sheets

- **AI agents and LLM apps:** connect Claude, Cursor, ChatGPT or any MCP client to `https://mcp.apify.com/?tools=saadhazz/career-site-job-search` and the agent can call this Actor as a tool.
- **No-code:** use the official Apify integrations for Make, Zapier and n8n, or export the dataset straight to Google Sheets, CSV, Excel or JSON.
- **Scheduling and webhooks:** create a Schedule in Apify Console (e.g. every morning) and add a webhook or Slack/email integration to get notified when new data is ready.

### Pricing

**$2.00 per 1,000 jobs** returned ($0.002 per job). Filtered-out jobs, failed sites and runs with zero results cost nothing beyond Apify platform usage. Set **Max jobs** or a maximum charge per run to control spend, and the Actor stops cleanly at your limit.

### FAQ

**Is this legal?** The Actor reads only the **public job-board APIs** that Greenhouse, Lever, Ashby, Workable, Recruitee, Personio and SmartRecruiters provide so that companies can publish their openings on other sites. No login, no personal data, no anti-bot workarounds. Results contain job postings only, and recruiter names or emails are never collected.

**How fresh is it?** The index is rebuilt regularly (the date is in `SEARCH_SUMMARY`), and with **Verify matches live** (the default) the jobs you get are checked against the career site at run time.

**Why did a job I see on a company site not appear?** The company may use an ATS we don't index yet, or the job title may not contain your keyword. Add the company in `extraCompanyBoards` or broaden your keywords.

**Can I use it from code, Make, Zapier, n8n or an AI agent?** Yes. Use the Apify API, the integrations, or the Apify MCP server.

**Is there a free job search API?** The ATS job-board APIs are free but only work one company at a time. This Actor searches all indexed companies in one call for $2 per 1,000 jobs, and new Apify accounts get free monthly platform credit, enough for thousands of jobs.

**How do I get all jobs from Greenhouse (or Lever, or Ashby)?** Set **Career-site platforms (ATS)** to `greenhouse` (or `lever`, `ashby`), leave keywords empty, set `postedWithinDays` to `0` and raise `maxJobs`. For one known company, use the company filter or the sister [ATS Jobs API](https://apify.com/saadhazz/ats-jobs-api).

**How much does 10,000 jobs cost?** $20 at $2 per 1,000 jobs, plus a few cents of Apify platform usage. You only pay for jobs actually returned.

**Do you include LinkedIn or Indeed jobs?** No. Only jobs that employers publish on their own career sites. That means no reposts and no expired aggregator copies, and no scraping of sites that forbid it.

**Can I build a job board or job alert newsletter with it?** Yes, that is the main use case. Schedule a daily run with alert mode on, push new jobs to your database, and link each job to its `applyUrl`.

### Credits

The career-site directory is seeded in part from the open datasets [job-board-directory](https://github.com/kalebconfer-sys/job-board-directory) (CC0) and [LastRound AI hiring data](https://github.com/fyrosofttech/lastroundai-hiring-data) (CC BY 4.0). Live boards are re-validated on every index build.

### More data APIs from the same developer

- [ATS Jobs API](https://apify.com/saadhazz/ats-jobs-api): every open job from a list of companies on Greenhouse, Lever, Ashby, SmartRecruiters or Recruitee, in one schema. $1 / 1,000 jobs.
- [Remote Jobs API](https://apify.com/saadhazz/remote-jobs-aggregator): remote and work-from-home jobs from Remote OK, Himalayas, Jobicy and Arbeitnow, deduplicated. $1 / 1,000 jobs.
- [Bulk WHOIS & RDAP Lookup](https://apify.com/saadhazz/domain-whois-rdap): domain expiry dates, registrar, age, status, nameservers, MX/SPF/DMARC for thousands of domains. $1 / 1,000 domains.
- [Sitemap URL Extractor](https://apify.com/saadhazz/sitemap-url-extractor): every URL a website lists in its XML sitemaps, with lastmod, hreflang and optional HTTP status. $0.40 / 1,000 URLs.
- [PDF Text Extractor](https://apify.com/saadhazz/pdf-text-extractor): PDF URLs to clean page-by-page text, Markdown tables and metadata for RAG/LLM pipelines.
- [SEC EDGAR Filings Monitor](https://apify.com/saadhazz/sec-filings-monitor): new 8-K, 10-Q, 10-K and Form 4 filings for a list of tickers from the official SEC API.

Found a bug or need a field? Open an issue on the Issues tab; Issues are checked daily.

# Actor input Schema

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

A job matches if its title contains ALL words of ANY keyword, e.g. 'data engineer' matches 'Senior Data Engineer'. Leave empty to match every title.

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

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

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

Country names or ISO codes (e.g. 'Germany', 'US', 'United Kingdom') match the detected country; anything else (e.g. 'Berlin', 'EMEA') matches the location text. Empty = worldwide.

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

Keep only jobs marked remote by the employer.

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

Only jobs first published in the last N days. 0 = any date (jobs without a published date are then included).

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

Only jobs from companies whose name or career-site slug contains one of these, e.g. 'stripe', 'notion'.

## `ats` (type: `array`):

Platforms to search. Empty = all.

## `employmentTypes` (type: `array`):

Optional, e.g. 'full-time', 'part-time', 'contract', 'intern'. Matched against the employer's own label.

## `extraCompanyBoards` (type: `array`):

Add boards not in the index as 'ats:slug', e.g. 'greenhouse:airbnb', 'smartrecruiters:Visa'. They are fetched live and filtered the same way.

## `onlyNewSinceLastRun` (type: `boolean`):

Remembers jobs already returned for this search (in a named key-value store in your account) and returns only new ones. Schedule the Actor daily for a job alert.

## `alertId` (type: `string`):

Name for this alert's memory. If empty, a hash of the search filters is used.

## `liveRefresh` (type: `boolean`):

Re-fetch the matched companies' career sites now so closed jobs are dropped and the newest jobs added. Off = instant index-only results.

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

Adds the plain-text description (forces live verification; slower).

## `maxLiveCompanies` (type: `integer`):

Caps live re-fetching per run. Matches from other companies come from the daily index.

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

Maximum jobs to return (you pay per job returned).

## Actor input object example

```json
{
  "keywords": [
    "software engineer",
    "data scientist"
  ],
  "excludeKeywords": [],
  "locations": [
    "United States"
  ],
  "remoteOnly": false,
  "postedWithinDays": 7,
  "companies": [],
  "ats": [],
  "employmentTypes": [],
  "extraCompanyBoards": [],
  "onlyNewSinceLastRun": false,
  "alertId": "",
  "liveRefresh": true,
  "includeDescription": false,
  "maxLiveCompanies": 200,
  "maxJobs": 100
}
```

# Actor output Schema

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

One job posting per item, newest first.

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

Index date and size, matches in index, jobs returned and verified live.

## `runStats` (type: `string`):

Counters for HTTP outcomes and errors in this run.

# 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 = {
    "keywords": [
        "software engineer",
        "data scientist"
    ],
    "locations": [
        "United States"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("saadhazz/career-site-job-search").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 = {
    "keywords": [
        "software engineer",
        "data scientist",
    ],
    "locations": ["United States"],
}

# Run the Actor and wait for it to finish
run = client.actor("saadhazz/career-site-job-search").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 '{
  "keywords": [
    "software engineer",
    "data scientist"
  ],
  "locations": [
    "United States"
  ]
}' |
apify call saadhazz/career-site-job-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,saadhazz/career-site-job-search"
        }
    }
}
```

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/s3QKfErsw08I2KWuY/builds/c9b9oay2HwNYPGYAY/openapi.json
