# Lever Job Scraper (`cliqtomedia/lever-jobs-scraper`) Actor

Lever job scraper for published jobs from the public Lever boards you provide. Get stable job rows, content, filters and a clear run report.

- **URL**: https://apify.com/cliqtomedia/lever-jobs-scraper.md
- **Developed by:** [Cliqto Media](https://apify.com/cliqtomedia) (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

$0.30 / 1,000 unique job results

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

## Lever Job Scraper

Lever job scraper for published jobs from one or more public Lever company
boards. Add a board slug, a board URL, or one exact job URL. The Actor saves one
JSON row per unique job and writes a run report that explains each target.

### What you get

- Job title, location, all locations, department, team and commitment.
- Workplace type, country, creation time and direct job links when published.
- The public job description in HTML and plain text, plus list sections.
- Salary fields only when the employer publishes them.
- One row for each unique job, with a stable `id` and the source job ID.
- A `RUN_SUMMARY` report for empty boards, filters, missing boards and errors.

### How to use it

1. Add one or more public Lever board slugs or URLs.
2. Keep `includeContent` on when you need descriptions and lists.
3. Add filters when you want only matching jobs.
4. Run the Actor and open the Dataset with the saved rows.

### Input

```json
{
  "targets": ["leverdemo", "https://jobs.lever.co/palantir"],
  "includeContent": true,
  "filters": {
    "titleIncludes": ["engineer"],
    "workplaceTypes": ["remote"]
  },
  "maxJobsPerTarget": 0,
  "maxTotalJobs": 5000,
  "pageSize": 0,
  "continueOnError": true
}
```

`targets` is required and accepts up to 50 entries. A bare slug uses the global
Lever service. Use an EU board URL when the board is on the EU Lever service.
An exact public job URL returns one job row.

`maxJobsPerTarget` accepts 0–5,000; `0` means no per-board cap.
`maxTotalJobs` accepts 1–5,000 and is the maximum number of unique rows saved
in one run. `pageSize` accepts 0–1,000. Use `0` for the complete board response,
or use a positive value to read the board in source pages. `continueOnError`
lets other targets run after one target has a technical error.

Filters use OR logic inside one filter group and AND logic between groups. For
example, two `titleIncludes` values match either title, while a title and a
country filter must both match.

### Output

The default Dataset contains one row per unique published posting. Each row has
a stable `id`, the source `sourceJobId`, region and board, source fields, public
content, links and `observedAt`. Optional fields remain `null` or empty when the
board does not provide them. The Actor does not guess salary, country, company
name or update time.

The key-value store record `RUN_SUMMARY` contains a final status, counts and one
entry for every input target. `OK`, `EMPTY_BOARD`, `FILTERED_EMPTY` and
`NOT_FOUND` are different outcomes. Technical failures are not reported as
empty boards. No job application is submitted.

### Charging

The price is **$0.30 per 1,000 unique useful job rows** (`$0.00030` per row).
The Actor charges one result event for each accepted unique useful row. Empty,
filtered, duplicate, invalid, not-found and failed targets create no result
charge. Apify may also show its normal platform run charge.

### Limits and safe use

The most important limit is 5,000 unique rows per run. Fields such as salary,
country, workplace type and lists can be empty when the employer does not
publish them.

This Actor reads published public postings from the boards supplied in the
input. It is not a global Lever company index. It does not read internal or
closed jobs, enrich records, use login or cookies, automate a browser, use AI
extraction, or read another ATS.

The name Lever identifies the source format only. This project is not
affiliated with or endorsed by Lever. Customers are responsible for their use
of public job content and for following applicable terms, privacy and copyright
rules.

### Need help?

Open the run ID in Apify, then open `RUN_SUMMARY`. Check the target status first.
For a missing board, verify the slug in its public career-page URL. For an
empty result, check filters and limits before retrying. Share the run ID and the
status entry when you ask for support. Never share an access token.

# Changelog

This Actor's version history is a separate document: https://apify.com/cliqtomedia/lever-jobs-scraper/changelog.md

# Actor input Schema

## `targets` (type: `array`):

Use a board slug such as leverdemo, a public Lever board URL, or one exact public job URL. Bare slugs use the global Lever service.

## `includeContent` (type: `boolean`):

Keep the public HTML/plain job content and list sections in each result.

## `filters` (type: `object`):

All filled filter groups must match. Values within one group use OR logic.

## `maxJobsPerTarget` (type: `integer`):

Stop each board after this many useful results. Use 0 for no per-board cap.

## `maxTotalJobs` (type: `integer`):

Maximum number of unique job rows saved in one run.

## `pageSize` (type: `integer`):

Use the complete board response when 0. A positive value uses Lever skip/limit pages.

## `continueOnError` (type: `boolean`):

Process independent targets after a technical failure and report a partial run.

## Actor input object example

```json
{
  "targets": [
    "leverdemo"
  ],
  "includeContent": true,
  "maxJobsPerTarget": 0,
  "maxTotalJobs": 5000,
  "pageSize": 0,
  "continueOnError": true
}
```

# Actor output Schema

## `dataset` (type: `string`):

One row per unique useful published job.

## `runSummary` (type: `string`):

Target statuses, counts, timings and stop reasons.

# 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 = {
    "targets": [
        "leverdemo"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/lever-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 = { "targets": ["leverdemo"] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/lever-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 '{
  "targets": [
    "leverdemo"
  ]
}' |
apify call cliqtomedia/lever-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/lever-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/e30rSe65rgbfzIDa3/builds/ZEZrMcrKQuvEHs6iA/openapi.json
