Lever Jobs Scraper & API avatar

Lever Jobs Scraper & API

Pricing

Pay per usage

Go to Apify Store
Lever Jobs Scraper & API

Lever Jobs Scraper & API

Free Lever jobs scraper: pay only for platform usage. Extract every open job from one or many Lever boards (US and EU) with titles, locations, teams, salary ranges, remote/hybrid/on-site type, descriptions, and publish dates. Filter by team, location, workplace type, keywords, or date.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Milad Amirzadeh

Milad Amirzadeh

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

11 hours ago

Last modified

Share

Collect every open job from one or many Lever job boards in a single run: titles, locations, teams, departments, employment type, salary ranges, remote/hybrid/on-site type, full descriptions, and publish dates. Use the results for job-board feeds, recruiting research, salary benchmarking, hiring-trend tracking, and scheduled employer snapshots, with no login or API key.

The Actor is free to use: you pay only for Apify platform usage, which is typically a fraction of a cent per run.

Lever is the applicant tracking system behind the careers pages of companies such as Spotify, Palantir, Zoox, Shield AI, Veeva, and thousands more. This Actor reads Lever's public Postings API directly over HTTP. It runs without a browser or proxy and finishes most companies in a few seconds.

What you get

  • All open jobs for one or many companies per run, from a slug (spotify) or any board URL
  • Specific postings by URL (job_details mode)
  • US and EU boards detected automatically (jobs.lever.co and jobs.eu.lever.co)
  • Salary ranges with currency and period (year, month, hour), from Lever's salary fields and from the job description when the employer only writes the pay there (Spotify, Palantir, Veeva, and many others do). This roughly triples salary coverage.
  • Workplace type (Remote, Hybrid, On-site) and country code, as set by the employer
  • Team, department, commitment (employment type), and every listed location
  • Company name, even though Lever's API does not provide one
  • Full description as HTML, as clean plain text, and as structured bullet sections ("What you'll do", "Requirements")
  • Filters for workplace type, department or team, location or country, commitment, keywords, publish date, and salary availability
  • A per-company run summary showing open, matched, and saved counts, the detected region, and any slugs that were not found

Quick start

All jobs from several companies

{
"mode": "company_jobs",
"companySlugs": ["spotify", "zoox", "https://jobs.eu.lever.co/seb"],
"maxJobsPerCompany": 9999
}

Filtered: recent remote or hybrid engineering roles mentioning Python

{
"mode": "company_jobs",
"companySlugs": ["spotify", "zoox", "shieldai", "palantir"],
"workplaceTypes": ["remote", "hybrid"],
"filterDepartment": "Engineering",
"jobKeywords": ["python", "machine learning"],
"postedAfter": "30 days",
"maxJobsPerCompany": 200
}

Specific postings

{
"mode": "job_details",
"jobUrls": [
"https://jobs.lever.co/spotify/2193db3f-77c5-43b8-b030-8f92c9882bf1",
"https://jobs.eu.lever.co/seb/205c25b9-a4dc-41e2-8a23-7f3b2a887d21"
]
}

How to find a company's slug

Open the company's Lever board or any of its job postings. The slug is the path segment right after lever.co/:

URLSlug
https://jobs.lever.co/spotifyspotify
https://jobs.lever.co/zoox/2193db3f-...zoox
https://jobs.eu.lever.co/sebseb

You can paste any of these URLs directly. The Actor extracts the slug and finds the right region for you.

Input reference

FieldTypeDefaultBehavior
modestringcompany_jobscompany_jobs lists all open jobs for each company. job_details fetches specific postings.
companySlugsarray["spotify"]Board slugs or URLs. Used in company_jobs mode. Duplicates are removed.
jobUrlsarray[]Lever posting URLs or slug/postingId. Used in job_details mode.
includeContentbooleantrueSave the description as HTML (content), plain text (descriptionText), and bullet sections.
workplaceTypesarray[]Any of remote, hybrid, onsite, using the type the employer set in Lever.
filterDepartmentstringemptyCase-insensitive partial match against the department or team.
filterLocationstringemptyCase-insensitive partial match against every listed location, such as London. A two-letter country code (DE, US, UK) matches the country only: DE does not match Denver, and CA means Canada. Remote also matches jobs whose workplace type is remote. A US state name such as California also finds its code ("San Francisco, CA"), and state codes that are not country codes (NY, TX) match the state.
filterCommitmentstringemptyCase-insensitive partial match against the commitment, such as Full-time, Intern, or Contract.
jobKeywordsarray[]Up to 20 keywords or phrases. A job matches when any of them appears as a whole word in its title or description.
postedAfterstringemptyYYYY-MM-DD or relative (7 days). Inclusive, compared as UTC dates.
onlyWithSalarybooleanfalseKeep only jobs with a salary, from Lever's salary fields or the description.
maxJobsPerCompanyinteger500Maximum jobs saved per company after filtering, newest first. Use 9999 for all.
proxyConfigurationobjectoffOptional. The API is public, so a proxy is not required.

All filters that you set must match (AND). Filters apply only in company_jobs mode.

Keyword matching uses whole words, so ML matches "ML Engineer" but not "HTML". Add every form you want to catch, such as engineer and engineering.

Output

Each saved job looks like this:

