Lever Jobs API: how to list every posting from any Lever job board (jobs.lever.co) as JSON
Lever publishes a public postings API for every
company that hosts its jobs on jobs.lever.co. No key, no
login. This repository documents the endpoint, the response fields, the
skip/limit pagination and ships a
dependency-free Python example.
The endpoint
GET https://api.lever.co/v0/postings/{site}?mode=json
GET https://api.lever.co/v0/postings/{site}?mode=json&limit=100&skip=100
GET https://api.lever.co/v0/postings/{site}/{posting_id}?mode=json
GET https://api.lever.co/v0/postings/{site}?mode=json&team=Engineering&location=Remote&commitment=Full-time
site is the slug in the board URL:
https://jobs.lever.co/spotify → spotify.
Companies on the EU data center use
https://jobs.eu.lever.co/{site} and
https://api.eu.lever.co/v0/postings/{site}.
What you get back
A JSON array (not an object). Each posting:
| Field | Example | Notes |
|---|---|---|
id |
a1b2c3d4-... |
UUID, stable; diff between runs |
text |
Senior Backend Engineer |
the title |
categories.team |
Engineering |
|
categories.department |
R&D |
optional |
categories.location |
Stockholm |
|
categories.allLocations[] |
["Stockholm","Remote"] |
newer field, multi-location |
categories.commitment |
Full-time |
|
workplaceType |
remote / hybrid / onsite |
present on most boards since 2023 |
hostedUrl |
https://jobs.lever.co/spotify/a1b2c3d4-... |
job page |
applyUrl |
.../apply |
|
createdAt |
1761040320000 |
Unix epoch milliseconds |
descriptionPlain, description |
text / HTML | full description |
lists[] |
[{"text":"Requirements","content":"<li>..."}] |
bullet sections |
salaryRange |
{"min":..,"max":..,"currency":"USD","interval":"per-year-salary"} |
only where the company publishes it |
Pagination and limits
Default page size is 100 (limit max 100); page with
skip. Lever also returns the entire board with a large
limit on most sites, but relying on skip is
the documented way. There is no published rate limit; keep it to a few
requests per second and cache.
Python example (stdlib only)
import json, urllib.request
def lever_jobs(site):
skip = 0
while True:
url = f"https://api.lever.co/v0/postings/{site}?mode=json&limit=100&skip={skip}"
req = urllib.request.Request(url, headers={"User-Agent": "your-app/1.0 (contact@example.com)"})
with urllib.request.urlopen(req, timeout=30) as r:
page = json.load(r)
if not page:
return
for p in page:
c = p.get("categories") or {}
yield {"id": p["id"], "title": p["text"], "team": c.get("team"), "location": c.get("location"),
"commitment": c.get("commitment"), "workplace": p.get("workplaceType"),
"url": p["hostedUrl"], "posted_at": p.get("createdAt")}
skip += len(page)
if __name__ == "__main__":
rows = list(lever_jobs("spotify")); print(len(rows), "jobs"); print(rows[0])Finding Lever boards
Search site:jobs.lever.co or
site:jobs.eu.lever.co. A careers page that links to
jobs.lever.co/<slug>/<uuid> tells you the
slug.
Common questions
Why do I get an empty array? The slug is wrong, the company moved ATS, or the board is on the EU host.
Is createdAt the posting date? It is
the creation time of the posting record in milliseconds; for most
companies that matches the publish date closely.
Hosted version, pay per result
If you would rather not run and maintain this yourself, the same logic runs as a pay-per-result Apify Actor by CleanFeeds: https://apify.com/cleanfeedsapi/lever-jobs-api ($1.50 per 1,000 rows, no subscription, JSON/CSV/Excel export, API, scheduling, n8n/Make/Zapier and MCP integrations). A multi-ATS variant that mixes Greenhouse, Lever, Ashby, Workday, SmartRecruiters and Recruitee boards in one run: https://apify.com/cleanfeedsapi/ats-jobs-feed
Free sample data: a daily snapshot of about 10,000 open roles at 26 tech companies from these endpoints, CC BY 4.0: https://huggingface.co/datasets/cleanfeeds/tech-jobs-daily
More feeds: https://cleanfeeds.dev
Legal note
These are public, unauthenticated endpoints that the career pages themselves load. Job postings are employer announcements and belong to the employers. Be polite: identify your client with a User-Agent, cache results, and do not hammer the endpoints. Nothing here is affiliated with or endorsed by Lever.