Lever Jobs Scraper: jobs.lever.co Postings Export avatar

Lever Jobs Scraper: jobs.lever.co Postings Export

Pricing

from $0.32 / 1,000 unique job results

Go to Apify Store
Lever Jobs Scraper: jobs.lever.co Postings Export

Lever Jobs Scraper: jobs.lever.co Postings Export

Collect current jobs from public Lever.co boards (jobs.lever.co, global and EU) to track hiring at target companies, find leads by open roles or feed a job board. Official Lever postings API, no API key, login or proxy.

Pricing

from $0.32 / 1,000 unique job results

Rating

0.0

(0)

Developer

Cliqto Media

Cliqto Media

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 days ago

Last modified

Features

Limited permissions

Share

Collect current job postings from public Lever.co boards (jobs.lever.co, global and EU) to track hiring at target companies, find sales leads by open roles, or feed your own job board. Add a board slug, board URL, or one exact job URL. It uses the official Lever postings API: no API key, login or proxy. Get one row per unique job with a stable ID, description and published salary.

Start with targets: ["leverdemo"]. The new Input form has this small example filled in. Pricing is $0.002 per start + $0.45 per 1,000 useful job rows on the Free plan (down to $0.315 on Gold) at the default 512 MB memory. Check RUN_SUMMARY when a board is empty, a filter removes jobs, or a source request fails.

Lever Job Scraper: public boards to stable job rows, descriptions and a run report

Table of contents

What it does

Read public published postings from known Lever boards. Global and EU boards are supported. A bare slug uses the global service. An exact posting URL reads that job. The Actor uses the public Lever Postings API with direct HTTPS requests. No Lever account or API key is needed.

Get titles, locations, departments, teams, commitments, workplace types and public links. Keep HTML and plain descriptions, list sections and published salary fields when includeContent is true. The Actor gives each job a stable ID and records outcomes for all input targets.

Good fit

  • A snapshot of open jobs on known company Lever boards.
  • Recruiting market research by team, location, commitment or workplace type.
  • A job feed built from exported rows with stable IDs.
  • A scheduled job alert: with onlyNewSinceLastRun each run returns only jobs that earlier runs have not returned.

This product does not discover companies, search all Lever jobs, read private/internal or closed postings, submit applications, or report closed or changed jobs. Other ATS platforms need a separate Actor.

👉 Try it now: open the input form

How it works

  1. You give public Lever board slugs, board URLs or exact job URLs. Each one is checked and normalized; duplicates are read once.
  2. The Actor reads the published jobs of each board from Lever's public postings service, global or EU, without a login, browser or proxy. Your filters and row caps are applied.
  3. It saves one Dataset row per unique job with a stable ID, and a RUN_SUMMARY report with a status for every target: jobs found, empty board, filtered out, not found or a technical error.

👉 Try it now: open the input form

Quick start

Input form: box 1 Lever board or job URL with the leverdemo prefill, box 2 descriptions toggle, box 3 maximum total jobs, box 4 only new jobs

  1. Open the Input tab. Keep the filled targets example, leverdemo, or paste your public Lever board URL such as https://jobs.lever.co/leverdemo (box 1 in the picture). Click + Add for more companies in one run.

  2. Keep Include descriptions and lists on for the full job text, lists and salary (box 2). Turn it off when titles, locations and links are enough.

  3. Keep Maximum total jobs at the runtime default 5000 or set 100 for a first test (box 3). Filters are optional, see Input.

  4. Optional: turn on Only new jobs since the last run for a scheduled job alert (box 4).

  5. Click Start.

  6. Open the Output tab (box 1 below). Each row is one job; check title, location, department and createdAt (box 2). Open Storage → Key-value store → RUN_SUMMARY for each target's status and counts.

    Output table: Output tab with one row per Lever job and columns for ID, title, location, department, team, commitment, workplace type, country and created date

Expected result: one Dataset row per published job with a stable id; the demo board had 10 published jobs when checked on 27 October 2026. Live jobs may change. API calls must supply targets; an empty API input does not select the demo.

👉 Try it now: open the input form

Use cases

