# Career Site Jobs API: Greenhouse, Lever, Ashby, SmartRecruiters (`magenta_waterwheel/career-site-jobs-api`) Actor

Job postings API for company career sites on Greenhouse, Lever, Ashby and SmartRecruiters. Get salary ranges, location, remote flag and full descriptions from 8,500+ verified companies. Filter by title, location and date. Incremental mode returns only new or changed jobs. $2 per 1,000 jobs.

- **URL**: https://apify.com/magenta_waterwheel/career-site-jobs-api.md
- **Developed by:** [Huss](https://apify.com/magenta_waterwheel) (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

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

## Career Site Jobs API: Greenhouse, Lever, Ashby & SmartRecruiters

**Career Site Jobs API** pulls open job listings straight from company career sites hosted on **Greenhouse, Lever, Ashby and SmartRecruiters**. It reads the official public job-board APIs those platforms offer, so you get clean, structured data: title, department, location, remote or hybrid flag, employment type, **salary range** (where published), posting date, apply link and the full job description.

Give it a list of companies, or use the **built-in list of 8,500+ verified companies**, filter by keyword, location, remote or posting date, and export to JSON, CSV, Excel or straight into your app via API. Turn on **incremental mode** to get only new or changed jobs on every scheduled run.

### What can Career Site Jobs API do?

- 🏢 **Scrape any company on Greenhouse, Lever, Ashby or SmartRecruiters.** Use a short token such as `greenhouse:airbnb` or paste the career-page URL.
- 📚 **Search across 8,500+ companies at once** with the built-in, pre-verified company list.
- 💰 **Get salary data** published by the employer (min, max, currency, interval) on Greenhouse, Lever and Ashby boards that publish pay ranges.
- 🔎 **Filter** by title keywords, excluded keywords, location, remote only, and posted within N days.
- 🔁 **Monitor job boards** with incremental mode: output only `NEW` and `CHANGED` jobs, and optionally `REMOVED` ones.
- 🧾 **Plain-text or HTML descriptions**, ready for search indexes, LLMs and RAG pipelines.
- ⚡ **Fast and reliable.** It uses official JSON endpoints, not HTML scraping or browsers, so there are no proxies to pay for and nothing breaks when a site's design changes.
- 🤖 **Works great for AI agents** via the Apify API, MCP server, or integrations such as Make, Zapier and n8n.

### Why use Career Site Jobs API?

Jobs on company career sites are the **original source**: they appear there first, include the employer's own salary range and full description, and disappear when the role is filled. Job boards and aggregators repost them later, often without pay data.

|                                   | Career Site Jobs API                   | Job-board scrapers (LinkedIn, Indeed) | Job-data subscriptions    |
| --------------------------------- | -------------------------------------- | ------------------------------------- | ------------------------- |
| Data source                       | Employer's own ATS job board           | Reposted listings                     | Mixed, often cached       |
| Freshness                         | Live at run time                       | Varies                                | Daily or weekly snapshots |
| Salary ranges                     | Yes, where the employer publishes them | Sometimes                             | Sometimes                 |
| Login, proxies or anti-bot issues | None (official public APIs)            | Common                                | n/a                       |
| Only new or changed jobs          | Built in (incremental mode)            | Rare                                  | Rare                      |
| Price                             | **$2 per 1,000 jobs**, pay as you go   | Varies                                | Monthly contract          |

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

- **Greenhouse jobs API**: every open role on `boards.greenhouse.io` and `job-boards.greenhouse.io` boards, with departments, offices and pay ranges.
- **Lever jobs API**: postings from `jobs.lever.co` and `jobs.eu.lever.co`, including team, commitment, workplace type and salary.
- **Ashby jobs API**: postings from `jobs.ashbyhq.com`, with compensation tiers, remote flag and employment type.
- **SmartRecruiters jobs API**: postings from `jobs.smartrecruiters.com`, including full descriptions and experience level.

All four come out in **one normalized schema**, so you don't have to write and maintain four integrations.

### Who is it for?

- **Job boards and aggregators** that need fresh, first-party listings from employers.
- **Recruiters and sales teams** looking for companies that are hiring for specific roles (hiring signals).
- **Labor-market and salary researchers** who need structured postings with pay ranges.
- **Job seekers and AI agents** that track new openings at target companies.
- **HR tech and AI startups** that need a reliable jobs feed for matching, enrichment or LLM training data.
- **Investors and analysts** watching hiring velocity as a growth signal.

### How to scrape company career sites

1. Click **Try for free**.
2. In **Companies**, add one company per line, for example `greenhouse:airbnb`, `lever:palantir`, `ashby:ramp` or `https://jobs.smartrecruiters.com/BoschGroup`. Or enable **Use built-in company list**.
3. Optionally add **Title keywords** (for example `data engineer`) and **Locations** (for example `Remote`, `London`).
4. Click **Start** and download your jobs as JSON, CSV, Excel, XML or HTML.

#### How do I find a company's board token?

Open the company's careers page and click a job. The token is the first part of the path on the ATS domain:

| ATS             | Career page URL                               | Input                        |
| --------------- | --------------------------------------------- | ---------------------------- |
| Greenhouse      | `https://job-boards.greenhouse.io/airbnb`     | `greenhouse:airbnb`          |
| Lever           | `https://jobs.lever.co/palantir`              | `lever:palantir`             |
| Lever (EU)      | `https://jobs.eu.lever.co/<token>`            | `lever-eu:<token>`           |
| Ashby           | `https://jobs.ashbyhq.com/ramp`               | `ashby:ramp`                 |
| SmartRecruiters | `https://jobs.smartrecruiters.com/BoschGroup` | `smartrecruiters:BoschGroup` |

You can paste any of these URLs directly. The Actor detects the platform automatically.

### Input example

```json
{
    "companies": ["greenhouse:airbnb", "lever:palantir", "ashby:ramp", "smartrecruiters:BoschGroup"],
    "keywords": ["engineer", "data"],
    "excludeKeywords": ["intern"],
    "locations": ["United States", "Remote"],
    "postedWithinDays": 30,
    "descriptionFormat": "text",
    "incrementalMode": false
}
```

See the **Input** tab for every option with descriptions.

### Output example

Each job is one dataset item:

```json
{
    "jobId": "ashby:ramp:3f4509ad-1858-478b-a7fb-bcd792d9575a",
    "ats": "ashby",
    "companyToken": "ramp",
    "companyName": "ramp",
    "sourceJobId": "3f4509ad-1858-478b-a7fb-bcd792d9575a",
    "title": "Product Manager | Procurement",
    "department": "Product",
    "team": "Product Management",
    "location": "New York, NY (HQ)",
    "locations": ["New York, NY (HQ)", "San Francisco, CA"],
    "country": "USA",
    "remote": true,
    "workplaceType": "hybrid",
    "employmentType": "FullTime",
    "experienceLevel": null,
    "postedAt": "2026-10-05T16:09:02.202+00:00",
    "updatedAt": null,
    "jobUrl": "https://jobs.ashbyhq.com/ramp/3f4509ad-1858-478b-a7fb-bcd792d9575a",
    "applyUrl": "https://jobs.ashbyhq.com/ramp/3f4509ad-1858-478b-a7fb-bcd792d9575a/application",
    "salaryMin": 230000,
    "salaryMax": 325000,
    "salaryCurrency": "USD",
    "salaryInterval": "1 YEAR",
    "salaryText": "$230K – $325K • Offers Equity",
    "descriptionHtml": null,
    "descriptionText": "ABOUT RAMP\n\nRamp is building the smart infrastructure for finance teams, embedded in the transaction flow of every dolla...",
    "changeType": null,
    "firstSeenAt": null,
    "scrapedAt": "2026-10-07T20:19:46.429Z"
}
```

The **Overview** and **Jobs with salary** views in the Output tab show the most useful columns. A `RUN_SUMMARY` record in the run's key-value store lists how many companies succeeded or failed, with error details.

### Incremental mode: get only new or changed jobs

Enable **Incremental mode** and schedule the Actor (for example daily). The Actor remembers each job's fingerprint (title, location, department, team, employment type, salary and description) in a named key-value store:

- The **first run** returns all matching jobs with `changeType: "NEW"`.
- **Later runs** return only jobs that are `NEW` or `CHANGED`, plus `REMOVED` jobs if **Output removed jobs** is on.
- If nothing changed, the run succeeds with zero results, and you pay nothing for results.

Use a different **State store name** for each monitoring task, such as one per filter set, so tasks don't overwrite each other's memory.

### How much does it cost to scrape career sites?

This Actor uses **pay-per-event** pricing. You pay mainly for the jobs you get:

| Event                     | Price                                           |
| ------------------------- | ----------------------------------------------- |
| Job saved to the dataset  | **$2.00 per 1,000 jobs** ($0.002 per job)       |
| Company job board scanned | $0.10 per 1,000 companies ($0.0001 per company) |
| Actor start               | $0.00005 per run                                |

There's no extra charge for proxies or compute. Filters are applied before charging, so jobs you filter out are free, and failed company boards aren't charged at all. The small per-company charge covers loading each board, so scanning the full seed list of 8,500+ companies costs under $1 before any matched jobs.

Examples:

- 4 companies, all jobs (about 750 jobs): about **$1.50**
- 1,000 companies filtered to remote data engineering roles (about 140 jobs): about **$0.37**
- 1,000 companies with incremental mode, 500 new jobs since yesterday: about **$1.10**

Set **Maximum cost per run** in the run options to cap spending; the Actor stops cleanly when it is reached. The prefilled example input is capped at 200 jobs (about $0.40), so your first run is cheap.

### Tips

- Set **Job description format** to `None` for the fastest runs when you only need titles, locations and links.
- SmartRecruiters needs one extra request per job to load the description, so large SmartRecruiters boards take longer when descriptions are on.
- Use **Max jobs** to preview results cheaply before a big run.
- Seed-list scans of thousands of companies finish faster with 4 GB of memory. Pricing is per event, so memory doesn't change what you pay.

### Use it with AI agents (MCP) and the API

Add this Actor as a tool in Claude, ChatGPT, Cursor, VS Code or any other MCP client through the [Apify MCP server](https://docs.apify.com/mcp):

```text
https://mcp.apify.com?tools=magenta_waterwheel/career-site-jobs-api
```

Then just ask, for example: *"Find remote data engineering jobs posted in the last 7 days at Airbnb, Ramp and Palantir."* The agent fills in the input, runs the Actor and reads the results. The Actor runs with **limited permissions**, so it can only access its own run storage.

To get results in a single HTTP request, call the synchronous endpoint with your [Apify API token](https://console.apify.com/settings/integrations):

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

You can also use the official [Python](https://docs.apify.com/api/client/python) and [JavaScript](https://docs.apify.com/api/client/js) clients, or the ready-made code on the **API** tab.

### Integrations and scheduling

- ⏰ **Schedule runs** hourly, daily or weekly in Apify Console, with no server to maintain.
- 🔗 **Send results anywhere**: Google Sheets, Slack, Google Drive, Airbyte, webhooks, or no-code tools such as **Make, Zapier and n8n**.
- 📤 **Export** the dataset as JSON, CSV, Excel, XML, RSS or HTML.
- 📈 **Monitoring**: get notified if a run fails, and see every run's log and cost in Console.

### FAQ

#### Is there a free trial?

Yes. Apify's Free plan includes **$5 of usage credit every month**, enough for about **2,500 jobs** with this Actor. No credit card is needed to start.

#### How do I get only new jobs every day?

Turn on **Incremental mode** and create a daily schedule in Apify Console. Each run returns only jobs that are new or changed since the previous run, and you pay only for those.

#### Is it legal to scrape job listings from career sites?

This Actor reads public job postings that employers publish through the official public job-board APIs of Greenhouse, Lever, Ashby and SmartRecruiters, which exist so job postings can be shown on other sites. It does not log in, bypass protections or collect personal data. You are responsible for how you use the data; check the terms that apply to your use case.

#### Why did my run fail with "no jobs"?

The Actor fails on purpose instead of returning an empty dataset, so you never pay for a silent empty run. The status message tells you why: all boards failed (usually a wrong token, see `RUN_SUMMARY`), the boards have no open jobs, or your filters matched nothing.

#### What happens if one company fails?

Each company is retried on network or server errors (see **Max retries per company**). A board that doesn't exist (HTTP 404) is reported in `RUN_SUMMARY` and skipped. Other companies continue normally.

#### Which companies are in the built-in list?

The list contains companies whose public boards on Greenhouse, Lever, Ashby or SmartRecruiters had at least one open job when the list was built. It was compiled from public web-crawl data (Common Crawl) and verified against each platform's API. The list is refreshed with new Actor versions.

#### Does it support Workday, iCIMS or other ATS platforms?

Not yet. Greenhouse, Lever, Ashby and SmartRecruiters are supported today. Tell us in the **Issues** tab which platform you need next.

#### Can I use it with AI agents or via API?

Yes. Call it via the [Apify API](https://docs.apify.com/api/v2), the Apify MCP server, or the JavaScript and Python clients, and read results from the dataset. The output fields are stable and documented in the Output tab.

#### How do I report a problem?

Open an issue in the **Issues** tab with the run link and the company that failed. We aim to reply within one business day, and we're happy to add companies or ATS platforms on request.

### More tools from the same developer

| Actor                                                                                       | What it does                                                          | Price                     |
| ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------------------------- |
| [Website Screenshot & PDF API](https://apify.com/magenta_waterwheel/website-screenshot-pdf) | Full-page PNG/JPEG screenshots and web page to PDF in bulk            | $2.50 / 1,000 screenshots |
| [App Store Reviews Scraper](https://apify.com/magenta_waterwheel/app-store-reviews-details) | Apple App Store reviews and app details in any country                | $0.25 / 1,000 reviews     |
| [Document & PDF to Markdown](https://apify.com/magenta_waterwheel/document-to-markdown)     | PDF, Word, PowerPoint, Excel and HTML to LLM-ready Markdown, with OCR | $3 / 1,000 pages          |

# Actor input Schema

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

One company per line. Use "ats:token" (for example greenhouse:airbnb, lever:palantir, lever-eu:token, ashby:ramp, smartrecruiters:BoschGroup) or paste a career-page URL such as https://job-boards.greenhouse.io/airbnb, https://jobs.lever.co/palantir, https://jobs.ashbyhq.com/ramp or https://jobs.smartrecruiters.com/BoschGroup.

## `useSeedList` (type: `boolean`):

Also scrape the built-in list of 8,500+ verified companies with active job boards (Greenhouse, Ashby, SmartRecruiters and Lever). Combine with keyword and location filters to search across many employers at once.

## `seedAts` (type: `array`):

Limit the built-in list to these platforms. Leave empty for all.

## `maxSeedCompanies` (type: `integer`):

Use at most this many companies from the built-in list (largest boards first). 0 means no limit.

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

Keep jobs whose title contains any of these words or phrases (case-insensitive). Leave empty to keep all jobs.

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

Drop jobs whose title contains any of these words (case-insensitive), for example "intern" or "senior".

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

Keep jobs whose location contains any of these strings (case-insensitive), for example "New York", "London", "Germany" or "Remote".

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

Keep only jobs marked as remote by the ATS or with "remote" in the location.

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

Keep only jobs posted or updated in the last N days. 0 means no date filter.

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

How to return the job description. "Plain text" is best for AI and search; "None" makes runs faster and output smaller.

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

Stop after this many jobs have been saved. 0 means no limit (the run still stops at your maximum cost per run).

## `incrementalMode` (type: `boolean`):

Remember jobs between runs and output only jobs that are new or whose title, location, salary or description changed since the last run. Ideal for scheduled runs. The first run returns all jobs as NEW.

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

Name of the key-value store that keeps incremental state. Use a different name for each monitoring task (for example one per filter set).

## `outputRemovedJobs` (type: `boolean`):

In incremental mode, also output jobs that disappeared since the last run, marked with changeType REMOVED. These are billed like other results.

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

How many company boards to fetch in parallel.

## `maxRequestRetries` (type: `integer`):

How many times to retry a company board after a network error or server error. A board that does not exist (HTTP 404) is not retried.

## Actor input object example

```json
{
  "companies": [
    "greenhouse:airbnb",
    "https://jobs.lever.co/palantir",
    "ashby:ramp"
  ],
  "useSeedList": false,
  "seedAts": [],
  "maxSeedCompanies": 0,
  "keywords": [],
  "excludeKeywords": [],
  "locations": [],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "descriptionFormat": "text",
  "maxJobs": 200,
  "incrementalMode": false,
  "stateStoreName": "career-site-jobs-state",
  "outputRemovedJobs": false,
  "maxConcurrency": 10,
  "maxRequestRetries": 3
}
```

# Actor output Schema

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

No description

## `allFields` (type: `string`):

No description

## `runSummary` (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:airbnb",
        "lever:palantir",
        "ashby:ramp",
        "smartrecruiters:Playtech"
    ],
    "maxJobs": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("magenta_waterwheel/career-site-jobs-api").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:airbnb",
        "lever:palantir",
        "ashby:ramp",
        "smartrecruiters:Playtech",
    ],
    "maxJobs": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("magenta_waterwheel/career-site-jobs-api").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:airbnb",
    "lever:palantir",
    "ashby:ramp",
    "smartrecruiters:Playtech"
  ],
  "maxJobs": 200
}' |
apify call magenta_waterwheel/career-site-jobs-api --silent --output-dataset

```

## MCP server setup

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

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/g8Nm3MCloA3chX1I1/builds/Zph1rQVzniIAPT1Oz/openapi.json
