Lever & Greenhouse Jobs Lookup & New-Job Alerts avatar

Lever & Greenhouse Jobs Lookup & New-Job Alerts

Pricing

from $1.50 / 1,000 job returneds

Go to Apify Store
Lever & Greenhouse Jobs Lookup & New-Job Alerts

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

Stego

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 days ago

Last modified

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's warning names the other, so you can enter that token instead. Otherwise it's skipped with status uncertainMatch and a suggestion, and nothing is charged. For example, Palantir is used because the board lever:palantir is titled "Palantir Technologies", but a name whose likeliest board has a different title (say, Acme Robotics guessing a board titled "Totally Different Staffing") is skipped as uncertainMatch. Set allowUncertainMatches to 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 gets unsupportedAts;
    • 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 a boards-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, or greenhouse:<token>. This is the fastest and most reliable option.
  • 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: false in the run's OUTPUT and the status message says so.
  • Whole-word keyword matching. AI matches "AI Engineer" but not "Maintain"; art doesn'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/spotify and lever:spotify, or https://boards.greenhouse.io/acme and greenhouse:acme) are read and charged once. Every entry you typed still appears in OUTPUT; the later ones get status duplicate, with sameAs naming the entry that was actually read and the same boardName.
  • 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: maxResults 1000 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 whether maxResults, maxResultsPerCompany or 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. onlyNew remembers 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 maxResults is filled in full: 31 big Lever boards plus 30 small ones with maxResults 25,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.

FieldDescription
companiesUp to 500 names, careers URLs, Lever / Greenhouse board URLs or lever: / lever-eu: / greenhouse: tokens.
allowUncertainMatchesDefault off. Include guessed boards whose own name doesn't match what you typed.
keywords / keywordMode / searchInWhole-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.
excludeKeywordsDrop jobs whose title or description contains any of these, e.g. Senior, Intern.
locations / excludeLocationsWhole-word match on the job's location and all of its listed locations, e.g. London, Germany, Remote.
remoteany (default), only or exclude.
departmentsWhole-word match on the department (Greenhouse departments, or the Lever department and team).
postedWithinDaysOnly jobs first published in the last N days (0 = all open jobs).
onlyWithSalaryOnly jobs with a published pay range.
minSalary + salaryCurrencyKeep jobs whose range reaches at least this yearly amount in this ISO currency. Hourly and monthly ranges are annualized.
maxResultsMax jobs per run, across all companies (default 100, newest first per company).
maxResultsPerCompanyOptional per-company cap (0 = none).
includeDescription / descriptionFormat / descriptionMaxLengthFull description, off by default. text or html, with optional truncation.
includeContactDetailsOff by default. When off, emails and phone numbers inside descriptions are replaced with [email removed] / [phone removed].
onlyNew / stateKey / baselineOnFirstRun / stateStoreNameAlert 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:

  • ats is lever or greenhouse.
  • postedAt is Lever's createdAt or Greenhouse's first_published. updatedAt is Greenhouse's updated_at (Lever doesn't publish one, so it's null). requisitionId and language come from Greenhouse (null for Lever).
  • remote and workplaceType: 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); otherwise workplaceType is null (not stated).
  • department and team are Lever's department and team; for Greenhouse, department joins the job's departments and team is null. employmentType is Lever's commitment (e.g. "Permanent", "Full-time"); Greenhouse doesn't publish one (null).
  • leverInstance is global (jobs.lever.co) or eu (jobs.eu.lever.co), and null for Greenhouse. country is Lever's country code (null for Greenhouse).
  • matchConfidence is high for board URLs, tokens and careers-page links, and for guesses whose board name matches. It's medium only with allowUncertainMatches. boardName is 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 in salaryNote (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/salaryMax span the ranges that share the first range's currency and period, and salaryRanges lists them all. Salaries that appear only in the description text aren't parsed, and many large employers publish no structured pay, so onlyWithSalary/minSalary drop all their jobs.
  • company is Greenhouse's company_name or 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)

  1. Set onlyNew: true and a stateKey, then schedule the Actor daily.
  2. The first run remembers today's matching jobs and returns nothing; you pay only the run start.
  3. Each later run returns only jobs that haven't been returned before. If maxResults or 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.
  4. 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.
  5. The state store (default ats-jobs-state) is shared by all runs and tasks in your account. Use a different stateKey per 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 other greenhouse.io host 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 as unsupportedAts. The Actor never sends a request to Ashby hosts, not even a robots.txt check: a careers site that redirects there is reported as unsupportedAts without 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 honours Retry-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 +/00 numbers, national formats such as UK 020 7946 0958, DE 030 1234567 / 030/1234567 and FR 01 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, company is 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.