TaskInputUseful fieldsNext step
Monitor hiring at target companiesTheir Lever board slugs in targets, onlyNewSinceLastRun: true, run on a schedulesourceJobId, title, team, createdAt, observedAtEach run gives only new jobs; for closed jobs, compare id values of two full runs without onlyNewSinceLastRun
Find sales leads from open rolesBoards of prospect companies, filters.teams such as Sales or Engineeringtitle, department, team, locations, hostedUrlPush rows to your CRM or sheet
Feed a job board or job alertincludeContent: true, filters.locationIncludes, filters.descriptionIncludes or filters.postedWithinDaysdescriptionText, salaryRange, workplaceType, applyUrlPublish or send the rows from your own system
Recruiting market researchMany boards, filters by team, location or commitmentteam, department, commitment, country, salaryRangeGroup rows by team, place or pay
Recheck a known postingExact job URL in targetsStable id, observedAt, source fieldsSee whether the job is still published

👉 Try it now: open the input form

Input

targets is required. It must have 1–50 strings. Duplicate normalized targets are fetched once. Invalid targets get INVALID_INPUT entries and are not fetched. A missing/empty target array or invalid option shape fails validation.

Fields

FieldTypeRequiredRuntime default / UI prefillAllowed values and effect
targetsarrayyesNo runtime default. UI prefill and schema default: ["leverdemo"].Use a board slug such as leverdemo, a public Lever board URL, or one exact public job URL. Bare slugs use the global Lever service.
includeContentbooleannoRuntime default: true. No UI prefill.Keep the public HTML/plain job content and list sections in each result.
filtersobjectnoNo filters. No UI prefill.All filled filter groups must match. Values within one group use OR logic.
maxJobsPerTargetintegernoRuntime default: 0. No UI prefill.Stop each board after this many useful results. Use 0 for no per-board cap. Range 0–5000.
maxTotalJobsintegernoRuntime default: 5000. No UI prefill.Maximum number of unique job rows saved in one run. Range 1–5000.
pageSizeintegernoRuntime default: 0. No UI prefill.Use the complete board response when 0. A positive value uses Lever skip/limit pages. Range 0–1000.
continueOnErrorbooleannoRuntime default: true. No UI prefill.Process independent targets after a technical failure and report a partial run.
onlyNewSinceLastRunbooleannoRuntime default: false. No UI prefill.Return only jobs that an earlier run with the same targets and filters has not returned. See Only new jobs.

Nested filters

All filled groups must match (AND). Values within one group match any value (OR). Text matches ignore case and trim outer spaces. Empty arrays do not filter. Filters run after fetching source rows; a small result cap does not cap the source response size.

FieldType / limitDefaultMatch rule
filters.titleIncludesarray; up to 20 valuesNo restrictionKeep jobs whose title contains at least one of these values. Case-insensitive substring.
filters.titleExcludesarray; up to 20 valuesNo restrictionSkip jobs whose title contains any of these values, e.g. intern. Case-insensitive substring.
filters.locationIncludesarray; up to 20 valuesNo restrictionKeep jobs whose source location contains at least one of these values. Case-insensitive substring. Checks all locations.
filters.locationExcludesarray; up to 20 valuesNo restrictionSkip jobs with any location that contains one of these values. Case-insensitive substring.
filters.descriptionIncludesarray; up to 20 valuesNo restrictionKeep jobs whose posting text (opening, description, lists, additional) contains at least one value. Case-insensitive substring. Works with includeContent: false.
filters.descriptionExcludesarray; up to 20 valuesNo restrictionSkip jobs whose posting text contains any of these values. Case-insensitive substring.
filters.departmentsarray; up to 20 valuesNo restrictionKeep jobs whose source department equals one of these values. Case-insensitive exact value.
filters.teamsarray; up to 20 valuesNo restrictionKeep jobs whose source team equals one of these values. Case-insensitive exact value.
filters.commitmentsarray; up to 20 valuesNo restrictionKeep jobs whose source commitment equals one of these values. Case-insensitive exact value.
filters.workplaceTypesarray; up to 4 valuesNo restrictionKeep jobs with one of these source workplace types.
filters.countriesarray; up to 20 valuesNo restrictionKeep jobs whose source country is one of these ISO-2 values. Case-insensitive exact value.
filters.createdAfterstring; UTC ISO date-time, e.g. 2026-10-01T00:00:00ZNo restrictionOnly jobs created on or after this ISO date-time. Jobs with no source creation time do not match.
filters.postedWithinDaysinteger; 0–365No restriction (0)Only jobs created in the last N days, counted from the run time. Jobs with no source creation time do not match.