{
"jobId": "e25fdd3f-628f-4141-b9fe-7298f3de55af",
"title": "Advisory Manager (Client Associate) in SOEs & Infrastructure team | SEB, Vilnius",
"companyName": "SEB",
"companySlug": "seb",
"location": "Vilnius",
"allLocations": ["Vilnius"],
"country": "LT",
"workplaceType": "Hybrid",
"department": "Baltic",
"team": "Corporate Banking",
"commitment": "Corporate Banking",
"salaryMin": 3750,
"salaryMax": 5650,
"salaryCurrency": "EUR",
"salaryInterval": "month",
"salaryDescription": "(before tax deduction).\nThe final offer will depend on the experience and competencies of the selected candidate...",
"salarySource": "lever",
"url": "https://jobs.eu.lever.co/seb/e25fdd3f-628f-4141-b9fe-7298f3de55af",
"applyUrl": "https://jobs.eu.lever.co/seb/e25fdd3f-628f-4141-b9fe-7298f3de55af/apply",
"content": "<div><p><strong>Do you want your daily work to have a meaningful impact on Lithuania?</strong></p>...",
"descriptionText": "Do you want your daily work to have a meaningful impact on Lithuania?\nAt SEB, you do not just build a career...",
"sections": [
{ "title": "What you will do", "items": ["Develop and strengthen relationships with Lithuania's largest public sector institutions...", "..."] }
],
"publishedAt": "2026-09-25T11:44:23+00:00",
"region": "eu",
"scrapedAt": "2026-09-26T20:57:42+00:00"
}
FieldMeaning
jobIdLever posting ID (UUID).
titleJob title.
companyName / companySlugCompany name read from the hosted posting page, and the board slug. The name falls back to the slug if the page is unavailable.
location / allLocationsPrimary location, and every location the posting lists.
countryTwo-letter country code set by the employer.
workplaceTypeRemote, Hybrid, On-site, or null when the employer left it unspecified.
department / team / commitmentLever's categories. Commitment is the employment type, named freely by each employer.
salaryMin / salaryMax / salaryCurrency / salaryIntervalSalary range and its period (year, month, week, day, hour, one-time). A single figure has equal min and max. null when no salary is stated.
salaryDescriptionThe employer's compensation note, or the sentence the salary was read from.
salarySourcelever when the employer filled in Lever's salary fields, description when the salary was read from the job text, null when neither has one.
url / applyUrlHosted job page and application page.
content / descriptionTextFull description (intro, bullet lists, and closing text) as HTML and as plain text. null when includeContent is off.
sectionsThe titled bullet lists as {title, items}, useful for extracting requirements or responsibilities.
publishedAtWhen the posting was created (UTC).
regionLever data region, us or eu.
scrapedAtWhen the job was collected (UTC).

Results appear in the default dataset. Use the Job overview view for compact metadata, salaries, and links, or the Job descriptions view for text.

Run summary

Each run also writes an OUTPUT record to the default key-value store. It shows every target's status (ok, not_found, or error), its region, and its open, matched, and saved job counts, so you can spot mistyped slugs without reading the log. When no target succeeds, the run is marked as failed.

API and exports

Run the Actor from your application with the standard Apify API:

curl -X POST \
"https://api.apify.com/v2/acts/miladamirzadeh~lever-jobs-scraper/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"companySlugs": ["spotify", "zoox"],
"workplaceTypes": ["remote"],
"maxJobsPerCompany": 50
}'

You can also use the generated Python, JavaScript, CLI, OpenAPI, and MCP examples in the Actor's API tab. Datasets export to JSON, CSV, Excel, XML, and HTML.

Recurring workflows

Save a tested input as an Apify Task and schedule it daily or weekly. For daily runs, set postedAfter to 1 day so each run saves only postings published since the day before.

Typical uses:

  • Job-board and aggregator ingestion
  • Salary benchmarking across companies that publish pay ranges
  • Tracking hiring volume by team, location, or workplace type
  • Alerts for new roles at target companies, through Apify integrations such as Slack, Google Sheets, Make, or Zapier

Each run produces an independent dataset. The Actor does not keep history between runs.

Practical limitations

  • You need each company's Lever slug. Lever has no public directory of all boards.
  • Only published postings are available. Internal and unlisted postings are not exposed by the public API.
  • Lever records when a posting was created, not when it was last edited, so there is no "updated after" filter.
  • Salaries read from the description (salarySource: "description") are the first salary the text states. When a posting lists several ranges (per city or level), the first one is saved and salaryDescription shows its context. Amounts labeled OTE (on-target earnings), bonuses, and perks are skipped.
  • A bare $ is read as USD unless the text names another currency code, such as CAD. When the period isn't stated, it's inferred from the amount (for example, $18 is hourly and $120,000 yearly).
  • Commitment values are free text chosen by each employer, so the same employment type can be spelled differently across companies.
  • Filters apply only in company_jobs mode.
  • Closed postings return not_found in job_details mode.

Pricing

The Actor is free. There is no per-run or per-result fee; you pay only for the Apify platform usage (compute units) of your runs, which the Apify free plan's monthly credit covers for most users.

Runs are cheap because the Actor makes plain HTTP requests with no browser or proxy. It runs at 512 MB by default and used under 180 MB in testing. Saving every job from Veeva and Palantir (about 1,200 jobs) took 23 seconds, which is well under 0.01 compute units.

Troubleshooting and support

If a run returns no jobs:

  1. Open the OUTPUT record. A not_found status means the slug is wrong or the company does not use Lever.
  2. Open the company's job posting in a browser and copy the slug from the URL.
  3. Remove the filters temporarily to rule out an overly narrow match.

For support, open an Actor issue with your input (without tokens), the run link, and what you expected to see.