Lever Jobs Lookup — Job Postings API by Company Slug avatar

Lever Jobs Lookup — Job Postings API by Company Slug

Pricing

from $3.00 / 1,000 successful lookups

Go to Apify Store
Lever Jobs Lookup — Job Postings API by Company Slug

Lever Jobs Lookup — Job Postings API by Company Slug

Look up any company's live Lever job postings by slug or careers-page URL — title, location, team, commitment, and apply link, one row per open role. Straight from Lever's own public postings API, no login or key needed. Charged once per company with at least one open role — never per job posting.

Pricing

from $3.00 / 1,000 successful lookups

Rating

0.0

(0)

Developer

Adrian Voss

Adrian Voss

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

You paste a list of companies — a bare Lever slug like spotify or a full careers URL like https://jobs.lever.co/spotify — and you get back every open role on that company's Lever job board: title, location, team, commitment type, posting date, and a direct apply link, one row per posting. This hits Lever's own public postings API (api.lever.co) directly, the same JSON feed that powers a company's public jobs.lever.co careers page — no scraping, no login, no API key. You can also filter down to the roles you actually care about, and put the actor on a schedule to get only the postings that are new since your last run.

Who it's for

The accountable_eel catalogue sells company intelligence columns for outbound. Each actor takes a list of domains or company identifiers and returns one flat, stably-named row per input — firmographics, registry IDs, tech stack, email route, hiring activity — the shape a Clay table, an n8n workflow, or an AI agent can consume without post-processing. Pricing is pay-per-event and per-domain: a few tenths of a cent for a row that was actually found, and nothing for a miss, so a list that doesn't enrich costs you next to nothing. Where an official source exists — VIES, GLEIF, SEC EDGAR, Brønnøysund, PRH, RDAP — it is queried directly instead of scraped. No seat licence, no monthly minimum, no credit system to decode.

For Lever specifically: if your outbound list includes companies that hire through Lever, this is the column that turns "are they hiring" into a number and a role list you can filter and re-run.

Why this one

  • Direct from Lever's own API, not HTML scraping — nothing to break when a careers page gets redesigned, and no proxy or browser overhead.
  • Priced per company, not per job. A company with 200 open roles costs the same as one with three; you're paying for the lookup, not the payload size.
  • Real job filters, not just a keyword grep on the finished row — title include/exclude, location, remote, and posted-date all run before the row is built, so jobCount reflects what actually matched.
  • A delta mode built for a schedule. onlyNewSinceLastRun remembers what it showed you last time in a named key-value store in your own account, so a recurring run reports new roles instead of dumping the whole board every time.
  • Lever's own workplaceType field drives the remote flag — a structural signal most ATS platforms don't expose, backed up by a text match on location and title as a fallback.

What you get

Every row carries these fields. query, found, status, message and scrapedAt are on every row regardless of what was found; the rest come from Lever's postings API.

FieldType / formatWhat it is
querytextThe input you passed in, as given.
foundbooleantrue if the company has a Lever board (even with 0 matching roles), false if it has no board at all.
statustextOK, NOT_FOUND, or BAD_FORMAT — see the FAQ for what each means.
messagetextHuman-readable detail, populated on a miss.
scrapedAtdateWhen this row was fetched, ISO timestamp.
companytextThe Lever slug the row is for, normalized (lowercase, URL stripped to the slug).
jobCountnumberHow many postings are in this row's result — after filters, and after delta if onlyNewSinceLastRun is on.
totalJobCountnumberOpen jobs on the board before any filtering — lets you tell "filtered out" apart from "nothing there".
newJobsnumberPostings new since your last run. null unless onlyNewSinceLastRun is on.
firstRunbooleanWhether this was the baseline run of this watchlist. null unless onlyNewSinceLastRun is on.
jobsarrayThe full matched job list, nested. Present when "One row per job posting" is off; each entry has the same title/location/team/commitment/createdAt/postedAt/remote/applyUrl shape as the flat columns below.
titletextJob title.
locationtextPosting location, as Lever's categories.location reports it.
teamtextTeam/department, as Lever's categories.team reports it.
commitmenttextEmployment type — e.g. Permanent, Intern, Contract — as Lever reports it.
createdAtdateWhen Lever created the posting, ISO timestamp.
postedAtdateSame value as createdAt — Lever only tracks one date per posting; kept as a separate field for consistency with the other ATS actors in this catalogue.
remotebooleantrue when Lever's own workplaceType says remote, or the location/title text matches a remote pattern as a backstop.
applyUrllinkDirect link to apply for the posting.