Filter strings have a maximum length of 200 characters; country values use two letters. workplaceTypes accepts remote, hybrid, on-site, unspecified.

Only new jobs

With onlyNewSinceLastRun: true the Actor remembers the job IDs it has handled and skips them in later runs. The memory is a named key-value store in your Apify account, lever-jobs-scraper-state, with one record per set of targets and filters. The first run returns all matching jobs as a baseline. A different target list or different filters start a new baseline. Jobs cut off by maxJobsPerTarget, maxTotalJobs or a charge limit stay new for the next run, and so do jobs that failed to save. Up to 50,000 IDs are kept per record; the oldest are dropped first. Delete the record to start over.

RUN_SUMMARY shows previouslySeenJobs, stateBaseline (true on the first run) and stateSaved. A board with no new jobs gets FILTERED_EMPTY. Skipped known jobs are billed like filtered jobs (filtered-job, $0.01 per 1,000), and a board with no new jobs gets one no-result-target.

Setting interactions

SettingsResult
maxJobsPerTarget: 0 + maxTotalJobs: 5000No per-board cap; stop at 5,000 unique useful rows across the run
Positive per-target and total capsApply both caps after filtering and dedupe; a per-target cap still allows later boards
pageSize: 0Read one complete board response, subject to the 25 MiB response limit
Positive pageSizeUse Lever skip/limit pages; stop at a short/empty page, cap or repeated-page error
includeContent: falseOmit content and salary fields; lists is []; identity/category/link fields remain
continueOnError: trueContinue independent targets after a source failure and show a partial summary
onlyNewSinceLastRun: trueJobs already returned by an earlier run with the same targets and filters are skipped and billed as filtered-job

Examples

Small demo, also used for the output example below:

{"targets": ["leverdemo"]}

Two boards with a title filter and a per-board cap:

{
"targets": ["leverdemo", "https://jobs.lever.co/palantir"],
"filters": {"titleIncludes": ["engineer"]},
"maxJobsPerTarget": 20,
"maxTotalJobs": 40,
"includeContent": true
}

This saves up to 20 matching jobs from each board and 40 in total.

Job alert for remote engineering jobs that mention Kubernetes, without interns, only new since the last run:

{
"targets": ["leverdemo", "https://jobs.lever.co/palantir"],
"filters": {
"titleIncludes": ["engineer"],
"titleExcludes": ["intern"],
"descriptionIncludes": ["kubernetes"],
"workplaceTypes": ["remote"],
"postedWithinDays": 30
},
"onlyNewSinceLastRun": true
}

A filter may return no matches. EU input uses https://jobs.eu.lever.co/<board>. Public api.lever.co/v0/postings/<board> and EU API URLs are also accepted. HTTPS is required. Arbitrary hosts, userinfo, custom ports, fragments and traversal paths are rejected. Tracking query parameters are discarded.

👉 Try it now: open the input form

Output

Dataset fields

Each row is one unique published job. The stable ID is lever:{region}:{boardSlug}:{encodedSourceJobId}. The same title can occur on distinct jobs; IDs control dedupe. observedAt is this Actor's observation time. createdAt comes from the source, converted to an ISO timestamp; it is not an update time.

