# Career Site Jobs Scraper: Greenhouse, Lever, Ashby & More (`intenal_builds/ats-career-jobs-scraper`) Actor

Live job postings straight from company career boards (Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee) via their public job board APIs. Auto-detects the ATS, normalizes fields incl. salary, filters by title, location, department, remote and date. From $1.50 per 1,000 jobs.

- **URL**: https://apify.com/intenal_builds/ats-career-jobs-scraper.md
- **Developed by:** [Jaydan Eaton](https://apify.com/intenal_builds) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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 Scraper: Greenhouse, Lever, Ashby, Workable, SmartRecruiters & Recruitee Jobs API

Get **live job postings straight from company career pages**. Paste company names or careers URLs and get clean, normalized jobs (title, location, department, remote, **salary**, posted date, apply link and full description) from the six most popular applicant tracking systems (ATS):

**Greenhouse · Lever · Ashby · Workable · SmartRecruiters · Recruitee**

It uses each ATS's **official public job-board API**, the same feeds that power companies' own careers pages. There are no logins, no cookies, no proxies and nothing to get blocked, and the data is fresh at the moment you run it.

### Why this jobs scraper?

- **Direct from the source.** Jobs come straight from the employer's board, not a stale aggregator copy, so you see what's open right now.
- **Auto-detects the ATS.** Type `ramp` and it finds Ashby. Type `stripe` and it finds Greenhouse. Or pass `lever:palantir` or a careers URL.
- **One normalized schema across 6 ATS platforms.** It's easy to combine, dedupe and load into a sheet, CRM or database.
- **Salary data** when the employer publishes it (Ashby, Lever and Recruitee commonly do).
- **Hiring-signal summary.** `COMPANY_SUMMARY` gives total open roles per company and how many match your filters. That's ideal for sales prospecting ("who's hiring SDRs?").
- **Cheap and predictable.** $1.50 per 1,000 jobs. Failed or not-found companies cost nothing.
- **Built for AI agents and MCP.** Structured input, a dataset schema and an output schema make it easy for agents to call.

### Use cases

- **Job boards and newsletters:** a niche board (remote, AI, climate, fintech) built from a list of target companies.
- **Sales and recruiting intelligence:** find companies hiring for roles that signal they need your product.
- **Job seekers:** track every new "Product Manager" role at your 50 dream companies.
- **Market research:** headcount growth, department mix, remote ratios and salary bands.
- **AI and RAG:** feed fresh job descriptions to LLM pipelines.

### Input examples

**Engineering roles at three companies:**

```json
{"companies": ["greenhouse:stripe", "https://jobs.lever.co/palantir", "ramp"], "titleKeywords": ["engineer"]}
```

**Remote sales jobs posted this week, with descriptions:**

```json
{"companies": ["stripe", "ramp", "huggingface"], "titleKeywords": ["sales", "account executive"], "remoteOnly": true, "postedWithinDays": 7, "includeDescription": true}
```

### Output example

```json
{
  "ats": "ashby", "companySlug": "ramp", "company": "ramp",
  "title": "Security Engineer, Cloud", "location": "New York, NY (HQ)",
  "department": "Engineering", "employmentType": "FullTime", "remote": false,
  "salary": "$211.4K - $290.6K", "salaryMin": 211400, "salaryMax": 290600, "salaryCurrency": "USD",
  "postedAt": "2026-04-07T17:12:35.753000+00:00",
  "url": "https://jobs.ashbyhq.com/ramp/...", "applyUrl": "https://jobs.ashbyhq.com/ramp/.../application"
}
```

### Pricing (pay per event)

| Event | Price |
|---|---|
| `job`: one job posting in your dataset | **$0.0015** ($1.50 per 1,000 jobs) |
| Actor start | Apify default |

Use `maxResults` and `maxJobsPerCompany` to cap your spend.

### FAQ

**How do I find a company's slug?** Open their careers page. If the URL looks like `boards.greenhouse.io/acme`, `jobs.lever.co/acme`, `jobs.ashbyhq.com/acme`, `apply.workable.com/acme`, `jobs.smartrecruiters.com/Acme` or `acme.recruitee.com`, then `acme` is the slug. You can also paste the URL itself.

**Is this legal?** The actor only reads public job-board APIs that the ATS vendors publish so job listings can be displayed anywhere. It doesn't log in, bypass blocks or collect personal data. Always follow the terms of the sites you use and your local laws.

**Does it support Workday, iCIMS or LinkedIn?** Not yet. Those don't offer an open public job-board API. This actor sticks to official public feeds for reliability.

**Why are some salaries empty?** Salary appears only when the employer publishes it on the posting.

**A company wasn't found. Why?** It may use a different ATS or a custom careers site. Check `COMPANY_SUMMARY`. Not-found companies are never charged.

**Can I schedule it?** Yes. Use Apify Schedules (for example daily) together with `postedWithinDays: 1` to get only new jobs.

# Actor input Schema

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

Companies to pull jobs from. Use a board slug (e.g. 'stripe'), 'ats:slug' to skip auto-detection (e.g. 'lever:palantir', 'ashby:ramp', 'smartrecruiters:BoschGroup'), or a careers page URL (e.g. https://jobs.lever.co/palantir).

## `atsPlatforms` (type: `array`):

Which applicant tracking systems to try when auto-detecting a plain slug. Leave all selected for best coverage.

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

Keep jobs whose title contains ANY of these (case-insensitive), e.g. 'engineer', 'sales'. Empty = all jobs.

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

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

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

Keep jobs whose location contains ANY of these, e.g. 'New York', 'London', 'Remote'. Empty = anywhere.

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

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

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

Keep only jobs marked remote by the employer (or with 'remote' in the location).

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

Keep only jobs posted in the last N days. 0 = any age. Jobs without a posted date are kept.

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

Include the full plain-text job description (slower for SmartRecruiters, which needs one extra request per job).

## `descriptionMaxChars` (type: `integer`):

Truncate descriptions to this length. 0 = no limit.

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

Cap matched jobs per company. 0 = no cap.

## `maxResults` (type: `integer`):

Maximum total jobs to output (you are charged per job). Use it to cap cost.

## `concurrency` (type: `integer`):

How many companies to fetch in parallel. Keep it modest to be polite to job board APIs.

## Actor input object example

```json
{
  "companies": [
    "greenhouse:stripe",
    "lever:palantir",
    "ashby:ramp"
  ],
  "atsPlatforms": [
    "greenhouse",
    "lever",
    "ashby",
    "workable",
    "smartrecruiters",
    "recruitee"
  ],
  "titleKeywords": [],
  "excludeTitleKeywords": [],
  "locations": [],
  "departments": [],
  "remoteOnly": false,
  "postedWithinDays": 0,
  "includeDescription": false,
  "descriptionMaxChars": 5000,
  "maxJobsPerCompany": 0,
  "maxResults": 1000,
  "concurrency": 8
}
```

# Actor output Schema

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

All matched job postings.

## `companySummary` (type: `string`):

Per-company ATS detected, total open jobs and matched jobs (hiring signal).

# 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:palantir",
        "ashby:ramp"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("intenal_builds/ats-career-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:palantir",
        "ashby:ramp",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("intenal_builds/ats-career-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:palantir",
    "ashby:ramp"
  ]
}' |
apify call intenal_builds/ats-career-jobs-scraper --silent --output-dataset

```

## MCP server setup

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