# Lever ATS Jobs Scraper – Scrape Lever.co (`logiover/lever-postings-scraper`) Actor

Unofficial Lever.co API: scrape Lever ATS job postings and salary data without an API key, export to CSV/JSON. No login, global + EU instances.

- **URL**: https://apify.com/logiover/lever-postings-scraper.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** Jobs, Lead generation, AI
- **Features:** Limited permissions
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 results

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 ATS Jobs Scraper — Scrape Lever.co Postings, Salary & Descriptions (No API)

![Lever Postings Scraper](https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/GjS6nQ8qauOdq9KGy-actor-w1uWcDERGNygNdJd2-d2TSpSDi7q-lever_icon.png)

![Apify Actor](https://img.shields.io/badge/Apify-Actor-00A67E?logo=apify\&logoColor=white) ![No API key](https://img.shields.io/badge/No%20API%20key-required-2ea44f) ![Pay per result](https://img.shields.io/badge/Pricing-Pay%20per%20result-1C7ED6) ![Jobs](https://img.shields.io/badge/Category-Jobs-8B5CF6) ![Export](https://img.shields.io/badge/Export-JSON%20%7C%20CSV%20%7C%20Excel-F59E0B)

Scrape job postings, structured **salary data**, workplace type and full descriptions from any company that hires through the **Lever ATS**. Point this Lever scraper at one or more `jobs.lever.co/{company}` boards and it returns clean, normalized records with **title, team, location, workplace type, salary range, apply links & full job descriptions** — ready to export to CSV, JSON or Excel. Works across thousands of Lever-powered career pages (currently verified examples include Spotify, Palantir, Veeva, Match Group, Lyra Health and Highspot), supports both the **global and EU** Lever instances, and exposes Lever's native server-side filters plus extra client-side filtering. **Fast, no browser, no API key, no login.**

> ### 🏆 Why this Lever scraper?
>
> **20+ fields per posting** · **all open roles from a board in one call** · direct HTTP + JSON (no browser) · native Lever server-side filters + client-side salary/country/workplace filters · global + EU instances · export to JSON / CSV / Excel. The unofficial **Lever Postings API alternative** for recruiting, salary benchmarking and job-aggregator ingestion.

***

### ✨ What this Actor does / Key features

- 🧩 **Whole boards or single postings** — `jobs` mode lists every open role from a board; `jobDetail` mode fetches specific postings by UUID with full descriptions and structured lists.
- 🏢 **Thousands of Lever companies** — any active account on `jobs.lever.co/{company}` works; currently verified examples include Spotify, Palantir, Veeva, Match Group, Lyra Health and Highspot. Employers can migrate ATS providers, so always use the handle from the company's current careers link.
- 🌍 **Global + EU instances** — switch between `global` (api.lever.co) and `eu` (api.eu.lever.co) so you can reach European-only employers that 404 on the global endpoint.
- 💰 **Structured salary data** — disclosed compensation is normalized into `salaryMin`, `salaryMax` and `salaryCurrency`, plus a client-side minimum-salary filter to drop undisclosed roles.
- ⚡ **Fast server-side filters** — Lever-native `team`, `department`, `location`, `commitment`, `level`, `limit`, `skip` and `group` are applied by Lever's servers before data is transferred.
- 🎯 **Extra client-side filters** — narrow by title keywords, workplace type (on-site / remote / hybrid), ISO country code and minimum disclosed salary — criteria Lever can't filter on natively.
- 🗺️ **Rich location data** — primary `location`, `allLocations`, ISO 3166-1 alpha-2 `country` and `workplaceType` for every posting.
- 📝 **Full descriptions** — in `jobDetail` mode, get `fullDescriptionPlain` plus structured `lists` (requirements, responsibilities, benefits) and disclosed salary description.
- 🔗 **Public links** — `hostedUrl` (public listing) and `applyUrl` (direct apply link) for every role.
- 🚀 **Direct HTTP + JSON extraction** — reads Lever's public postings endpoints; no headless browser, no DOM walking, no auth token.
- ⚙️ **Batch-friendly** — fetch multiple sites in parallel with adjustable concurrency and per-site result caps for cost control.

### 🚀 Quick start (3 steps)

1. **Configure** — pick a **Mode** (`jobs`), add one or more **Lever sites** (the `{company}` from `jobs.lever.co/{company}`, e.g. `leverdemo`), and choose the **Instance** (`global` or `eu`). Add filters if you want.
2. **Run** — click **Start**. The Actor calls Lever's postings endpoint once per site and streams normalized postings into your dataset.
3. **Get your data** — open the **Output** tab and export to **JSON, CSV, JSONL, Excel or XML**, or pull it via the Apify API.

### 📥 Input

Give the Actor a **Mode** and at least one **Lever site**. Everything else is optional. Try `leverdemo` as a guaranteed-working smoke test.

#### Example — all postings from a company board

```json
{
  "mode": "jobs",
  "sites": ["leverdemo"],
  "instance": "global"
}
```

#### Example — remote engineering roles with disclosed salary

```json
{
  "mode": "jobs",
  "sites": ["lyrahealth"],
  "instance": "global",
  "team": ["Engineering"],
  "filterWorkplaceTypes": ["remote"],
  "filterSalaryMin": 100000
}
```

#### Example — multiple companies, US-only, full-time

```json
{
  "mode": "jobs",
  "sites": ["leverdemo", "highspot", "lyrahealth"],
  "instance": "global",
  "commitment": ["Full Time"],
  "filterCountries": ["US"],
  "concurrency": 5,
  "maxResultsPerSite": 200
}
```

#### Example — deep detail for specific postings (jobDetail mode)

```json
{
  "mode": "jobDetail",
  "sites": ["leverdemo"],
  "instance": "global",
  "jobIds": ["5ac21346-8e0c-4494-8e7a-3eb92ff77902"]
}
```

| Field | Type | Description |
|-------|------|-------------|
| `mode` | string | `jobs` (list all postings, one call per site) or `jobDetail` (fetch single postings by ID). **Required.** |
| `sites` | array | One or more Lever site names — the `{company}` in `jobs.lever.co/{company}`. Case-sensitive. In `jobDetail` mode only the first site is used. |
| `instance` | string | `global` (api.lever.co) or `eu` (api.eu.lever.co). Switch to `eu` if a company 404s on global. |
| `jobIds` | array | Posting UUIDs to fetch. Required when `mode = jobDetail`. E.g. `5ac21346-8e0c-4494-8e7a-3eb92ff77902`. |
| `team` | array | **Server-side** Lever filter. Case-sensitive (`Engineering`, not `engineering`). Multiple values OR'ed. |
| `department` | array | **Server-side** Lever filter on department / org unit. Case-sensitive. |
| `location` | array | **Server-side** Lever filter. Case-sensitive. E.g. `San Francisco`, `Remote - US`. |
| `commitment` | array | **Server-side** employment-type filter: `Full Time`, `Part Time`, `Internship`, `Contract`. |
| `level` | array | **Server-side** seniority filter. Customer-defined values (`Senior`, `Junior`, `Director`). |
| `limit` | integer | Lever's native `?limit=` — caps postings the server returns per board. 0 = no cap. |
| `skip` | integer | Lever's native `?skip=` — pagination offset; skip N postings before returning. |
| `group` | string | Lever's native `?group=`: `none`, `team`, `commitment` or `location`. |
| `filterTitleKeywords` | array | **Client-side**: keep only postings whose title contains any keyword (case-insensitive). |
| `filterWorkplaceTypes` | array | **Client-side**: keep only `on-site`, `remote`, `hybrid` or `unspecified` roles. |
| `filterCountries` | array | **Client-side**: keep only postings matching these ISO 3166-1 alpha-2 codes (`US`, `GB`, `DE`). |
| `filterSalaryMin` | integer | **Client-side**: keep only postings with `salaryRange.min` ≥ this. Undisclosed-salary roles are dropped. 0 = disabled. |
| `maxResultsPerSite` | integer | Hard cap applied after all filters. 0 = unlimited. Useful for testing / cost control. |
| `concurrency` | integer | How many sites to fetch in parallel (1–20). 5 is a safe default. |

> **Finding a company's Lever handle:** open the company's current careers page. If the URL looks like `https://jobs.lever.co/highspot`, the handle (site) is `highspot`. Many companies also link out from a "View all jobs" button that lands on their `jobs.lever.co` board. If a valid board returns 404 on `global`, check whether its current link uses Lever's **EU** instance; a 404 can also mean the employer migrated away from Lever or the handle is stale.

#### Additional input fields

These optional fields are also available in the input form and API:

| Field | Type | Default | Description |
|---|---|---|---|
| `maxResults` | integer | `500` | Global cap across all sites. Keeps the default empty-input run fast and cheap. Set 0 for no overall limit (pull every posting on every site). |

### 📤 Output

One row per posting — exportable to JSON, CSV, JSONL, Excel or XML. Here is a trimmed sample record from `jobs` mode:

```json
{
  "_mode": "jobs",
  "site": "leverdemo",
  "instance": "global",
  "id": "5ac21346-8e0c-4494-8e7a-3eb92ff77902",
  "title": "Senior Backend Engineer",
  "team": "Engineering",
  "department": "Product Engineering",
  "location": "San Francisco, CA",
  "allLocations": ["San Francisco, CA", "Remote - US"],
  "workplaceType": "hybrid",
  "country": "US",
  "commitment": "Full Time",
  "level": "Senior",
  "salaryMin": 160000,
  "salaryMax": 210000,
  "salaryCurrency": "USD",
  "createdAtIso": "2026-06-28T15:42:11.000Z",
  "hostedUrl": "https://jobs.lever.co/leverdemo/5ac21346-8e0c-4494-8e7a-3eb92ff77902",
  "applyUrl": "https://jobs.lever.co/leverdemo/5ac21346-8e0c-4494-8e7a-3eb92ff77902/apply",
  "scrapedAt": "2026-07-06T12:00:00.000Z"
}
```

<details>
<summary><b>📋 Full field reference (click to expand)</b></summary>

| Field | Description |
|-------|-------------|
| `_mode` | Actor mode that produced this record (`jobs` or `jobDetail`) |
| `site` | Lever account name (the `{company}` in the board URL) |
| `instance` | Lever instance used: `global` or `eu` |
| `id` | UUID of the posting |
| `title` | Job title |
| `team` | Internal team name |
| `department` | Department / org unit |
| `location` | Primary office location |
| `allLocations` | All office locations for the posting (array) |
| `workplaceType` | `on-site`, `remote`, `hybrid` or `unspecified` |
| `country` | ISO 3166-1 alpha-2 country code |
| `commitment` | Employment type (Full Time, Part Time, Internship, Contract) |
| `level` | Seniority level where the employer discloses it |
| `salaryMin` / `salaryMax` | Disclosed minimum / maximum salary |
| `salaryCurrency` | Salary currency code |
| `salaryRange` | Raw salary range object (min, max, currency, interval) |
| `salaryDescriptionPlain` | Employer's free-text salary description *(jobDetail mode)* |
| `fullDescriptionPlain` | Full job description as plain text *(jobDetail mode)* |
| `lists` | Structured sections — requirements, responsibilities, benefits *(jobDetail mode)* |
| `createdAtIso` | Posting creation timestamp (ISO 8601) |
| `hostedUrl` | Public Lever-hosted listing page |
| `applyUrl` | Direct apply link |
| `scrapedAt` | When this record was produced (ISO 8601) |

</details>

#### Additional output fields

These fields are also present in the dataset:

| Field | Type | Description |
|---|---|---|
| `additional` | string | Additional |
| `additionalPlain` | string | Additional plain |
| `createdAt` | number | Created at |
| `descriptionBody` | string | Description body |
| `descriptionBodyPlain` | string | Description body plain |
| `descriptionPlain` | string | Description plain |
| `fullDescription` | string | Full description |
| `opening` | string | Opening |
| `openingPlain` | string | Opening plain |
| `salaryDescription` | string | Salary description |
| `salaryInterval` | string | Salary interval |

### 💡 Use cases

- **Recruiting & sales leads** — build a list of companies actively hiring through Lever, segmented by team, location or workplace type.
- **Salary benchmarking** — collect disclosed pay ranges across many Lever boards for compensation research, using `salaryMin` / `salaryMax` and the minimum-salary filter.
- **ATS jobs export** — mirror a specific company's open roles into your own ATS, CRM or spreadsheet.
- **Job aggregator ingestion** — feed thousands of fresh, structured Lever postings into a job board or app.
- **Hiring-trend analytics** — track headcount signals (new roles per team, remote vs. on-site mix) over time by re-running on a schedule and diffing on `createdAtIso`.
- **Talent-market mapping** — pass multiple `sites` in one run to compare open roles across competitors.

### 👥 Who uses it

Recruiters & talent-acquisition teams · staffing & RPO agencies · sales teams doing hiring-signal prospecting · compensation & people-analytics teams · job boards and aggregators ingesting fresh postings · market researchers & data journalists tracking hiring trends · founders benchmarking roles and pay against peer companies.

### 💰 Pricing

This Actor runs on a simple **pay-per-result** model — you pay for the postings you extract, with no separate Apify platform fees to calculate. Try it on the **free tier** first, then scale up. See the **Pricing** tab on this page for the current rate.

### ❓ Frequently Asked Questions

**Is it legal to scrape Lever.co?**
The Actor only collects publicly available job posting data from public `jobs.lever.co` career pages. You are responsible for using the data in compliance with Lever's terms and applicable laws such as GDPR.

**Does Lever have a public API? Is this a Lever Postings API alternative?**
Lever exposes a public postings endpoint per company board, but it is raw and unnormalized. This Actor reads those public endpoints directly and returns clean, normalized records with structured salary, workplace type and country fields — giving you an unofficial **Lever Postings API alternative** with no key, token or official API access required.

**Can I scrape Lever jobs without an API key or login?**
Yes. The Actor uses pure HTTP against public Lever ATS career pages — no API key, no login, no auth token and no headless browser are required. You only need an Apify account.

**How do I find a company's Lever handle (site)?**
It is the company account name in the board URL: `https://jobs.lever.co/{site}`. For example, the site for `https://jobs.lever.co/highspot` is `highspot`. Open the company's current careers page and check whether it redirects to a `jobs.lever.co` URL — the segment after the slash is the handle.

**Why am I getting 404s for a company?**
First verify the handle from the company's current careers page: employers can migrate away from Lever and old handles then return 404. If the current board is still Lever-hosted, check whether it uses Lever's **EU instance** and switch **Instance** from `global` to `eu` (api.eu.lever.co). If every requested handle fails, the actor now fails the run explicitly instead of reporting a misleading successful empty dataset.

**Can I get salary data from Lever?**
Yes, when the employer discloses it. Postings carry structured `salaryMin`, `salaryMax` and `salaryCurrency` fields, and you can drop unpaid/undisclosed roles with the `filterSalaryMin` filter.

**How do I export Lever job postings to CSV or JSON?**
Run the Actor on your Lever sites, then download the dataset in CSV, JSON, JSONL, Excel or XML from the run — or fetch it through the Apify API.

**How much data can I get?**
`jobs` mode returns every open posting on a board in a single call, and you can batch many companies per run. Use `limit` / `skip` for Lever-native pagination and `maxResultsPerSite` to cap output for testing or cost control.

**How do I scrape all engineering jobs from a company's Lever board?**
Enter the company's Lever site name, set the `team` filter to `Engineering` (case-sensitive) and run — the Actor returns every matching posting with location, workplace type and salary when disclosed.

**How do I get only remote jobs with disclosed salaries from Lever?**
Set `filterWorkplaceTypes` to `remote` and `filterSalaryMin` above zero; postings without a remote workplace type or a disclosed salary are dropped, leaving a clean remote, paid job list.

**What's the difference between `jobs` and `jobDetail` mode?**
`jobs` lists all postings from each board (one call per site) with the core fields. `jobDetail` fetches specific postings by UUID and adds the full description (`fullDescriptionPlain`) and structured `lists` such as requirements and responsibilities.

### 🔗 More job scrapers by logiover

Building a hiring dataset across ATS platforms and job boards? Pair the Lever scraper with the rest of the jobs suite:

| Source | Actor |
|---|---|
| 🧩 Greenhouse ATS | [Greenhouse Job Board Scraper](https://apify.com/logiover/greenhouse-job-board-scraper) |
| 🇩🇪 Arbeitnow | [Arbeitnow Jobs Scraper](https://apify.com/logiover/arbeitnow-jobs-scraper) |
| 🌐 Indeed | [Indeed Jobs Scraper](https://apify.com/logiover/indeed-jobs-scraper) |
| 💼 The Muse | [The Muse Jobs Scraper](https://apify.com/logiover/the-muse-jobs-scraper) |
| ⛰️ Himalayas | [Himalayas Remote Jobs Scraper](https://apify.com/logiover/himalayas-remote-jobs-scraper) |
| 🇫🇷 Welcome to the Jungle | [Welcome to the Jungle Jobs Scraper](https://apify.com/logiover/welcome-to-the-jungle-jobs-scraper) |
| 🇦🇺 SEEK | [SEEK Jobs Scraper](https://apify.com/logiover/seek-jobs-scraper) |
| 🇩🇪 StepStone | [StepStone.de Jobs Scraper](https://apify.com/logiover/stepstone-scraper) |
| 🧵 Jobicy | [Jobicy Remote Jobs Scraper](https://apify.com/logiover/jobicy-remote-jobs-scraper) |
| 🗞️ HN "Who is hiring?" | [Hacker News Who Is Hiring Scraper](https://apify.com/logiover/hacker-news-who-is-hiring-scraper) |

👉 Browse all **[logiover scrapers on Apify Store](https://apify.com/logiover)** — 180+ actors across real estate, jobs, crypto, social media & B2B data.

### ⏰ Scheduling & integration

Schedule this Actor on Apify to track Lever hiring daily or weekly. Export results to JSON, CSV or Excel, sync to Google Sheets, or push to your database, BI tools and webhooks through the Apify API. Connect it to **Make, n8n or Zapier** to build automated recruiting, sourcing and hiring-analytics pipelines.

### 🤖 AI Agents, MCP & RAG Integration

**Lever ATS Jobs Scraper – Scrape Lever.co** works natively as an on-demand data tool for AI assistants and autonomous workflows.

Connect this Actor directly to **Apify AI**, **Claude Desktop**, **Cursor**, **VS Code**, **Windsurf**, **LangChain**, or **LlamaIndex** via the official **Apify MCP Server** — no custom wrapper code needed:

```json
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=logiover/lever-postings-scraper"
    }
  }
}
```

- **Schema-typed inputs & outputs:** Clean JSON records with explicit `.actor/input_schema.json` and `.actor/output_schema.json` definitions so LLM agents infer parameters and parse fields accurately without HTML noise.
- **Bounded & predictable runs:** Built-in volume caps and pay-per-result budget guards prevent runaway agent tool loops.
- **RAG & automation ready:** Stream run datasets straight into vector stores, n8n, Make, Zapier, or webhook pipelines.

### 💬 Support, Issues & Reviews

- **Bug reports & target-site changes:** Hit an unexpected empty result or selector change? [Open a ticket in the Issues tab](https://apify.com/logiover/lever-postings-scraper/issues) with your **Run ID** or sample input — we actively monitor issues and ship fixes fast.
- **Feature & field requests:** Need an additional data attribute or filter? [Request it in the Issues tab](https://apify.com/logiover/lever-postings-scraper/issues).
- **Enjoying this Actor?** If it saved you engineering time, please consider leaving an honest [review on Apify Store](https://apify.com/logiover/lever-postings-scraper/reviews) or bookmarking [logiover/lever-postings-scraper](https://apify.com/logiover/lever-postings-scraper) — organic developer feedback helps others discover reliable tools and keeps maintenance prioritized.

### ⚖️ Legal

This Actor extracts only publicly available data and is intended for legitimate recruiting, research, analytics and lead-generation use. You are responsible for complying with Lever's terms of service, GDPR and any applicable local laws.

***

This Actor is an independent tool. It is not affiliated with, endorsed by, or sponsored by Lever ATS; Lever ATS and all other trademarks mentioned here are the property of their respective owners.

### Lever ATS scraping — frequently asked questions

#### Do I need a Lever ATS API key, account or login?

No. This Actor reads publicly available pages and feeds, so there is nothing to register for and no credentials to manage.

#### How do I export Lever ATS data to CSV, Excel, JSON or Google Sheets?

Open the **Storage** tab after a run and pick the format you want — CSV, Excel, JSON, XML or an HTML table. For Google Sheets, Airtable or a database, use the dataset URL or the Apify API so the sheet refreshes itself on every run.

#### Can I schedule this Lever ATS scraper to run daily or hourly?

Yes. Use the **Schedules** tab and pick a cadence. Daily is enough for most tracking work; pick hourly only if the posts you care about really do change that fast.

#### How many posts can I get, and what does it cost?

See the volume section above for a measured figure. Billing is per result, so you pay for the rows you actually receive and a run that finds nothing costs nothing.

#### Is scraping Lever ATS legal?

This Actor collects only information that Lever ATS publishes publicly. It does not log in, does not defeat access controls and does not touch private data. You remain responsible for how you use the output, including under GDPR and similar rules where personal data is involved.

#### What happens if Lever ATS blocks the run or changes its layout?

A refused exit IP is swapped for a fresh one within a quarter of a second and retried, and rate limiting is waited out rather than fought. If nothing gets through, the run **fails with the reason** instead of reporting success with zero rows — so an empty result always means "no matches", never "the source would not answer".

#### Can I use this with an AI agent, LangChain or an MCP client?

Yes. The Actor is callable over the Apify API and through Apify's MCP server, so an agent can run it and read the dataset back as a tool call.

### 📝 Changelog

#### 2026-11-14

- Verified live high-volume benchmark (2026-11-14): extracted **650** structured records in **3.2s** on the production build.
- Hardened internal proxy stall fallback and pay-per-event dataset instance budget protection.

#### 2026-11-11

- Added reliable terminal run status telemetry and structured Apify AI / MCP Server (`mcp.apify.com`) tool configuration.
- Added direct Issues & Reviews support links and refreshed live maintenance verification.

#### 2026-11-01

- Monthly health check (2026-11-01): a live run on the current build completed successfully and returned data. Input options, output fields and pricing are unchanged.
- README refreshed: 1 link to renamed Actors updated, 2 links to retired Actors removed; independence disclaimer added; documented 1 additional input field; documented 11 additional output fields.

#### 2026-10-15

- A run that reaches its maximum cost per run now stops cleanly with its results saved and a status message, instead of ending as aborted.
- A proxy group your account cannot use no longer stops the run at start-up; it falls back to the default Apify Proxy.
- Runs with a short timeout (API and AI-agent calls) now finish inside it with what they collected, instead of being cut off.
- Memory is managed within the run's own limit, which removes a rare out-of-memory crash on large pages.
- The default used when the field is left out for `maxResults` is now 10,000 (was 1,000).

#### 2026-09-23

- Fleet-wide quality audit. Verified end to end against live data and re-checked the input schema, the output columns and the run configuration.
- Run reliability reviewed: 100.0% of public runs succeeded in the last 30 days.
- Input schema, output schema and pricing configuration reviewed.

#### 2026-09-01

- Fleet-wide health check. Verified against this Actor's real run history: 30-day success rate, output row counts, per-field fill rates, and peak memory against the configured memory limit.
- Reviewed for the failure patterns that have cost this fleet runs — unguarded proxy setup, retry loops that can outlast the run's own time budget, and full-page HTML parsing that can exhaust a small container.
- No change to input, output fields or scraping logic.

#### 2026-08-11

- Maintenance release: refreshed the build and dependencies.
- Re-verified live execution, non-empty structured output and dataset field/type integrity.
- Reviewed reliability (retries, pagination) and output quality as part of a full-fleet QA pass.

#### 2026-08-01

- Completed the August 2026 full health check: verified empty/programmatic default, Console UI default, and two source-informed alternative inputs on Apify.
- Confirmed successful live execution, non-empty structured output, dataset-field/type integrity, and logical sample quality within the 5-minute quality window.
- Declared 36 dataset fields from typed live cloud samples so the output contract is no longer an empty placeholder.
- Flattened Lever's native grouped response before normalization, preventing null-field rows when group is enabled; all-site/all-detail transport failures now fail explicitly instead of succeeding empty.
- Replaced migrated or empty Netflix/Plaid/Mixpanel examples with live official Lever boards (Lyra Health and Highspot) and clarified the difference between an EU-instance board and a stale handle.
- Declared 36 nullable dataset fields from typed live cloud samples so the output contract is no longer an empty placeholder or brittle to sparse modes.

#### 2026-08-01 — Health-check remediation

- August 2026 monthly health-check remediation is in progress; this build contains fixes verified from empty/default, Console-default, targeted live probes, or field-level semantic review.
- Declared 36 dataset fields from typed live cloud samples so the output contract is no longer an empty placeholder.
- Flattened Lever's native grouped response before normalization, preventing null-field rows when group is enabled; all-site/all-detail transport failures now fail explicitly instead of succeeding empty.
- Replaced migrated or empty Netflix/Plaid/Mixpanel examples with live official Lever boards (Lyra Health and Highspot) and clarified the difference between an EU-instance board and a stale handle.
- The final four-input matrix verdict will be appended after post-build cloud revalidation.

#### 2026-07-06

- ✨ README overhaul: richer output sample, ready-to-run example scenarios, cross-promo links to related logiover scrapers, and clearer quick-start.

#### 2026-07-01

- Maintenance pass: re-verified end-to-end on live data and confirmed successful runs within the 5-minute quality window on the default input.
- Sharpened Store metadata (SEO title & description) and expanded the FAQ with high-intent, long-tail questions for easier discovery in Google and Apify Store search.
- Added ready-to-run example tasks that cover common real-world use cases.

#### 2026-06-15

- Reliability pass: re-verified end-to-end on live data with real-world inputs. Routine maintenance build.

#### 2026-06-07

- Docs: added coverage for using this as an unofficial Lever.co API, exporting Lever job postings to CSV/JSON, and scraping Lever jobs without an API key or login.

***

\*Maintained: last verified 2026-11-14 — checked end-to-end against live run history (reliability, output fields and types, and time/memory budgets).

# Changelog

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

# Actor input Schema

## `mode` (type: `string`):

What to fetch: a list of jobs from one or more Lever sites, or a deep detail object for specific posting IDs.

## `sites` (type: `array`):

One or more Lever site names — the slug in https://jobs.lever.co/{SITE}. For 'jobDetail' mode only the first site is used. Case-sensitive. Examples: spotify, palantir, veeva, gopuff, matchgroup, leverdemo. Leave empty to scrape a built-in set of large, well-known Lever career pages so you get real jobs immediately.

## `instance` (type: `string`):

Lever runs two regional instances. Most companies are on 'global' (api.lever.co). EU customers (frequent for European-only employers) are on 'eu' (api.eu.lever.co). If you get 404s on 'global', try 'eu'.

## `jobIds` (type: `array`):

List of posting UUIDs to fetch. Required when mode = jobDetail. Example: 5ac21346-8e0c-4494-8e7a-3eb92ff77902

## `team` (type: `array`):

Lever-native filter. Postings are filtered server-side. Case-sensitive — must match exactly (e.g. 'Engineering' not 'engineering'). Multiple values are OR'ed.

## `department` (type: `array`):

Lever-native filter. Case-sensitive. Multiple values are OR'ed.

## `location` (type: `array`):

Lever-native filter. Case-sensitive. Multiple values are OR'ed. Example: 'San Francisco' or 'Remote - US'.

## `commitment` (type: `array`):

Lever-native filter. Case-sensitive. Examples: 'Full Time', 'Part Time', 'Internship', 'Contract'. Multiple values are OR'ed.

## `level` (type: `array`):

Lever-native filter. Case-sensitive. Values are customer-defined (e.g. 'Senior', 'Junior', 'Director').

## `limit` (type: `integer`):

Forwarded as Lever's ?limit= parameter. Caps the number of postings the server returns per board. Leave at 0 for no cap.

## `skip` (type: `integer`):

Forwarded as Lever's ?skip= parameter. Use for pagination: skip N postings from the start before returning results.

## `group` (type: `string`):

Lever's ?group= parameter. When set, the API returns postings grouped by the chosen category. Leave as 'none' for ungrouped output.

## `filterTitleKeywords` (type: `array`):

Client-side: keep only postings whose title contains any of these strings (case-insensitive). Useful for job-role targeting (e.g. 'engineer', 'designer'). Multiple keywords are OR'ed.

## `filterWorkplaceTypes` (type: `array`):

Client-side: keep only postings with these workplace types. Lever's native enum values.

## `filterCountries` (type: `array`):

Client-side: keep only postings whose 'country' field matches one of these ISO 3166-1 alpha-2 codes (e.g. 'US', 'GB', 'DE'). Case-insensitive.

## `filterSalaryMin` (type: `integer`):

Client-side: keep only postings whose salaryRange.min is >= this number. Postings WITHOUT a disclosed salary are dropped when this filter is active. Set to 0 to disable.

## `maxResultsPerSite` (type: `integer`):

Hard cap applied after all filters, per site. 0 = unlimited. Useful for testing or controlling cost.

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

Global cap across all sites. Keeps the default empty-input run fast and cheap. Set 0 for no overall limit (pull every posting on every site).

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

How many sites to fetch in parallel. 5 is a safe default. Higher = faster, but Lever may rate-limit you on huge batches.

## Actor input object example

```json
{
  "mode": "jobs",
  "sites": [
    "spotify",
    "palantir",
    "veeva",
    "matchgroup",
    "leverdemo"
  ],
  "instance": "global",
  "jobIds": [],
  "team": [],
  "department": [],
  "location": [],
  "commitment": [],
  "level": [],
  "limit": 0,
  "skip": 0,
  "group": "none",
  "filterTitleKeywords": [],
  "filterWorkplaceTypes": [],
  "filterCountries": [],
  "filterSalaryMin": 0,
  "maxResultsPerSite": 0,
  "maxResults": 500,
  "concurrency": 5
}
```

# Actor output Schema

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

All records extracted by this run. Open the Dataset tab to browse, filter, and export as CSV, JSON, or Excel.

# 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 = {
    "sites": [
        "spotify",
        "palantir",
        "veeva",
        "matchgroup",
        "leverdemo"
    ],
    "maxResults": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/lever-postings-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 = {
    "sites": [
        "spotify",
        "palantir",
        "veeva",
        "matchgroup",
        "leverdemo",
    ],
    "maxResults": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/lever-postings-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 '{
  "sites": [
    "spotify",
    "palantir",
    "veeva",
    "matchgroup",
    "leverdemo"
  ],
  "maxResults": 500
}' |
apify call logiover/lever-postings-scraper --silent --output-dataset

```

## MCP server setup

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