FieldMeaningTypeCan be empty?Example / enumSource / notes
idStable ID: lever:{region}:{board}:{postingId}.stringnolever:global:leverdemo:ad208490-…Set by the Actor
sourceThe public source name.stringnoleverSet by the Actor
idRuleVersionVersion of the stable identifier rule.stringnov1Set by the Actor
regionGlobal or EU public Lever instance.stringnoglobal, euSet by the Actor
boardSlugNormalized public Lever site slug.stringnoleverdemoSet by the Actor
boardUrlCanonical public hosted board URL.stringnohttps://jobs.lever.co/leverdemoSet by the Actor
sourceJobIdUpstream Lever posting ID.stringnoad208490-4052-4f91-a57e-433f2d1e484bLever source, not guessed
titlePublished job title.stringnoCustomer Success ManagerLever source, not guessed
locationPrimary source location, when present.stringyes (null)Atlanta, GeorgiaLever source, not guessed
locationsSource location values.arraycan be []["Atlanta, Georgia"]Lever source, not guessed
departmentSource department, when present.stringyes (null)Customer SuccessLever source, not guessed
teamSource team, when present.stringyes (null)Customer Success TeamLever source, not guessed
commitmentSource commitment, when present.stringyes (null)Regular Full Time (Salary)Lever source, not guessed
countrySource ISO-2 country, when present.stringyes (null)USLever source, not guessed
workplaceTypeSource workplace type or unspecified.stringnoremote, hybrid, on-site, unspecifiedLever source, not guessed
openingHtmlSource opening HTML when content is included.stringyes; omitted with includeContent: falsetext or HTML from the postingLever source, not guessed
openingTextPlain opening text when content is included.stringyes; omitted with includeContent: falsetext or HTML from the postingLever plain field, or converted from HTML
descriptionHtmlSource combined description HTML.stringyes; omitted with includeContent: falsetext or HTML from the postingLever source, not guessed
descriptionTextPlain combined description.stringyes; omitted with includeContent: falsetext or HTML from the postingLever plain field, or converted from HTML
descriptionBodyHtmlSource body HTML.stringyes; omitted with includeContent: falsetext or HTML from the postingLever source, not guessed
descriptionBodyTextPlain body text.stringyes; omitted with includeContent: falsetext or HTML from the postingLever plain field, or converted from HTML
listsSource list sections with title, HTML and text.arraycan be []; [] with includeContent: false[{"title": "Requirements", …}]Lever source, not guessed
additionalHtmlSource additional HTML.stringyes; omitted with includeContent: falsetext or HTML from the postingLever source, not guessed
additionalTextPlain additional text.stringyes; omitted with includeContent: falsetext or HTML from the postingLever plain field, or converted from HTML
salaryRangeSource salary range when provided.objectyes; omitted with includeContent: falsemin, max (number or null), currency, interval (string or null)Lever source, not guessed
salaryDescriptionHtmlSource salary note HTML.stringyes; omitted with includeContent: falsetext or HTML from the postingLever source, not guessed
salaryDescriptionTextPlain salary note.stringyes; omitted with includeContent: falsetext or HTML from the postingLever plain field, or converted from HTML
hostedUrlCanonical public job page.stringnohttps://jobs.lever.co/leverdemo/ad208490-…Lever source, not guessed
applyUrlSource application URL; never submitted by the Actor.stringyes (null)https://jobs.lever.co/leverdemo/ad208490-…/applyLever source, not guessed
createdAtSource creation time in ISO format.stringyes (null)2026-09-09T11:01:39.000ZLever source, not guessed
observedAtTime this Actor observed the row.stringno2026-10-28T05:00:00.000ZSet by the Actor

lists[] has title (section label), html (section body), and text (plain body), all strings. salaryRange is null or an object with min/max (number or null), currency/interval (string or null). No salary or location is guessed. workplaceType falls back to unspecified.

Missing source scalar values become null. Arrays can be empty. With includeContent: false, HTML/text and salary fields are omitted rather than set to null. HTML is source content; sanitize it before displaying it in your own web app. Plain text uses source plain fields when supplied, or HTML conversion. List body text is converted from list HTML. Some uncommon named HTML entities can remain encoded.

Example row

This trimmed row is from the leverdemo input above. Full descriptions and the remaining fields are in the Dataset.

