# Career Page Jobs API - Greenhouse, Lever, Ashby, Workable (`lost.fany/greenhouse-lever-ats-jobs-scraper`) Actor

Job openings from company career pages on Greenhouse, Lever, Ashby, SmartRecruiters, Workable and Recruitee. Pass company names or career URLs, the ATS is detected automatically. dryRun prices a run before you pay; charged only for jobs delivered.

- **URL**: https://apify.com/lost.fany/greenhouse-lever-ats-jobs-scraper.md
- **Developed by:** [Natalia Ivanova](https://apify.com/lost.fany) (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 $1.10 / 1,000 job rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Page Jobs API - Greenhouse, Lever, Ashby, Workable ATS

Get **every open position straight from company career pages** — the ones hosted on Greenhouse, Lever, Ashby, SmartRecruiters, Workable and Recruitee. Give the Actor company names, ATS links or careers-page URLs; it **detects which applicant-tracking system each company uses** and returns one clean dataset: title, location, remote flag, department, team, employment type, compensation (where the ATS publishes it), publication date, full description and the direct apply link.

It reads only the **public job-board APIs the ATS vendors publish for career sites** — the same data the career page itself loads. No login, no HTML scraping, no proxies, no rate-limit games. That is why it does not break when a career page changes its design, and why it is fast: hundreds of companies in a couple of minutes.

### What you can do with it

- **Hiring signals for sales and investors** — watch which target accounts open roles, in which teams, at what pace. Run daily and diff the datasets.
- **Job boards and newsletters** — build a niche board ("AI companies hiring in Europe") sourced directly from employers, with canonical apply links.
- **Recruiting and talent research** — track competitors' open roles, salary ranges (Ashby, Lever, Greenhouse where published), locations and remote policies.
- **Job search on autopilot** — a watch-list of dream companies, filtered by keywords and location, delivered to Slack or email through Apify integrations.
- **AI agents** — expose live openings of any company to an agent through the Apify MCP server.

### Supported ATS

| ATS | Detected from | Notes |
|---|---|---|
| Greenhouse | `boards.greenhouse.io/<token>`, `job-boards.greenhouse.io/<token>` | Full description, departments, offices |
| Lever | `jobs.lever.co/<site>` | Workplace type, salary range when published |
| Ashby | `jobs.ashbyhq.com/<name>` | Compensation tiers, remote flag, teams |
| SmartRecruiters | `careers.smartrecruiters.com/<Company>` | Experience level; description needs one extra request per job |
| Workable | `apply.workable.com/<slug>` | Telecommuting flag, department |
| Recruitee | `<slug>.recruitee.com` | Requirements included in description |

**Auto-detection.** For a bare company slug (`gitlab`, `openai`) the Actor probes all six APIs and uses the one that answers with jobs. For a company careers page (`https://example.com/careers`) it scans the page for ATS links. If nothing is found, the company is reported in the run summary with a hint — pass the ATS link or `ats:slug` explicitly (`lever:netflix`).

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `companies` | array | — | Slugs, ATS URLs, careers-page URLs or `ats:slug`. One per line. |
| `keywords` | array | `[]` | Whole-word match in title, department, team, location. Empty = all. |
| `excludeKeywords` | array | `[]` | Drop matching jobs. |
| `location` | string | — | Location text must contain this (`Remote`, `Berlin`, `United States`). |
| `remoteOnly` | boolean | `false` | Only remote jobs (ATS flag or "remote" in title/location). |
| `includeDescription` | boolean | `true` | Full description as text and HTML. |
| `maxJobsPerCompany` | number | `1000` | Cap per company. |
| `maxItems` | number | `5000` | Cap in total. |

Example — engineering roles, remote, at three companies:

```json
{
  "companies": ["gitlab", "https://jobs.ashbyhq.com/openai", "lever:netflix"],
  "keywords": ["engineer", "developer"],
  "remoteOnly": true,
  "includeDescription": false
}
```

### Output

```json
{
  "id": "greenhouse:gitlab:8556658002",
  "ats": "greenhouse",
  "atsName": "Greenhouse",
  "company": "gitlab",
  "companyName": "GitLab",
  "title": "AI Engineer",
  "url": "https://job-boards.greenhouse.io/gitlab/jobs/8556658002",
  "applyUrl": "https://job-boards.greenhouse.io/gitlab/jobs/8556658002",
  "location": "Remote, Bangalore",
  "remote": true,
  "workplaceType": null,
  "department": "Enterprise Applications",
  "team": "India",
  "employmentType": null,
  "seniority": null,
  "compensation": null,
  "publishedAt": "2026-05-22T13:16:29Z",
  "updatedAt": "2026-08-31T21:56:36Z",
  "description": "GitLab is the intelligent …",
  "descriptionHtml": "<div class=\"content-intro\">…</div>",
  "scrapedAt": "2026-09-10T15:40:02Z"
}
```

The `OUTPUT` record in the key-value store lists every company with the ATS detected, jobs found and kept, and the reason if it could not be resolved.

### Use cases

Ready-made examples you can run without configuring anything:

- [Career page jobs API for any company](https://apify.com/lost.fany/greenhouse-lever-ats-jobs-scraper/examples/career-page-jobs-api) — ready-made task, run it as is
- [Auto-detect the ATS behind a list of domains](https://apify.com/lost.fany/greenhouse-lever-ats-jobs-scraper/examples/ats-auto-detect) — ready-made task, run it as is

#### Career page jobs API for any company

Give company names or careers URLs and get live openings straight from the company's own ATS — no job-board reposts, no expired listings.

```json
{ "companies": ["stripe", "notion"] }
```

#### ATS auto-detect for a list of domains

The Actor works out which applicant-tracking system each company runs before fetching, so a mixed list needs no preparation.

```json
{ "companies": ["https://example.com/careers"] }
```

#### Scrape SmartRecruiters and Workable jobs

The smaller ATS platforms are covered by the same schema as Greenhouse, Lever and Ashby.

```json
{ "companies": ["acme"], "includeDescription": true }
```

### Pricing

Pay per event: a small fee per Actor start plus a fee per job returned. Companies that cannot be resolved cost nothing beyond the start fee. Current prices are in the **Pricing** tab.

### Good to know

- Fields differ by ATS: Greenhouse has no employment type, SmartRecruiters has no remote flag on the list endpoint, compensation appears only where the employer publishes it.
- `remote` is the ATS flag when it exists; otherwise a heuristic on title/location ("remote", "anywhere", "work from home").
- Companies sometimes run two ATS instances (one per region). Pass each link separately.
- The ATS vendors publish these APIs for public career pages; please use the data respectfully and keep the apply links intact.

### Use with AI agents (MCP)

Add the Actor to the [Apify MCP server](https://apify.com/apify/actors-mcp-server) and ask: "Which remote backend roles does Company X have open right now?" Typical tool input: `{ "companies": ["companyx"], "keywords": ["backend"], "remoteOnly": true, "includeDescription": false }`.

### Related Actors

- [Remote Jobs Scraper](https://apify.com/lost.fany/remote-jobs-scraper)
- [Hacker News Search API](https://apify.com/lost.fany/hacker-news-search-scraper)
- [Tech Stack Detector](https://apify.com/lost.fany/website-tech-stack-detector)

### Cost control

Pay per event only works if you can see the bill before you pay it:

- Set `dryRun` to count every result and print what a full run would cost - nothing is charged, and only a few sample rows are stored.
- You are charged only for rows actually delivered to the dataset; a run that finds nothing costs nothing beyond the start event.
- `maxItems` is respected exactly, and the run stops before the platform's Max total charge for the run.
- Every run writes a `COST` record to the key-value store: chargeable events, charged events, the amount in USD and whether a limit was hit.

# Actor input Schema

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

One per line: a company slug (gitlab, openai), an ATS careers URL (https://boards.greenhouse.io/gitlab, https://jobs.lever.co/<slug>, https://jobs.ashbyhq.com/<slug>, https://careers.smartrecruiters.com/<Company>, https://apply.workable.com/<slug>, https://<slug>.recruitee.com), a company careers page URL (the Actor looks for ATS links on it), or an explicit 'ats:slug' like lever:netflix.

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

Keep jobs whose title, department, team or location contains ANY of these words (whole-word, case-insensitive). Empty = all jobs.

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

Drop jobs whose title, department, team or location contains any of these.

## `location` (type: `string`):

Keep only jobs whose location text contains this, e.g. Remote, London, United States.

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

Keep only jobs marked remote by the ATS or whose title/location says remote.

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

Full job description as text and HTML (SmartRecruiters needs one extra request per job). Off = 300-character excerpt.

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

Cap per company after filtering.

## `maxItems` (type: `integer`):

Stop after this many jobs in total.

## `proxyConfiguration` (type: `object`):

Not needed normally; enable only if an ATS starts blocking Apify's IPs.

## `dryRun` (type: `boolean`):

Count every result and show what a full run would cost, without charging for it. Only a few sample rows are stored. Use it to check the price before you pay.

## Actor input object example

```json
{
  "companies": [
    "gitlab",
    "https://jobs.ashbyhq.com/openai",
    "smartrecruiters:BoschGroup"
  ],
  "keywords": [],
  "excludeKeywords": [],
  "remoteOnly": false,
  "includeDescription": true,
  "maxJobsPerCompany": 1000,
  "maxItems": 5000,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "dryRun": false
}
```

# Actor output Schema

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

One item per job: company, title, location, remote flag, department, employment type, compensation, description, links.

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

Counts and errors of the 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 = {
    "companies": [
        "gitlab",
        "https://jobs.ashbyhq.com/openai",
        "smartrecruiters:BoschGroup"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lost.fany/greenhouse-lever-ats-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": [
        "gitlab",
        "https://jobs.ashbyhq.com/openai",
        "smartrecruiters:BoschGroup",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("lost.fany/greenhouse-lever-ats-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": [
    "gitlab",
    "https://jobs.ashbyhq.com/openai",
    "smartrecruiters:BoschGroup"
  ]
}' |
apify call lost.fany/greenhouse-lever-ats-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lost.fany/greenhouse-lever-ats-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/S5DK18YHZE5M6UlDi/builds/5dB1cQwBmYzabwUzm/openapi.json
