# Lever Jobs Scraper - Postings API by Company (`make_no_mistakes/lever-jobs-scraper`) Actor

Scrape open jobs from any company on Lever (jobs.lever.co), US and EU instances. Type a company name or domain; the Lever site is found for you. Commitment, team, workplace type, salary range, all locations, apply URL. Delta mode for daily runs.

- **URL**: https://apify.com/make_no_mistakes/lever-jobs-scraper.md
- **Developed by:** [Make No Mistakes LLC](https://apify.com/make_no_mistakes) (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

from $0.60 / 1,000 job scrapeds

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

## Lever Jobs Scraper: Postings API by Company

Scrape every open job from any company's Lever job board (`jobs.lever.co`, and EU-hosted
`jobs.eu.lever.co` boards). Type a company name, a domain, a Lever site name or a board URL. The
Actor finds the Lever site and region for you and returns each job with its team, department,
commitment, workplace type, every location, salary range where published, full description and
apply URL.

| Company | Title | Team | Commitment | Workplace | Location | Pay | Apply |
|---|---|---|---|---|---|---|---|
| Spotify | Android Engineer - Experience | Experience | Permanent | hybrid | London, Stockholm | | [apply](https://jobs.lever.co/spotify/2193db3f-77c5-43b8-b030-8f92c9882bf1/apply) |
| Spotify | Artist Label Partnerships Manager, Taiwan | Music Marketing | Permanent | onsite | Taiwan | | [apply](https://jobs.lever.co/spotify/77526d53-3811-4336-9c0d-72f6ac0242c7/apply) |
| Palantir | Administrative Business Partner | Administrative | Full-time | hybrid | London, United Kingdom | | [apply](https://jobs.lever.co/palantir/ac978161-6f46-4f6b-ad9e-a258e642751c/apply) |
| Match Group | Android Engineer III | Engineering (Hinge) | Full-time | hybrid | New York, New York | 150,000 - 180,000 USD / year | [apply](https://jobs.lever.co/matchgroup/cb977666-1e41-4098-ad9c-6ab387e56a7a/apply) |
| Match Group | AI Product Engineer | Internships | Internship | hybrid | Vancouver, British Columbia | 35 - 38 CAD / hour | [apply](https://jobs.lever.co/matchgroup/69396299-e587-4063-aef6-0ce2fd66e9ee/apply) |

*Real rows from the default run on 2026-10-03.*

**Try it: the default input returns 254 jobs (Spotify 82, Palantir 100 of 319, Match Group 72) for
about $0.51**, in about 6 seconds. No login, no proxy, no API key: it reads Lever's official public
Postings API.

### What is Lever-specific here

- **US and EU Lever, automatically.** Lever runs two separate postings APIs: `api.lever.co` and
  `api.eu.lever.co` (EU data residency). Scrapers that only read the US one report EU-hosted
  employers as having no jobs. This Actor checks both regions and uses the one with the larger
  board; `lever_region` tells you which. Board URLs on either host work.
- **Company name in, Lever site out.** `Match Group` resolves to `matchgroup`, `palantir.com` to
  `palantir`. If you give a domain and the name guess misses, the company's careers page is read for
  its Lever link.
- **Lever's own fields as filters:** `commitments` (Full-time, Permanent, Internship, Contract...),
  `teams` (team or department) and `workplaceTypes` (remote, hybrid, on-site).
- **Pay where published**, with the right interval: Lever's structured `salaryRange` comes back as
  `salary_min`/`salary_max`/`salary_currency`/`salary_period` (Match Group's intern rate is
  `HOUR`, its engineering roles `YEAR`), plus the employer's pay note in `salary_description`.
- **Every location** in `all_locations`, not just the primary one.
- **Companies not on Lever are reported, not dropped.** You get a free `company_not_found` row
  naming where the company actually hires, e.g. `not on Lever: this company's job board is on
  Greenhouse (https://job-boards.greenhouse.io/stripe)`.

### Use cases

- **Recruiting and sourcing:** watch competitors' Lever boards by team and get each new posting
  the day it opens with delta mode.
- **Sales signals:** hiring bursts in a team ("Data Platform", "RevOps") as a buying signal.
- **Job boards and aggregators:** clean, deduplicated, normalized jobs with real apply URLs.
- **Internship and early-career boards:** `commitments: ["Intern"]` across hundreds of companies.
- **Job seekers:** a daily alert of new roles at your target companies.

### Input

```json
{
  "companies": ["Spotify", "palantir.com", "https://jobs.lever.co/matchgroup"],
  "keywords": ["engineer"],
  "locations": ["New York", "London", "Remote"],
  "remoteOnly": false,
  "postedWithinDays": 30,
  "commitments": ["Full-time", "Permanent"],
  "teams": ["Engineering"],
  "workplaceTypes": ["remote", "hybrid"],
  "onlyNewSinceLastRun": false,
  "includeDescription": true,
  "maxItems": 1000,
  "maxItemsPerCompany": 100
}
```

| Field | What it does |
|---|---|
| `companies` | Names, domains, Lever site names or board URLs (US or EU), mixed freely. |
| `keywords` | Keep jobs whose title, department or team contains any of these words. |
| `locations` | Keep jobs whose location contains any of these strings. |
| `remoteOnly` | Keep only jobs whose workplace type or location says remote. |
| `postedWithinDays` | Keep only jobs created in the last N days. |
| `commitments` | Lever-only: match the commitment (case-insensitive, partial). |
| `teams` | Lever-only: match the team or department. |
| `workplaceTypes` | Lever-only: remote, hybrid, on-site. |
| `onlyNewSinceLastRun` | Delta mode: only jobs you have not received before (see below). |
| `deltaStateName` | Name of the key-value store that remembers delivered jobs, one per schedule. |
| `includeDescription` | Set false to drop the description fields (smaller items, same price). |
| `maxItems` | Total jobs per run, and so your spend cap. |
| `maxItemsPerCompany` | Jobs per company (default 100). Set 0 for whole boards. |

### Output

Every job uses the same normalized schema as the
[Multi-ATS Job Board API](https://apify.com/make_no_mistakes/multi-ats-job-board-api), plus
Lever-specific fields:

```json
{
  "record_type": "job",
  "company": "Match Group",
  "title": "Android Engineer III",
  "team": "Engineering",
  "department": "Hinge",
  "commitment": "Full-time",
  "workplace_type": "hybrid",
  "location_raw": "New York, New York",
  "city": "New York",
  "country": "US",
  "is_remote": false,
  "employment_type": "FULL_TIME",
  "salary_min": 150000,
  "salary_max": 180000,
  "salary_currency": "USD",
  "salary_period": "YEAR",
  "posted_at": "2026-08-21",
  "apply_url": "https://jobs.lever.co/matchgroup/cb977666-1e41-4098-ad9c-6ab387e56a7a/apply",
  "company_slug": "matchgroup",
  "ats": "lever",
  "job_id": "cb977666-1e41-4098-ad9c-6ab387e56a7a",
  "source_url": "https://api.lever.co/v0/postings/matchgroup",
  "lever_site": "matchgroup",
  "lever_region": "us",
  "all_locations": ["New York, New York"],
  "hosted_url": "https://jobs.lever.co/matchgroup/cb977666-1e41-4098-ad9c-6ab387e56a7a",
  "salary_description": "Factors such as scope and responsibilities of the position, ... This salary range is reflective of a position based in New York City. ..."
}
```

`description_html` and `description_text` carry the full posting (opening, body, every list and
the closing section, assembled in order), and `raw` keeps the untouched Lever record. Lever's
public API publishes a created date only, so `updated_at` is null by design.

Dataset views: **Jobs**, **Lever details** and **Companies not on Lever**. `RUN_SUMMARY` in the
key-value store records how each company was resolved and the jobs per company.

### Delta mode for scheduled runs

Set `onlyNewSinceLastRun: true` and schedule the Actor. The first run returns everything and
remembers it; later runs return only jobs not delivered before, and **never charge twice for the
same job**. State lives in a named key-value store in your own account (`deltaStateName`), one
record per board.

### Pricing

Pay per event, no subscription:

| | Free plan | Bronze | Silver | Gold and up |
|---|---|---|---|---|
| Per job | $0.002 | $0.0015 | $0.001 | $0.0006 |
| Per run start | $0.001 | $0.001 | $0.001 | $0.001 |

- 100 jobs on the Free plan: about **$0.20**. 1,000 jobs: about **$2.00**.
- Filters run before charging: you pay only for jobs that pass them.
- `company_not_found` rows are free.
- `maxItems` is a hard spend cap. If your run's **Maximum cost per run** is too low for the jobs in
  scope, the run says so on its status line and in `RUN_SUMMARY`.

### No login, no proxy, official public API

Lever publishes its Postings API (`api.lever.co/v0/postings/{site}`, and the EU equivalent) so
employers' jobs can be listed anywhere. No account, cookies or proxies are involved.

### Related Actors

- [Multi-ATS Job Board API](https://apify.com/make_no_mistakes/multi-ats-job-board-api): one run
  across nine ATS platforms, for company lists that span Lever, Greenhouse, Ashby, Workday and more.
- [Company ATS Detector](https://apify.com/make_no_mistakes/company-ats-detector) (free): which
  ATS does a company use?
- [Greenhouse Jobs Scraper](https://apify.com/make_no_mistakes/greenhouse-jobs-scraper),
  [Ashby Jobs Scraper](https://apify.com/make_no_mistakes/ashby-jobs-scraper) and
  [Workday Jobs Scraper](https://apify.com/make_no_mistakes/workday-jobs-scraper).

### API example

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/make_no_mistakes~lever-jobs-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"companies": ["Spotify", "Palantir"], "teams": ["Engineering"], "maxItemsPerCompany": 50}'
```

### FAQ

**My company is on Lever but was not found.** Pass its board URL (`https://jobs.lever.co/<site>` or
`https://jobs.eu.lever.co/<site>`) or its domain. The Lever site name is sometimes not the company
name.

**Why do so few Lever jobs have pay?** Lever's salary range is optional for employers. In the
default run, 40 of 254 jobs had one; `salary_description` often explains the range when there is one.

**Is this affiliated with Lever?** No. This is an independent tool, not affiliated with, endorsed by
or sponsored by Lever (Employ Inc.). The name only describes which job boards it reads.

Published by Make No Mistakes LLC. Questions and feature requests: open an issue on this Actor's
Issues tab.

# Actor input Schema

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

Companies whose Lever job boards you want. Accepts company names ("Spotify"), domains ("palantir.com"), Lever site names ("matchgroup") or board URLs ("https://jobs.lever.co/matchgroup", "https://jobs.eu.lever.co/..."), mixed freely. A company that is not on Lever comes back as a free company_not_found row naming the ATS it does use. Default: \["Spotify", "Palantir", "Match Group"].

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

Keep a job when its title, department or team contains any of these words (case-insensitive). Default: empty = every job. Example: \["engineer", "data"].

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

Keep a job when any of these strings appears in its location, city, state or country (case-insensitive). Default: empty = every location. Example: \["New York", "London", "US"].

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

Default: false. When true, keep only jobs flagged remote or whose location says remote, anywhere or distributed.

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

Keep only jobs posted (or updated) in the last N days. Default: empty = the whole board. Example: 7.

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

Keep a job when its Lever commitment contains any of these strings (case-insensitive). Default: empty = any. Example: \["Full-time", "Intern"].

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

Keep a job when its Lever team or department contains any of these strings (case-insensitive). Default: empty = any. Example: \["Engineering"].

## `workplaceTypes` (type: `array`):

Keep only jobs with this Lever workplace type. Default: empty = any.

## `onlyNewSinceLastRun` (type: `boolean`):

Default: false. When true, return only jobs this setup has not returned before, so a scheduled run never pays twice for the same posting. State is kept per board in a named key-value store in your own account (see deltaStateName). The first run returns everything and records it. Already-delivered jobs are dropped before they are written and are never charged.

## `deltaStateName` (type: `string`):

Name of the key-value store in your account that remembers delivered jobs. Only used with onlyNewSinceLastRun. Use a different name per independent schedule. Default: "lever-jobs-scraper-delta".

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

Default: true. Set false to drop description_html and description_text, making each item about 10x smaller. The price is the same either way.

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

Maximum jobs returned across all companies, filled in company order. This is also your spend cap: $0.002 per job, so 1,000 jobs = $2.00. Default: 1000. 0 = unlimited.

## `maxItemsPerCompany` (type: `integer`):

Maximum jobs returned per company, so one huge board cannot use up the run. Default: 100. 0 = no per-company cap (a large employer can have several thousand open jobs).

## Actor input object example

```json
{
  "companies": [
    "Spotify",
    "Palantir",
    "Match Group"
  ],
  "remoteOnly": false,
  "onlyNewSinceLastRun": false,
  "includeDescription": true,
  "maxItems": 1000,
  "maxItemsPerCompany": 100
}
```

# Actor output Schema

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

One item per open Lever job (record_type = job), plus one free item per input that is not on Lever (record_type = company_not_found).

## `jobsCsv` (type: `string`):

The same items as CSV.

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

RUN_SUMMARY record: filters used, jobs per company, how each company was resolved, companies not on this platform, delta-mode counts, and whether the run was truncated by a cost limit.

# 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": [
        "Spotify",
        "Palantir",
        "Match Group"
    ],
    "maxItems": 1000,
    "maxItemsPerCompany": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("make_no_mistakes/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 = {
    "companies": [
        "Spotify",
        "Palantir",
        "Match Group",
    ],
    "maxItems": 1000,
    "maxItemsPerCompany": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("make_no_mistakes/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 '{
  "companies": [
    "Spotify",
    "Palantir",
    "Match Group"
  ],
  "maxItems": 1000,
  "maxItemsPerCompany": 100
}' |
apify call make_no_mistakes/lever-jobs-scraper --silent --output-dataset

```

## MCP server setup

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