Lever & Greenhouse Jobs Lookup & New-Job Alerts
Pricing
from $1.50 / 1,000 job returneds
Lever & Greenhouse Jobs Lookup & New-Job Alerts
Get open jobs from any company's Lever or Greenhouse job board: give names, careers URLs or board links and the Actor finds the board. Filter by date, location, remote, department, keyword and salary. New-job alerts. Official public Lever and Greenhouse APIs, clean JSON.
Pricing
from $1.50 / 1,000 job returneds
Rating
0.0
(0)
Developer
Stego
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
Lever & Greenhouse Jobs Lookup: open jobs for any company on Lever or Greenhouse, as clean JSON
Give it company names, careers page URLs or Lever / Greenhouse board links. It finds each company's Lever or Greenhouse job board and returns its open jobs as clean, flat JSON: title, company, location, remote / hybrid / on-site, department, team, commitment, posted date, salary (where the company publishes it) and a direct job link. Filter by posted date, location, remote, department, keyword and salary, or run it on a schedule to get only new jobs since your last run.
It reads only two official public, read-only APIs:
- Lever's Postings API (the same JSON feed each company's Lever careers page uses), whose docs say published postings "may be scraped by third parties";
- Greenhouse's Job Board API (
boards-api.greenhouse.io), whose docs say "Job Board data is publicly available, so authentication is not required for any GET endpoints".
No login, no API key, no browser and no crawling: for Lever, one API call per board (plus a check that the list is complete) and one read of each board's Lever page for its <title> (the company name); for Greenhouse, one API call per board (the API returns the full list with a total). The Actor never loads Greenhouse web pages, only that API. If you give a careers page URL, that one page is read once, if its robots.txt allows. A typical run takes seconds.
Lever and Greenhouse only. Companies on other applicant tracking systems (Ashby, Workday, SmartRecruiters…) are not read; their links and tokens get status unsupportedAts and cost nothing beyond the run start.
What it does
- Finds the board. Each entry can be:
- a company name (
Zoox,Palantir Technologies), which is matched against likely Greenhouse and Lever board names (Lever global and EU). A guessed board is used only when the board's own name matches what you typed (the Greenhouse board name or the Lever page title, ignoring Inc/Ltd/GmbH/Technologies…). If the same name exists on both, the matching one is used and the entry'swarningnames the other, so you can enter that token instead. Otherwise it's skipped with statusuncertainMatchand a suggestion, and nothing is charged. For example,Palantiris used because the boardlever:palantiris titled "Palantir Technologies", but a name whose likeliest board has a different title (say,Acme Roboticsguessing a board titled "Totally Different Staffing") is skipped asuncertainMatch. SetallowUncertainMatchesto include such boards; - a careers page URL (
https://www.example.com/careers/). The Actor reads that one page once (if robots.txt allows) and uses every Lever or Greenhouse board it links to (up to 5). Otherwise it guesses from the domain, with the same name check. A careers page that only links to another ATS getsunsupportedAts; - a board URL: Lever (
https://jobs.lever.co/spotify,jobs.eu.lever.co/...) or Greenhouse (https://job-boards.greenhouse.io/<token>,boards.greenhouse.io/<token>, an embed link with?for=<token>, or aboards-api.greenhouse.io/v1/boards/<token>link). Greenhouse URLs are only parsed for the board token; the Actor then reads that board through the Job Board API; - an explicit token:
lever:spotify,lever-eu:<site>for Lever's EU instance, orgreenhouse:<token>. This is the fastest and most reliable option.
- a company name (
- Returns every open job, never a silently cut list. For Lever, the Actor reads the full list and then asks for the page after the end, to prove there's nothing more. For Greenhouse, it compares the list with the total the API reports and asks once more if they differ. If a list can't be confirmed complete, that company is flagged
complete: falsein the run's OUTPUT and the status message says so. - Whole-word keyword matching.
AImatches "AI Engineer" but not "Maintain";artdoesn't match "Department". Add*at the end for a prefix match (engineer*). A*anywhere else (*engineer,eng*neer) is rejected with a clear message rather than silently matching nothing. - Each board once. Entries that resolve to the same board (e.g.
Spotify,https://jobs.lever.co/spotifyandlever:spotify, orhttps://boards.greenhouse.io/acmeandgreenhouse:acme) are read and charged once. Every entry you typed still appears in OUTPUT; the later ones get statusduplicate, withsameAsnaming the entry that was actually read and the sameboardName. - Fair sharing of
maxResults. Each company first gets up to an equal share. What's left at the end goes to the companies that still have matches, smallest first, so small companies get all their jobs and big ones split the rest evenly. Example:maxResults1000 over companies with 46, 80, 139, 195 and two with 2,000+ matches gives 46 / 80 / 139 / 195 / 270 / 270. Companies that were cut off are listed in the status message and in OUTPUT (notReturned), and the message says whethermaxResults,maxResultsPerCompanyor your max total charge was the limit. - Agent-friendly. It takes one call with a list of companies and gives back flat JSON with one date format (
YYYY-MM-DDTHH:MM:SSZ, UTC). A per-company summary in OUTPUT shows found, not found, failed and skipped companies, so an agent knows exactly what happened. - New-job alerts.
onlyNewremembers what it has returned (in a named key-value store), so a daily schedule returns only new postings. The first run takes a baseline and returns nothing. A company you add later gets its own baseline, so you're never billed for a backlog you didn't ask for. Each batch of up to 100 jobs is saved to the alert memory before it is pushed and charged, so a crashed, killed or timed-out run never re-delivers or re-charges a job. The trade-off: if the run dies in the middle of pushing a batch, that batch may be lost. Those jobs count as seen, so they aren't delivered (or charged) on the next run either. - Flat memory. Boards are streamed: at most 2 full job lists are in memory at once, and each company's results are pushed and freed before the next one is read. In a local test with big Lever boards (900 postings each, about 7 KB of description per posting), 31 boards peaked at about 180–230 MB (up to 5,000 results with HTML descriptions) and 60 boards in alert mode at about 200 MB, under the 512 MB default. A local test with 20 synthetic Greenhouse boards of 3,000 short postings each plus 5 Lever boards peaked at about 130 MB. Jobs held back for the end-of-run fair share are kept in a compressed temporary file, not in memory, so a large
maxResultsis filled in full: 31 big Lever boards plus 30 small ones withmaxResults25,000 and HTML descriptions returned all 25,000 jobs and peaked at about 185 MB.
Who it is for
- Recruiters and sourcers: watch target companies for new roles in a department or city.
- Sales and BD teams: hiring is a buying signal. Get a daily feed of companies opening roles like "Data Engineer" or "Head of Security".
- Job-board and newsletter builders: pull clean jobs from many employers with salary and remote flags.
- AI agents: answer "Is company X hiring for Y?" or "What remote engineering roles does Z have?" in a single call.
Input
Only companies is required. Everything else is optional.
| Field | Description |
|---|---|
companies | Up to 500 names, careers URLs, Lever / Greenhouse board URLs or lever: / lever-eu: / greenhouse: tokens. |
allowUncertainMatches | Default off. Include guessed boards whose own name doesn't match what you typed. |
keywords / keywordMode / searchIn | Whole-word keywords; any (default) or all; title (default) or titleAndDescription. Each keyword must contain a letter or digit. Note that some companies put the same boilerplate in every description, so description search can match every job. |
excludeKeywords | Drop jobs whose title or description contains any of these, e.g. Senior, Intern. |
locations / excludeLocations | Whole-word match on the job's location and all of its listed locations, e.g. London, Germany, Remote. |
remote | any (default), only or exclude. |
departments | Whole-word match on the department (Greenhouse departments, or the Lever department and team). |
postedWithinDays | Only jobs first published in the last N days (0 = all open jobs). |
onlyWithSalary | Only jobs with a published pay range. |
minSalary + salaryCurrency | Keep jobs whose range reaches at least this yearly amount in this ISO currency. Hourly and monthly ranges are annualized. |
maxResults | Max jobs per run, across all companies (default 100, newest first per company). |
maxResultsPerCompany | Optional per-company cap (0 = none). |
includeDescription / descriptionFormat / descriptionMaxLength | Full description, off by default. text or html, with optional truncation. |
includeContactDetails | Off by default. When off, emails and phone numbers inside descriptions are replaced with [email removed] / [phone removed]. |
onlyNew / stateKey / baselineOnFirstRun / stateStoreName | Alert mode (see below). Use a stateKey per saved search. Without one, the key is derived from the filters and the list of company entries you typed (normalised, order and repeats ignored), so a company that is briefly unreachable doesn't switch the run to a new memory. |
Example inputs
Is Spotify hiring remote engineers?
{ "companies": ["lever:spotify"], "keywords": ["engineer*"], "remote": "only" }
New jobs in the last 7 days at several companies, with salary:
{ "companies": ["Zoox", "https://jobs.lever.co/palantir", "greenhouse:<token>"],"postedWithinDays": 7, "onlyWithSalary": true, "maxResults": 500 }
Daily alert for business roles in London (schedule it daily):
{ "companies": ["Palantir", "lever:spotify"], "departments": ["Business"], "locations": ["London"],"onlyNew": true, "stateKey": "london-business" }
Output
One item per job (a Lever job shown; Greenhouse jobs have the same fields):
{"jobId": "f02fb195-ba10-40bd-a926-0318a34a7fae","title": "Staff Product Designer - Platform Design","company": "Spotify","ats": "lever","boardToken": "spotify","location": "London","allLocations": ["London", "Stockholm"],"remote": true,"workplaceType": "remote","department": "Design and User Experience","team": "Platform","employmentType": "Permanent","postedAt": "2026-10-21T17:27:06Z","updatedAt": null,"url": "https://jobs.lever.co/spotify/f02fb195-ba10-40bd-a926-0318a34a7fae","applyUrl": "https://jobs.lever.co/spotify/f02fb195-ba10-40bd-a926-0318a34a7fae/apply","requisitionId": null,"language": null,"country": "GB","leverInstance": "global","salaryMin": null,"salaryMax": null,"salaryCurrency": null,"salaryInterval": null,"salaryText": null,"salaryNote": null,"salaryRanges": [],"description": null,"input": "lever:spotify","scrapedAt": "2026-10-21T21:52:29Z","matchConfidence": "high","boardName": "Spotify"}
Notes on fields:
atsisleverorgreenhouse.postedAtis Lever'screatedAtor Greenhouse'sfirst_published.updatedAtis Greenhouse'supdated_at(Lever doesn't publish one, so it'snull).requisitionIdandlanguagecome from Greenhouse (nullfor Lever).remoteandworkplaceType: Lever publishes a workplace type (remote, hybrid or onsite); Greenhouse doesn't. When a posting has none, a job counts as remote when its location, offices or title say "Remote", "anywhere" or "work from home" (hybrid likewise); otherwiseworkplaceTypeisnull(not stated).departmentandteamare Lever's department and team; for Greenhouse,departmentjoins the job's departments andteamisnull.employmentTypeis Lever's commitment (e.g. "Permanent", "Full-time"); Greenhouse doesn't publish one (null).leverInstanceisglobal(jobs.lever.co) oreu(jobs.eu.lever.co), andnullfor Greenhouse.countryis Lever's country code (nullfor Greenhouse).matchConfidenceishighfor board URLs, tokens and careers-page links, and for guesses whose board name matches. It'smediumonly withallowUncertainMatches.boardNameis the board's own display name (the Greenhouse board name or the Lever page title). "high" means the names match, not that it's certainly the company you meant (e.g. two companies called "Mercury"); use a board URL or token when it matters.salary*comes only from structured pay data: Lever's salary range (with its own period: year, month, week, day or hour) or Greenhouse's pay transparency ranges (in cents, converted to whole units). Greenhouse ranges carry no period, so they count as yearly unless the range title says hourly or monthly; an obviously mislabelled "yearly" range is fixed and explained insalaryNote(a maximum of 200 or less is treated as hourly, one under 1,000 as entered in thousands). When a job has several ranges (e.g. pay zones),salaryMin/salaryMaxspan the ranges that share the first range's currency and period, andsalaryRangeslists them all. Salaries that appear only in the description text aren't parsed, and many large employers publish no structured pay, soonlyWithSalary/minSalarydrop all their jobs.companyis Greenhouse'scompany_nameor the Lever page title (e.g. "Palantir Technologies"). If that can't be read, it's the name you typed, or the board token.
The Overview, Salary and Details dataset views give you ready-made tables. The run's OUTPUT record lists each company with its status (ok, notFound, unsupportedAts, uncertainMatch, duplicate, error, skipped), how it was detected (token, boardUrl, careersPage, nameGuess, domainGuess or cache), the board it read (boardRef, e.g. lever:spotify, lever-eu:xentral or greenhouse:<token>, and for Lever leverInstance: global or eu) and the counts of jobs listed, matched and returned. Copy boardRef into companies to skip the lookup next time.
Alerts (only new jobs)
- Set
onlyNew: trueand astateKey, then schedule the Actor daily. - The first run remembers today's matching jobs and returns nothing; you pay only the run start.
- Each later run returns only jobs that haven't been returned before. If
maxResultsor your max charge cuts a run short, the rest come on the next run. A job is never returned or charged twice, even if a run crashes. If a run dies in the middle of pushing a batch, though, that batch (up to 100 jobs) may never be delivered, because it was already marked as seen. - Changing the filters for a state key takes a fresh baseline. Jobs already returned stay remembered. Detected boards are cached in the alert memory, so later alert runs skip detection.
- The state store (default
ats-jobs-state) is shared by all runs and tasks in your account. Use a differentstateKeyper saved search.
Pricing
Pay per event: a small fee per run start plus a fee per job returned. Not-found companies, baseline runs and filtered-out jobs cost nothing beyond the run start. Set Max total charge on a run to cap spending. The run-start fee counts toward the cap, so the cap minus the start fee is what's left for jobs. The Actor stops at the cap, says so in the status message and, in alert mode, keeps the rest for the next run.
Data sources, terms and limits
- Lever Postings API (
api.lever.co,api.eu.lever.co). Lever's docs say: "all job postings in the published state are publicly viewable. These jobs may be scraped by third parties." The company name comes from the<title>of the company's Lever page (jobs.lever.co/<site>), read once per board. - Greenhouse Job Board API (
boards-api.greenhouse.io, GET only). Greenhouse's docs say: "Job Board data is publicly available, so authentication is not required for any GET endpoints." Its robots.txt disallows only/embed/, not the/v1/API. We found no Greenhouse terms that restrict this use (Greenhouse's own user agreement covers its My Greenhouse candidate product, and its subscription agreement covers its customers). That is our reading, not an endorsement by Greenhouse. The Actor contacts no other Greenhouse host: board and job page URLs are only parsed for their token, and redirects or robots.txt hops to any othergreenhouse.iohost are never followed. - Other ATS vendors are not supported. Ashby, Workday and other ATS links or tokens (e.g.
ashby:acme,https://jobs.ashbyhq.com/acme) are reported asunsupportedAts. The Actor never sends a request to Ashby hosts, not even a robots.txt check: a careers site that redirects there is reported asunsupportedAtswithout following the redirect. - The Actor is polite: at most 1 request per second to each Lever host (their robots.txt sets
Crawl-delay: 1) and to the Greenhouse Job Board API, and about 3 per second to a company's own careers site, with a clear User-Agent. It retries 429 and 5xx responses with backoff and honoursRetry-After(seconds or HTTP date) for up to 5 minutes. If a host asks for a longer wait, that host is not contacted again for the rest of the run, and its remaining companies are reported as errors. - Careers page URLs: the Actor fetches only the one page you gave (following up to 5 redirects), once, and only if each host's robots.txt allows it. robots.txt redirects are followed by hand (up to 5 hops), never to another ATS vendor or to Greenhouse. A robots.txt that returns a server error, can't be reached or is over 2 MB counts as "disallowed" (RFC 9309); the Actor then guesses from the domain instead.
- Job postings are employer content. If you republish them, link to the original posting (
url) and follow each employer's terms. - Personal data: postings rarely contain personal data, but descriptions sometimes include a recruiter's email or phone number. Descriptions are off by default, and when they're on, emails and phone numbers are removed unless you turn on
includeContactDetails. That covers US numbers, international+/00numbers, national formats such as UK020 7946 0958, DE030 1234567/030/1234567and FR01 23 45 67 89,tel:links, and numbers right after words like "phone", "call" or "WhatsApp". Salary figures are kept. People's names in descriptions are not removed. If you do, you're responsible for having a lawful basis (e.g. under GDPR) to process them. - Name detection is a best guess. Only boards whose own name matches what you typed are used by default, but a company whose board token differs from its name can be missed (status
notFound, sometimes with a "did you mean" suggestion). Two different companies can also share a name. For anything important, use the board URL or an explicit token. - Some Lever and Greenhouse boards belong to staffing agencies; for those,
companyis the agency.
FAQ
Why didn't my company show up? It may use another ATS (Ashby, Workday, SmartRecruiters, …), which this Actor doesn't read, or a board token that differs from its name. Open its careers page, click a job, and if the link is on jobs.lever.co or greenhouse.io, paste that board URL.
How fresh is the data? It's live: each run reads the Lever and Greenhouse APIs at that moment.
Can I search all Lever or Greenhouse jobs at once? No. Both APIs work per company, so you need to list the companies you want.