# 🦅 Lever Jobs Scraper (`skootle/lever-jobs`) Actor

Scrape every open job from any Lever board. Returns title, team, location, commitment, country, parsed salary range, seniority, qualifications, and per-company hiring snapshots. Watchlist mode emits only new jobs since last run. Export, run via API, schedule, or integrate with other tools.

- **URL**: https://apify.com/skootle/lever-jobs.md
- **Developed by:** [Skootle](https://apify.com/skootle) (community)
- **Categories:** Jobs, AI, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 job records

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

![Lever Jobs Scraper](https://raw.githubusercontent.com/kesjam/skootle-actors-assets/main/heroes/lever-jobs.png)

### TL;DR

BD reps, recruiters, and AI sourcing agents track Lever job boards at dozens of companies and waste 30 minutes a day clicking through each one. One run of this actor pulls every open job from your list of companies, with team, location, commitment, country, parsed salary range, and seniority already typed. Ships an `agentMarkdown` field per record so you can drop a job straight into Claude, Codex, Slack, or a CRM as a single card. Watchlist mode emits only new postings since your last run, perfect for daily monitoring.

<!-- skootle:review-cta -->
> Try it on a small batch of slugs first, then let us know what you think in a [review](https://apify.com/skootle/lever-jobs/reviews).

---

### What does Lever Jobs do?

You give it a list of Lever company slugs. Each slug is the path after `jobs.lever.co/` in a public Lever board URL. For each slug, the actor pulls the company's full open-roles list, parses every field you would otherwise click through to see, and returns a normalized record per job.

What you get for every job:

- **Identity:** Lever posting ID (idempotent, same across runs), job title, hosted URL, apply URL, company slug, company name.
- **Categorization:** team, department, commitment (Full-time, Part-time, Contract, Internship, Fixed-Term, Scholarship), location, all-locations array.
- **Geo:** country code (ISO 2-letter), location string as displayed, normalized location, `isRemote` boolean derived from workplaceType + location text.
- **Pay:** parsed `compRange` with min, max, currency, and period (year / hour / month). Lever does not return salary as a structured field. We parse it from the salary section text using a tested heuristic. About 30 to 50 percent of jobs surface a usable range, depending on the company and US disclosure laws.
- **Content:** plain-text description (capped at 12,000 chars), HTML description (capped at 30,000 chars), Lever's `lists` array with qualifications and responsibilities preserved as separate sections.
- **Time:** posted-at as ISO 8601, raw epoch milliseconds, scraped-at ISO 8601.
- **Seniority:** heuristic enum (`intern`, `entry`, `mid`, `senior`, `staff`, `principal`, `lead`, `director`, `vp`, `executive`, or null) derived from the job title.
- **Quality:** `fieldCompletenessScore` 0 to 100 so you can self-filter sparse rows downstream.
- **Agent-ready:** `agentMarkdown` field, a 300 to 500 char pre-formatted markdown card per job.

Plus a `company_summary` record per company you scrape: `totalCount`, `openedInLast7Days`, `hiringVelocityScore` (jobs per day rolling 90-day window), and `jobsByTeam` / `jobsByLocation` / `jobsByCommitment` distribution maps.

### Why scrape Lever?

Lever hosts the public job boards for hundreds of growth-stage and enterprise companies. There is no single search interface across all of them. If you care about hiring signal at 30 named companies, you click into 30 different boards, every day, and re-read every list to find what changed. The data is public, the structure is consistent, the work is mechanical. That is exactly the kind of work that should be one API call away.

Specific workflows this collapses:

- **Daily hiring monitor:** check 50 named companies for new roles every morning. Watchlist mode emits only jobs whose IDs have never been seen, so you get a diff, not the full list.
- **Cross-company comp benchmarking:** you want to know what staff product designers make at portfolio companies. Pull a basket of slugs, filter by `seniority=staff` and `team` ~ design, read the `compRange`.
- **BD on hiring teams:** a company opens 12 engineering roles in a month, that is a buying signal. The `company_summary.hiringVelocityScore` gives you that as a sortable number.
- **Recruiter sourcing list-building:** generate a daily CSV of new senior engineering roles across 80 Lever boards. Filter by `seniority=senior` + `team=Engineering`, push to your CRM.
- **AI agent integrations:** the `agentMarkdown` field is built for LLM context windows. Drop any record into Claude or GPT-4 as a single message, ask "is this role a fit for my candidate profile X", get an answer.

### Who needs this?

- **Business development reps** mapping which target accounts are scaling specific functions (sales, customer success, engineering). Use `hiringVelocityScore` and `jobsByTeam` to rank accounts for outreach.
- **Recruiters and sourcers** building daily lists of new senior roles across a tracked set of companies. Watchlist mode + commitment + seniority filters gets you to a clean sourcing queue in one call.
- **Comp intelligence teams** benchmarking salary bands across a portfolio. The parsed `compRange` field gives you a numeric min and max with currency and period, ready to feed a notebook.
- **VC and PE talent partners** tracking hiring at portfolio companies. Combine `company_summary` records with the per-job feed to build a hiring scorecard.
- **AI auto-apply agents and sourcing platforms** that need a clean, typed jobs feed across Lever boards without standing up their own scraper.
- **Sales-intelligence platforms** layering hiring-signal data on top of firmographic profiles.
- **Recruitment-marketing teams** producing weekly "new roles" newsletters from a curated company set. The `agentMarkdown` card is ready to drop into your CMS.

### How to use Lever Jobs

1. Open the Actor in the Apify Console and click **Try for free**.
2. In the `companies` field, paste the Lever slugs you want. The slug is whatever follows `jobs.lever.co/` in a public board URL. Example: for `https://jobs.lever.co/palantir`, the slug is `palantir`.
3. Optionally narrow the results with `keywords` (title), `locations` (substring), `teams`, `commitments`, or the `remoteOnly` flag.
4. Set `maxItems` to the cap you want. Default is 10 (so the daily auto-test fits), raise to 1000 or more for production runs.
5. For daily monitoring, flip `watchlistMode: true`. The actor will read previously-seen IDs from the key-value store and only emit new ones.
6. Click **Start**. Results stream into the default dataset as they are written.
7. Download as JSON / CSV / Excel, or pull via the API for downstream pipelines. The `AGENT_BRIEFING` markdown digest is in the key-value store under that key.

### How much will scraping Lever cost?

Pay-per-event pricing, charged per record written. Two events:

| Event | Description | FREE | BRONZE | SILVER | GOLD | PLATINUM | DIAMOND |
|---|---|---|---|---|---|---|---|
| Actor start | One-time per run | $0.001 | $0.001 | $0.001 | $0.001 | $0.001 | $0.001 |
| Job record | Per dataset record (primary) | $0.003 | $0.0025 | $0.002 | $0.0015 | $0.0015 | $0.0015 |

A typical daily monitor run across 20 Lever boards with 30 active jobs each returns ~600 records and costs roughly $1.80 at FREE tier, $0.90 at GOLD. Compute time is sub-minute per company (HTTP-only, no browser), so Apify platform usage is negligible.

### Is it legal to scrape Lever?

The Lever job-board API (`api.lever.co/v0/postings/<slug>?mode=json`) is the same public endpoint that powers every embed on company career pages. It returns no authenticated data, no PII beyond what the company has chosen to publish, and is delivered without any anti-bot challenge. We honor rate limits, identify ourselves with a standard browser User-Agent, and do not attempt to access private boards or applicant data.

You are responsible for your own use of the resulting data. If you plan to republish or resell the records, talk to your legal counsel about the specific company's terms of service. Most growth-stage companies publish these boards because they want maximum distribution; aggregating that data for buyer-facing workflows is generally well within the norms of the public-jobs ecosystem.

### Examples

**1. Single company, full board**

```json
{
  "companies": ["palantir"],
  "maxItems": 500
}
````

**2. Engineering jobs across a portfolio**

```json
{
  "companies": ["palantir", "veo"],
  "teams": ["Engineering", "Data"],
  "maxItems": 200
}
```

**3. Remote senior roles**

```json
{
  "companies": ["palantir"],
  "remoteOnly": true,
  "keywords": ["senior", "staff", "principal"],
  "maxItems": 100
}
```

**4. New York jobs, full-time only**

```json
{
  "companies": ["palantir"],
  "locations": ["New York"],
  "commitments": ["Full-time"],
  "maxItems": 100
}
```

**5. Internship hunt across multiple companies**

```json
{
  "companies": ["palantir", "veo"],
  "commitments": ["Internship"],
  "maxItems": 200
}
```

**6. Daily watchlist monitor (only new jobs)**

```json
{
  "companies": ["palantir", "veo"],
  "watchlistMode": true,
  "maxItems": 1000
}
```

### Input parameters

| Field | Type | Required | Description |
|---|---|---|---|
| `companies` | string\[] | yes | Lever board slugs. The path after `jobs.lever.co/`. |
| `keywords` | string\[] | no | Title keywords. Job kept if ANY keyword appears in the title (case-insensitive). |
| `locations` | string\[] | no | Substring match against Lever's location field. |
| `teams` | string\[] | no | Substring match against the Lever team name. |
| `commitments` | string\[] | no | Filter by commitment (Full-time, Part-time, Contract, Internship, Fixed-Term, Scholarship, Temporary). |
| `remoteOnly` | boolean | no | Only jobs flagged remote by the company. Default false. |
| `maxItems` | integer | no | Cap on records returned. Default 10, max 5000. |
| `watchlistMode` | boolean | no | When true, only emits jobs whose IDs have never been seen by a prior run. Default false. |
| `proxyConfiguration` | object | no | Optional Apify proxy. Not required; Lever's public API is unrestricted. |

### Lever job output format

#### lever\_job

Per-job record. Idempotent primary key is `jobId`.

| Field | Type | Notes |
|---|---|---|
| `outputSchemaVersion` | string literal `'2026-05-11'` | Bump on breaking change. |
| `recordType` | `'lever_job'` | Discriminator. |
| `jobId` | string | Lever posting UUID. Same across runs. |
| `companySlug` | string | The slug you passed in. |
| `company` | string | Best-effort display name. |
| `title` | string | Job title. |
| `hostedUrl` | string | Public board URL. |
| `applyUrl` | string | null | Apply page URL. |
| `location` | object | `{ name, normalized, isRemote }`. |
| `team` | string | null | Lever team. |
| `commitment` | string | null | Full-time / Internship / Contract / etc. |
| `department` | string | null | Lever department (rarely populated). |
| `country` | string | null | ISO 2-letter country code. |
| `descriptionPlain` | string | Plain text, capped at 12,000 chars. |
| `descriptionHtml` | string | HTML, capped at 30,000 chars. |
| `lists` | array | Qualifications / responsibilities split into `{text, content}` entries. |
| `additional` | string | null | Salary section + extras (plain text). |
| `seniority` | enum | null | Parsed from title. |
| `compRange` | object | `{ min, max, currency, period }`, currency as ISO 3-letter, period as year/hour/month. |
| `categories` | object | Raw Lever categories. |
| `createdAtMs` | number | null | Epoch milliseconds. |
| `postedAt` | string | ISO 8601. |
| `scrapedAt` | string | ISO 8601. |
| `fieldCompletenessScore` | integer | 0 to 100. |
| `agentMarkdown` | string | Drop-into-LLM card. |

Sample:

```json
{
  "outputSchemaVersion": "2026-05-11",
  "recordType": "lever_job",
  "jobId": "a543d82a-a089-4b1c-afd1-4f30d3d8ee23",
  "companySlug": "palantir",
  "company": "Palantir",
  "title": "Administrative Business Partner",
  "hostedUrl": "https://jobs.lever.co/palantir/a543d82a-a089-4b1c-afd1-4f30d3d8ee23",
  "applyUrl": "https://jobs.lever.co/palantir/a543d82a-a089-4b1c-afd1-4f30d3d8ee23/apply",
  "location": { "name": "New York, NY", "normalized": "New York, NY", "isRemote": false },
  "team": "Administrative",
  "commitment": "Full-time",
  "department": null,
  "country": "US",
  "compRange": { "min": 60000, "max": 120000, "currency": "USD", "period": "year" },
  "categories": {
    "team": "Administrative",
    "location": "New York, NY",
    "commitment": "Full-time",
    "department": null,
    "allLocations": ["New York, NY"]
  },
  "createdAtMs": 1679955575647,
  "postedAt": "2023-03-27T22:19:35.647Z",
  "scrapedAt": "2026-05-11T18:00:00.000Z",
  "seniority": null,
  "fieldCompletenessScore": 90,
  "agentMarkdown": "**Administrative Business Partner** - Palantir\n- 👥 Administrative · 📋 Full-time\n- 📍 New York, NY\n- 💵 $60K-$120K/year\n- 📅 Posted 2023-03-27\n- 🔗 https://jobs.lever.co/palantir/a543d82a-a089-4b1c-afd1-4f30d3d8ee23"
}
```

#### company\_summary

One per company in the run.

| Field | Type | Notes |
|---|---|---|
| `recordType` | `'company_summary'` | Discriminator. |
| `companySlug` | string | |
| `company` | string | |
| `totalCount` | integer | All open jobs found, before filters. |
| `openedInLast7Days` | integer | Roles created in the last 7 days. |
| `hiringVelocityScore` | number | Jobs per day rolling 90-day window. |
| `jobsByTeam` | object | `{ teamName: count }`. |
| `jobsByLocation` | object | `{ locationName: count }`. |
| `jobsByCommitment` | object | `{ commitment: count }`. |

Sample:

```json
{
  "outputSchemaVersion": "2026-05-11",
  "recordType": "company_summary",
  "companySlug": "palantir",
  "company": "Palantir",
  "totalCount": 226,
  "openedInLast7Days": 14,
  "hiringVelocityScore": 1.47,
  "jobsByTeam": { "Engineering": 82, "Operations": 24, "Sales": 19 },
  "jobsByLocation": { "New York, NY": 41, "Washington, DC": 32, "London": 21 },
  "jobsByCommitment": { "Full-time": 204, "Internship": 18, "Fixed-Term": 4 },
  "scrapedAt": "2026-05-11T18:00:00.000Z"
}
```

### During the Actor run

The actor calls `api.lever.co/v0/postings/<slug>?mode=json` once per company, parses every record, and writes results as they go. Sub-minute per company. Two artifacts land in the default key-value store: `AGENT_BRIEFING` (markdown digest) and `WATCHLIST_STATE` (rolling ID list when watchlist mode is on).

### FAQ

#### How is this different from Lever's public RSS feeds?

Lever's RSS feed gives you a list of titles and links. This actor returns the parsed body of every posting, plus normalized location and country, parsed comp range, seniority, and per-company hiring snapshots. RSS is fine for "did anything change" notifications; the structured feed is what you need for analytics, sourcing, or AI agent context.

#### Can I monitor only new jobs?

Yes. Set `watchlistMode: true`. The actor reads a rolling list of up to 50,000 previously-seen job IDs from the key-value store and only emits jobs whose IDs are new. Schedule it daily and you have a diff feed.

#### Will this pair with Greenhouse coverage?

Yes. We ship a sister actor, `skootle/greenhouse-jobs`, with a near-identical output schema (matching `recordType`, `jobId`, `team`, `location`, `compRange`, `agentMarkdown`). Run both, union the datasets, and you cover both ATS platforms in one pipeline.

#### Why does this cost more than free Lever scrapers?

Free actors typically return Lever's raw JSON with no normalization. We parse comp ranges out of unstructured text, infer seniority from titles, strip HTML safely to plain text, compute a completeness score so you can self-filter, and ship an `agentMarkdown` field designed for LLM context. We also keep a versioned schema (`outputSchemaVersion`) so when Lever changes a field we bump the version and you know to update your downstream code. If you are feeding this into a customer-facing product or a daily AI-agent run, the reliability is the value.

#### Can I use it with Python / n8n / Make / Zapier?

Yes. Use the Apify API to start runs, poll status, and pull the dataset. The Apify client libraries exist for Python and JavaScript. n8n, Make, and Zapier all have native Apify nodes. Pass the same JSON input shape as the Console UI.

#### Why don't I see a salary on every job?

Lever does not return salary as a structured field. Some companies publish a range in the salary section (Palantir, for example), some publish it only in US states that require it by law, some never publish at all. When we find a range we parse it cleanly. When we cannot, `compRange.min` and `compRange.max` are null. Filter on `compRange.min !== null` to get only the rows where we resolved one.

#### How fresh is the data?

Real-time, every run. Lever's public API serves the same data their embed widget uses, with no caching layer in front of it on our side.

#### What happens if a company switches off Lever?

The fetch returns HTTP 404. We record an error entry in the `OUTPUT` summary with the offending slug and skip to the next company. Other companies in your list are unaffected.

#### Can I get historical postings?

Lever's public API only exposes currently-open roles. If a role closes, it disappears from the feed. If you want a historical archive, run the actor on a schedule and persist the dataset yourself.

#### Do I need to provide a proxy?

No. Lever's public API does not block by IP and has no bot challenge. The actor runs HTTP-only without a proxy. If you want to route through Apify Proxy for compliance reasons, you can pass `proxyConfiguration` and it will be honored.

### Why choose Lever Jobs

- **Hiring-velocity signal:** `company_summary.hiringVelocityScore` and `openedInLast7Days` give you a sortable BD trigger that no other Lever scraper computes.
- **Cross-ATS coverage:** pair with `skootle/greenhouse-jobs` (matching schema) for unified hiring data across both platforms.
- **Watchlist diff mode:** dedicated dedupe state across runs so monitoring schedules emit only new postings.
- **Parsed comp ranges:** numeric min, max, currency, and period, pulled out of unstructured salary text with a tested heuristic.
- **Seniority enum:** typed seniority instead of free-text title parsing every downstream system has to do.
- **Idempotent job IDs:** Lever's posting UUID is preserved so your downstream cache and dedupe keep working across runs.
- **Versioned output schema:** every record carries `outputSchemaVersion: '2026-05-11'`. We bump on breaking change.
- **Agent-grade extras:** `agentMarkdown` per record + `AGENT_BRIEFING.md` per run, drop straight into Claude / Codex / Slack / CRM.

#### Your feedback

Hit a bug or want a feature? Open an issue on the [Issues tab](https://apify.com/skootle/lever-jobs/issues/open) rather than the reviews page, and we'll fix it fast (typically within 48 hours).

### Other Skootle actors you might want to check

- [Greenhouse Jobs Scraper](https://apify.com/skootle/greenhouse-jobs) - the matching Greenhouse-side actor with the same schema shape.
- [Wellfound Jobs Scraper](https://apify.com/skootle/wellfound-jobs-scraper) - startup-focused board with founder profiles and equity data.
- [SAM.gov Federal Contracts](https://apify.com/skootle/sam-gov-federal-contracts) - U.S. federal contract opportunities joined with USAspending award history.
- [SEC EDGAR Filings](https://apify.com/skootle/sec-edgar-filings) - public company filings with normalized form-type taxonomy.

### Support and contact

Issues and feature requests via the Issues tab on this listing. We respond within 48 hours.

# Actor input Schema

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

Required. List of Lever job-board slugs to scrape. The slug is the path segment at jobs.lever.co/<slug>. Examples: 'palantir', 'veo'. Add as many as you want; each is fetched independently.

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

Case-insensitive title filter. A job is kept if ANY keyword appears in its title. Example: \['engineer','designer'].

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

Case-insensitive substring match against the Lever location field. Example: \['New York','London','Remote'].

## `teams` (type: `array`):

Filter by Lever team name. Example: \['Engineering','Product','Design'].

## `commitments` (type: `array`):

Filter by employment commitment as set on the Lever board.

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

When true, only jobs flagged remote by the company (workplaceType=remote OR 'Remote' in location) are returned.

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

Maximum job records to save across all companies. Default is conservative so the daily auto-test fits Apify's 5-minute window. Raise it for production runs.

## `watchlistMode` (type: `boolean`):

When true, the actor reads a rolling list of previously-seen job IDs from the key-value store and emits only jobs whose IDs have never been seen. Use for daily monitoring runs.

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

Optional Apify proxy configuration. Not required, Lever's public API is unrestricted.

## Actor input object example

```json
{
  "companies": [
    "palantir"
  ],
  "keywords": [],
  "locations": [],
  "teams": [],
  "commitments": [],
  "remoteOnly": false,
  "maxItems": 10,
  "watchlistMode": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Normalized Lever job records and per-company hiring snapshots.

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

Compact OUTPUT object with item count, error counts, and API call diagnostics.

## `agentBriefing` (type: `string`):

Per-run markdown digest with top-ranked jobs and per-company hiring snapshots.

# 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": [
        "palantir"
    ],
    "keywords": [],
    "locations": [],
    "teams": [],
    "commitments": [],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("skootle/lever-jobs").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": ["palantir"],
    "keywords": [],
    "locations": [],
    "teams": [],
    "commitments": [],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("skootle/lever-jobs").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "palantir"
  ],
  "keywords": [],
  "locations": [],
  "teams": [],
  "commitments": [],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call skootle/lever-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=skootle/lever-jobs",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "🦅 Lever Jobs Scraper",
        "description": "Scrape every open job from any Lever board. Returns title, team, location, commitment, country, parsed salary range, seniority, qualifications, and per-company hiring snapshots. Watchlist mode emits only new jobs since last run. Export, run via API, schedule, or integrate with other tools.",
        "version": "0.1",
        "x-build-id": "J7LAsFi5DVewIGIaX"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/skootle~lever-jobs/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-skootle-lever-jobs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/skootle~lever-jobs/runs": {
            "post": {
                "operationId": "runs-sync-skootle-lever-jobs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/skootle~lever-jobs/run-sync": {
            "post": {
                "operationId": "run-sync-skootle-lever-jobs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "companies"
                ],
                "properties": {
                    "companies": {
                        "title": "Lever company slugs",
                        "type": "array",
                        "description": "Required. List of Lever job-board slugs to scrape. The slug is the path segment at jobs.lever.co/<slug>. Examples: 'palantir', 'veo'. Add as many as you want; each is fetched independently.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Title keywords (optional)",
                        "type": "array",
                        "description": "Case-insensitive title filter. A job is kept if ANY keyword appears in its title. Example: ['engineer','designer'].",
                        "items": {
                            "type": "string"
                        }
                    },
                    "locations": {
                        "title": "Locations (optional)",
                        "type": "array",
                        "description": "Case-insensitive substring match against the Lever location field. Example: ['New York','London','Remote'].",
                        "items": {
                            "type": "string"
                        }
                    },
                    "teams": {
                        "title": "Teams (optional)",
                        "type": "array",
                        "description": "Filter by Lever team name. Example: ['Engineering','Product','Design'].",
                        "items": {
                            "type": "string"
                        }
                    },
                    "commitments": {
                        "title": "Commitment types (optional)",
                        "type": "array",
                        "description": "Filter by employment commitment as set on the Lever board.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Full-time",
                                "Part-time",
                                "Contract",
                                "Internship",
                                "Fixed-Term",
                                "Scholarship",
                                "Temporary"
                            ],
                            "enumTitles": [
                                "Full-time",
                                "Part-time",
                                "Contract",
                                "Internship",
                                "Fixed-Term",
                                "Scholarship",
                                "Temporary"
                            ]
                        }
                    },
                    "remoteOnly": {
                        "title": "Remote only",
                        "type": "boolean",
                        "description": "When true, only jobs flagged remote by the company (workplaceType=remote OR 'Remote' in location) are returned.",
                        "default": false
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum job records to save across all companies. Default is conservative so the daily auto-test fits Apify's 5-minute window. Raise it for production runs.",
                        "default": 10
                    },
                    "watchlistMode": {
                        "title": "Watchlist mode (new jobs only)",
                        "type": "boolean",
                        "description": "When true, the actor reads a rolling list of previously-seen job IDs from the key-value store and emits only jobs whose IDs have never been seen. Use for daily monitoring runs.",
                        "default": false
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration (optional)",
                        "type": "object",
                        "description": "Optional Apify proxy configuration. Not required, Lever's public API is unrestricted."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