{
"id": "lever:global:leverdemo:ad208490-4052-4f91-a57e-433f2d1e484b",
"sourceJobId": "ad208490-4052-4f91-a57e-433f2d1e484b",
"boardSlug": "leverdemo",
"title": "Customer Success Manager",
"location": "Atlanta, Georgia",
"locations": [
"Atlanta, Georgia"
],
"department": "Customer Success",
"team": "Customer Success Team",
"commitment": "Regular Full Time (Salary)",
"workplaceType": "hybrid",
"hostedUrl": "https://jobs.lever.co/leverdemo/ad208490-4052-4f91-a57e-433f2d1e484b",
"applyUrl": "https://jobs.lever.co/leverdemo/ad208490-4052-4f91-a57e-433f2d1e484b/apply"
}

Reports and outcomes

The Output tab links to dataset and runSummary. They are links, not a second copy of the rows. The Actor writes RUN_SUMMARY in the default key-value store; it does not write a separate OUTPUT record.

RUN_SUMMARY includes schemaVersion, status, received/valid/duplicate/processed/unprocessed target counts, results, duplicateJobs, emptyBoards, filteredEmpty, notFound, technicalFailures, retries, rate-limit counts, invalid/filtered source row counts, previouslySeenJobs, stateBaseline and stateSaved (only with onlyNewSinceLastRun), limitReached, chargeLimitStop, charge events/mode, transport, timings, requests, bytes, failed target references, and targets[].

Each target entry has inputIndex, canonicalTarget, mode, region, status, source/emitted row counts, retries and errorCode; bytes/requests and duplicate references are present when relevant.

OutcomeDataset / reportWhat to do
OKUseful job rowsExport or use rows
EMPTY_BOARDNo jobs returned by a valid source boardCheck later if needed
FILTERED_EMPTYSource had jobs, filters matched noneReview filters
NOT_FOUNDBoard or exact posting returned HTTP 404Check the URL; posting may be closed
INVALID_INPUT, DUPLICATE_TARGETNo result row for that targetCorrect invalid input; duplicates need no retry
LIMIT_REACHEDSaved rows retained; more jobs may existReview per-target/total/platform charge caps
Technical errorTIMEOUT, RATE_LIMITED, UPSTREAM_5XX, UPSTREAM_4XX, NETWORK_ERROR, BAD_CONTENT_TYPE, MALFORMED_JSON, SCHEMA_DRIFT, RESPONSE_TOO_LARGE, REDIRECT_ERROR, STORAGE_ERROR, ABORTED or UNPROCESSEDRead RUN_SUMMARY; fix input or retry later

Run-summary status is SUCCEEDED, PARTIAL, FAILED or LIMIT_REACHED. Apify run status and summary status are separate: a partial run can finish on the platform and still have failed targets. A full technical source failure fails the platform run. Empty/missing targets do not prove that a company has no jobs elsewhere.

👉 Try it now: open the input form

Pricing

Pay per event. Apify charges the standard apify-actor-start event automatically: $0.002 per start, one event per GB of run memory (minimum one). At the default 512 MB each run has one start event; 2 GB means two.

EventFree planBronzeSilverGold
Unique job row saved (unique-job-result)$0.45 / 1,000$0.405 / 1,000$0.36 / 1,000$0.315 / 1,000
Job read but skipped by your filters (filtered-job)$0.01 / 1,000samesamesame
Board or job URL with no paid rows (no-result-target)$0.0003 eachsamesamesame

no-result-target is charged once for a board or exact job URL that is not found, empty, or fully filtered. Duplicate rows, duplicate targets, invalid input and technical failures (timeouts, rate limits, Lever errors) are never charged. A partial run pays the start plus accepted useful rows and the small read events above.

Run at 512 MB (Free plan)Actor event charge
One missing board, 0 rows$0.0023
10 useful jobs$0.0065
100 useful jobs$0.047
1,000 useful jobs$0.452
5,000 useful jobs (current maximum per run)$2.252
A 4,000-job board filtered down to 0 rows$0.0423
A 4,000-job board filtered down to 100 rows$0.086

The filtered-job fee applies to every job your filters skip, also when other jobs match. On a very large board with a narrow filter it can be a noticeable part of the bill.

These are event fees; the standard PPE tariff has no separate customer platform-usage surcharge. Check the run billing and your plan.

