Lever Jobs Scraper avatar

Lever Jobs Scraper

Pricing

from $0.84 / 1,000 results

Go to Apify Store
Lever Jobs Scraper

Lever Jobs Scraper

Jobs from any company's Lever job board (jobs.lever.co, jobs.eu.lever.co) via the public Postings API: title, department, team, location, remote/hybrid, commitment, salary range, posted date, apply URL and the full description. Filter by keyword, department, location, remote.

Pricing

from $0.84 / 1,000 results

Rating

0.0

(0)

Developer

Ibnu Adzim

Ibnu Adzim

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Every open job on any company's Lever job board — Zoox, Binance, Palantir and the thousands of others hosted at jobs.lever.co/<site> (or jobs.eu.lever.co/<site>) — through Lever's public Postings API: title, department, team, commitment, location(s) and country, remote / hybrid / on-site, salary range with currency and interval where the company publishes it, posted date, apply URL, and the full description assembled from Lever's four description pieces, as text and HTML.

HTTP only, no login, no key, no browser. Boards are walked in pages of 100 postings; Lever's Crawl-delay: 1 is honoured.

What it is for

  • Company watchlists — a list of sites on a schedule, diff by jobId.
  • Multi-company search — many sites, one keyword, one dataset.
  • Salary datasets — salaryRange is structured where present (Zoox 225 of 239 postings; Binance none).
  • EU-hosted boards — a jobs.eu.lever.co URL is fetched from the EU API host automatically.

Input

fieldwhat it does
sitesSite slugs (zoox) or URLs (jobs.lever.co/zoox, jobs.eu.lever.co/<site>, a job URL under the site). Case-sensitive on Lever's side; sent as given.
searchTerms, departments, locations, remoteOnlyLocal filters on the walked board (see #3 below for why they are local).
includeDescriptionOn by default; same requests, rows ~10× bigger.
maxItems, maxConcurrency, minRequestInterval, proxyConfigurationLimits. minRequestInterval never goes below 1 s.

Each site gets a BOARD_SUMMARY with the pages walked, the total (known only when the board was walked to its end), how many rows carry a salary, what the filters dropped, and the board's own department and location vocabularies.

Four things about this API worth knowing before you trust a run

1. Offset pages with no total, and bad values fail soft

skip/limit work and the order is stable — but nothing says how many postings exist; a page shorter than limit is the end. limit=abc answers 200 [] (indistinguishable from an empty board), limit=-5 answers N−5 postings, skip=-1 answers []. The Actor only ever sends non-negative integers and stops at the first short page.

2. An empty board and a missing board differ only by status

kraken, mistral, wealthsimple → 200 [] (a real site with nothing public). plaid, figma → 404 {"ok":false,"error":"Document not found"}. And LEVERDEMO is a 404 while leverdemo has 11 postings: slugs are case-sensitive. 404 → site_not_found; [] → summary with totalJobsOnBoard: 0 and stoppedReason: empty_board.

3. The server-side filters are exact matches with inconsistent case rules

?department=software, Software and SOFTWARE all return 90 Zoox jobs, but ?department=Soft returns 0; ?location=Foster City, CA returns 204 while ?location=foster city, ca returns 0. A typo or a case slip is a silent empty run. The Actor never sends them; departments / locations are substring, case-insensitive filters on the walked board.

4. The description is four pieces, not one

description is only the opening paragraph; the titled sections (Requirements, Benefits, "In this role, you will:") are lists[] of HTML <li> strings; additional is the closing paragraph; salaryDescription another. The Actor assembles all of them into description (text) and descriptionHtml, and keeps the raw pieces in sections. Section titles carry trailing whitespace on real boards; stripped.

Other things measured

  • createdAt is an integer of epoch milliseconds; kept raw as createdAtMs and converted to ISO UTC in createdAt.
  • workplaceType is lowercase remote / hybrid / onsite.
  • allLocations is the full list where a posting is open in several offices (Binance: 243 of 298 postings).
  • Postings are ~10 KB each; a 100-posting page is ~1 MB. No throttling or anti-bot layer seen.

Output

  • JOB — jobId, title, url, applyUrl, department, team, commitment, workplaceType, location, allLocations, country, createdAt, createdAtMs, salaryMin, salaryMax, salaryCurrency, salaryInterval, salaryDescription, description, descriptionHtml, sections, site, region, resultPosition.
  • BOARD_SUMMARY — site, region, boardUrl, totalJobsOnBoard (null when the walk stopped early), jobsReturned, pagesWalked, rowsWithSalary, stoppedReason (exhausted, max_items, empty_board, max_pages), filteredOut, departmentsOnBoard, locationsOnBoard.
  • ERROR — invalid_input, site_not_found, payload_shape_changed, fetch_failed, with detail.

Known limits

  • No total exists on the API; totalJobsOnBoard is the count walked and is null when maxItems stopped the walk.
  • The order Lever returns is not by date; sort on createdAt yourself.
  • Salary is what the company chose to publish (rowsWithSalary says how many).