Price

$5 per 1,000 companies, plus a $0.0001 start fee. Misses (found:false) are never charged.

That's the FREE-tier rate — it drops on paid Apify plans. You're only billed for a company with at least one open role on its Lever board; a company with no board, an unknown slug, or a slug that's moved off Lever costs nothing. A company whose board exists but whose postings all get filtered out (or has nothing new since your last run) still returns found: true and is still charged — the lookup happened and answered your question, it just came back at jobCount: 0.

1,000 companies through this actor: ~$5 if every one has an active Lever board, less for whatever fraction come back as misses. The same 1,000 rows through a credit-based enrichment platform: $80–$400.

How to use

  1. In the Apify Console. Open the actor page and click Start — the companies field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
  2. Via the API. Call it directly with a POST request — no Console needed once you have an API token:
    curl "https://api.apify.com/v2/acts/accountable_eel~lever-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"companies":["spotify"]}'
  3. On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.

Paste one company per line — a bare slug (spotify) or a full careers URL (https://jobs.lever.co/spotify); both resolve the same way. Leave the filters empty and you get every open posting on each board.

To narrow the results, open the 🎯 Job filters section of the Input tab:

  • titleKeywords / excludeTitleKeywords — keep or drop roles by title, case-insensitive, partial-word matches count.
  • locations — keep only roles whose location mentions one of your terms.
  • remoteOnly — keep only roles Lever (or the location/title text) marks remote.
  • postedAfter — drop anything posted before this date.

Different filters combine with AND; values inside one filter combine with OR. jobCount always reflects what matched, totalJobCount always shows what was on the board before filtering, so a filtered-to-zero result is never ambiguous with a broken run.

To watch a list on a schedule instead of re-pulling the same roles every time, turn on onlyNewSinceLastRun in the 🔁 Watch for new jobs section. The first run baselines and returns everything that matches; every run after that returns only postings it hasn't shown you before, with newJobs and firstRun telling you which case you're in. A quiet run still returns a row (jobCount: 0, newJobs: 0) rather than nothing, so you can tell "nothing new" apart from "the schedule broke."

Turn off "One row per job posting" in the Input tab to get one row per company instead, with the full matched job list nested in jobs.

Input

{
"companies": [
"spotify"
]
}

One company per line — paste the Lever slug or the full jobs.lever.co careers URL. Accepted formats: spotify, https://jobs.lever.co/spotify.

Don't know the company's exact Lever slug? Paste their careers page URL instead — both spotify and https://jobs.lever.co/spotify work, and the slug is pulled out automatically.

Sample output

By default you get one row per open job posting (turn off "One row per job posting" in the Input tab to get one row per company instead, with the full job list nested inside):

queryfoundstatuscompanyjobCounttotalJobCountnewJobsfirstRunjobstitlelocationteamcommitmentcreatedAtpostedAtremoteapplyUrlscrapedAt
spotifytrueOKspotify95<open jobs on the board (before filters)><first run of this watchlist?><all jobs (full list)>Advertiser Solutions Vendor Lead - Programmatic and Direct SupportLondonAdvertising Sales - Emerging and Scaled SalesPermanent2026-07-20T17:49:59.619Z<remote?>https://jobs.lever.co/spotify/890b2c0f-f46f-4a4b-bb73-3a6af6e0edd52026-08-23T06:01:20.062Z

A real row looks like:

queryfoundstatuscompanytitlelocationapplyUrl
spotifytrueOKspotifyAndroid Engineer - AdvertisingNew York, NYhttps://jobs.lever.co/spotify/a0fa7da3-4c3c-4fa2-97bd-7d6eb01eb9e5

A company slug that doesn't exist on Lever, has moved off the platform, or currently has zero open postings comes back as a single found: false row with a status/message explaining why — and is never charged.

Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

curl "https://api.apify.com/v2/acts/accountable_eel~lever-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
-X POST \
-H "Content-Type: application/json" \
-d '{"companies":["spotify"]}'

n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~lever-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"companies":["spotify"]} (swap in an expression from an earlier node for a real value).

Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~lever-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"companies":["{{company}}"]}, mapping the row's company into the companies array.

MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Lever Jobs Lookup | Apify" — the agent will find and run this actor.

Tips

  • Start with no filters to see the full board, then add titleKeywords or locations once you know what you're looking for — filters apply before the row is built, so you never pay to see roles you're about to throw away in a downstream step.
  • Put a filtered list on a schedule with onlyNewSinceLastRun on instead of re-running the full pull — you'll get a newJobs count each time instead of a full dump to diff yourself.
  • Remember that changing any filter starts a fresh watchlist — the seen-list is keyed on the filter combination, so editing titleKeywords mid-schedule re-baselines rather than silently reusing the old seen-set.
  • Use totalJobCount alongside jobCount when you're not sure whether a zero result means "no match" or "no board" — a found: true row with jobCount: 0 means the board exists and your filters just didn't match anything on it.
  • If your list is mixed across ATS platforms, don't try to guess which company runs Lever — ats-jobs-unified-lookup checks all seven platforms per company and tells you which one hit.

vs. alternatives

What it costsWhat you getTrade-off
This actor (lever-jobs-lookup)$0.005 per company whose board is found (less on paid tiers), $0.0001 actor start, nothing for a company with no Lever boardEvery open posting for a company's Lever board — title, location, team, commitment, apply URL — filtered by role keyword, location, remote, or posting date, with onlyNewSinceLastRun for deltasLever only. If your list is mixed-ATS, use ats-jobs-unified-lookup. Lever exposes one date per posting (no separate "first posted" vs. "last updated"), and only one location field — no per-office breakdown.
TheirStack$0.005–$0.03 per companyA job-postings dataset with history, normalised across many ATS platforms and job boardsBroader coverage than one platform, and it keeps history. This reads Lever's own API live, at the bottom of that price range.
Lever's own APIFreeThe same JSONIt is the same JSON. This handles the slug/URL parsing, filtering, deltas, and the retries — and hands you a flat table instead of raw postings JSON.
Clay$0.08–$0.40 per enriched row in credits, on top of a seatA whole enrichment workspace — waterfalls across dozens of providers, plus the table and the sequencing around itIf you want one place that does everything and you're not counting rows, that's Clay. This is one column, priced per column, callable from Clay via its HTTP step.

Prices for third-party tools are their published list prices as of August 2026 and are not tracked here — check the vendor before relying on the comparison.

FAQ

Why is a row empty / why does found say false? Either the input doesn't look like a Lever slug or URL (status: BAD_FORMAT), or that company doesn't have a Lever board, or currently has zero open roles (status: NOT_FOUND). Check the message column for the specific reason.

Why wasn't I charged for that row? You're only charged for a company where at least one open role was found on its board. A company with no board or no current openings is free — check status to see which.

Why was I charged for a company that returned 0 jobs? Because its board exists and has open postings — they just didn't match your filters, or weren't new since your last run. totalJobCount shows how many were actually on the board. A company with no Lever board, or with nothing open at all, comes back found: false and is never charged.

Does the "new since last run" state cost anything or leak between users? It lives in a named key-value store (lever-jobs-lookup-state) inside your own Apify account, so nobody else can see it, and its storage cost is negligible — a list of posting IDs per company per filter combination. Delete that store to reset every watchlist. Changing any filter also starts a fresh watchlist automatically, since the filter combination is part of the seen-list's key.

Are there rate limits? The actor queries Lever's public postings API once per company in your input list; it isn't authenticated and doesn't need a key. Very large company lists run as a normal Apify job — expect run time to scale with list size, same as any other actor in this catalogue.

Is this GDPR-safe to run on a list of companies? The input is company slugs or careers-page URLs, and the output is public job posting data Lever already serves on the company's own careers page — nothing personal is looked up or stored beyond the seen-list of posting IDs used for delta mode, which lives in your own account.

Can I schedule this and call it from an AI agent at the same time? Yes — the same actor works both ways. Put it on an Apify schedule with onlyNewSinceLastRun for a standing watchlist, and call it synchronously over HTTP or MCP (see above) for one-off or agent-driven lookups; they don't interfere with each other unless they share the same filter combination on the same company.

Does this work for companies not on Lever? No — only companies whose careers page runs on Lever's jobs.lever.co platform. Companies on Greenhouse, Ashby, Workday, or another ATS need the matching lookup actor for that platform, or ats-jobs-unified-lookup if you don't know which platform a company uses.