maxTotalJobs caps rows, not a bill in dollars. Use Apify's maximum total charge option (maxTotalChargeUsd in API calls) to limit total Actor event charges, including the start. At 512 MB, allow at least $0.00245 for one start and one useful job. The run stops cleanly when the limit is reached. This option does not limit all platform costs.

RUN_SUMMARY.chargeEvents counts job-result events; filteredJobEvents and noResultTargetEvents count the two small read events. The automatic start appears in the Apify run billing. The summary is not a customer invoice.

👉 Try it now: open the input form

Limits

  • Up to 50 targets and 5,000 saved jobs per run.
  • Requests are paced one at a time with a 1-second host gap, up to 3 attempts, 20 seconds per request including body reading, up to 2 safe redirects, 25 MiB per response, and 1,000 pages per board. Large boards or repeated retries may exceed your platform timeout. Completeness means the public source response observed for your supplied boards, subject to these limits. Jobs may change during pagination.
  • Only public published postings of boards you supply: no company discovery, global Lever search, private/internal or closed postings, applications, or closed/changed-job reports.
  • Salary, location and dates are only what the source publishes; nothing is guessed.

👉 Try it now: open the input form

API, export and integrations

  • API: start a run with the Apify Actor run API and the same input JSON, then read the default Dataset.
  • Export: Dataset export supports JSON and CSV, plus other Apify formats. Nested lists are best kept in JSON.
  • Scheduling: you can use Apify scheduling with the same input. Each run has a start charge. Add onlyNewSinceLastRun: true to get only new jobs in each scheduled run; closed or changed jobs are not reported, so use the stable id in your system for those.

Use with AI agents (MCP)

  • MCP server with only this Actor: https://mcp.apify.com?tools=cliqtomedia/lever-jobs-scraper.
  • Smallest useful input: {"targets": ["leverdemo"]}.
  • Key output fields: id (stable job ID), title, location, team, hostedUrl (public job page); RUN_SUMMARY.targets[].status tells why a board gave no rows.
  • A small board such as the demo returns about 10 rows for about $0.0065 at 512 MB on the Free plan. Up to 50 targets and 5,000 rows per run; supply known board slugs, the Actor does not search Lever.

👉 Try it now: open the input form

Troubleshooting

  • URL rejected: use a supported HTTPS Lever host and one board or posting path. Do not paste a company's general careers URL.
  • No rows: open RUN_SUMMARY. Check EMPTY_BOARD, FILTERED_EMPTY, NOT_FOUND and technical errors separately.
  • Fewer rows: check caps, chargeLimitStop, filters and per-target status. An early stop does not prove a complete board.
  • Timeout, block or rate limit: retry later with fewer targets. No login, browser or proxy bypass is provided.
  • Missing salary or dates: the source may not publish them. They are not inferred.

👉 Try it now: open the input form

FAQ

Do I need a Lever account?

No. Only public published postings are read. See Lever Postings API documentation.

Can I get every job on Lever?

You must supply known boards. There is no company discovery or cross-company global search.

Can I get EU jobs or one job URL?

Yes. Use an EU hosted board/job URL for EU mode. An exact posting URL returns that job if it remains public.

Does a repeat run return only new jobs?

Only if you turn on onlyNewSinceLastRun. Then the first run returns all matching jobs and later runs with the same targets and filters return only jobs not returned before. Without it, each run is a fresh snapshot.

Is no output free?

No. A zero-row run still has the $0.002 start charge at default 512 MB, plus $0.0003 for each board or job URL that gave no rows and $0.01 per 1,000 jobs skipped by your filters; there is no job-result event. Higher memory can increase the start count. Check your run's billing.

Can descriptions or locations be missing?

Yes. The source controls those fields. Check nulls, empty arrays and includeContent; do not treat missing fields as guessed values.

👉 Try it now: open the input form

👉 Try it now: open the input form

Support

Open an issue in this Actor's Apify Issues tab. Include the run ID, public input mode and the relevant RUN_SUMMARY target status. Do not share tokens, cookies, private URLs or sensitive payloads.

Lever identifies the source format. This product is not affiliated with or endorsed by Lever.

👉 Try it now: open the input form