Lever & Ashby Jobs Scraper: Career Site Job Feed avatar

Lever & Ashby Jobs Scraper: Career Site Job Feed

Pricing

from $2.00 / 1,000 jobs

Go to Apify Store
Lever & Ashby Jobs Scraper: Career Site Job Feed

Lever & Ashby Jobs Scraper: Career Site Job Feed

Lever jobs scraper and Ashby jobs scraper: returns postings from companies' public Lever and Ashby job boards in one schema: normalized salary, seniority, remote/hybrid, description and apply URL. Only new jobs, plus closed-job alerts. Posting content belongs to the employers.

Pricing

from $2.00 / 1,000 jobs

Rating

0.0

(0)

Developer

FedSignals Data

FedSignals Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Many tech and growth companies publish their openings on Lever or Ashby job boards. This Actor reads those jobs directly from Lever's and Ashby's public job-posting feeds: Lever's postings API (api.lever.co/v0/postings/<company>) and Ashby's public job posting API (api.ashbyhq.com/posting-api/job-board/<company>). It doesn't scrape aggregators, doesn't log in and doesn't need a browser, so runs are fast, cheap and reliable. Every job comes out in one normalized schema: title, company, locations, remote, department, employment type, salary range normalized to a min, max, currency and period (plus an estimated yearly figure), seniority, workplace type (remote, hybrid or on-site), description (text or HTML), apply URL and posted/updated dates.

Give it Lever or Ashby board URLs, lever:slug / ashby:slug pairs or bare company slugs. It filters by keyword, location, remote, department, employment type, seniority, workplace type, minimum yearly pay and posting age. In incremental mode it returns only jobs you haven't seen before, plus a closed record when a job you received disappears from its board. That makes it a good fit for daily job alerts, job-board backfills, hiring-signal tracking and recruiting pipelines.

No API key or login is needed. The job postings belong to the employers that published them; the Actor passes on what each company publishes on its public board, with a link back to the original posting. It doesn't output recruiter or hiring-manager names, and personal email addresses inside descriptions are replaced with [email removed].

Supported sources

SourceBoard URLFeed read
Leverhttps://jobs.lever.co/<company> (EU: https://jobs.eu.lever.co/<company>)Lever public postings API, api.lever.co/v0/postings/<company>
Ashbyhttps://jobs.ashbyhq.com/<company>Ashby public job posting API, api.ashbyhq.com/posting-api/job-board/<company>

Only these two are supported. Any other job board, or a company's own careers page, stops the run before anything is fetched, so no jobs are charged (only Apify's $0.00005 start fee applies), and the run message names the entries to change.

What you can put in companies

InputExample
Board URLhttps://jobs.lever.co/spotify, https://jobs.ashbyhq.com/openai
lever:slug or ashby:sluglever:palantir, ashby:ramp
Bare slug (auto-detect)ramp (checks Lever and Ashby and uses the board with more jobs; use a URL or ats:slug to pick one)

You can also tick starter lists: 36 well-known companies (16 on Lever, 20 on Ashby) whose public boards were checked on Oct 29, 2026.

Example input

{
"companies": ["https://jobs.lever.co/spotify", "ashby:openai", "ramp"],
"keywords": ["data engineer", "machine learning"],
"locations": ["united states", "new york", "san francisco"],
"includeRemoteWithLocation": true,
"seniority": ["senior", "staff", "lead"],
"workplaceTypes": ["remote", "hybrid"],
"postedWithinDays": 30,
"onlyNew": true,
"descriptionFormat": "text",
"maxItems": 1000
}

Example output

A new job (from our Oct 30, 2026 test on Spotify's Lever board; description shortened):

{
"recordType": "job",
"jobId": "lever:spotify:47aeb6ee-f8c9-4f1e-9197-25c4c5676e5d",
"ats": "lever", "company": "Spotify", "companySlug": "spotify", "atsJobId": "47aeb6ee-f8c9-4f1e-9197-25c4c5676e5d",
"title": "Director of Sales - Emerging & Scaled (New Business)",
"location": "New York, NY", "locations": ["New York, NY"], "country": "US",
"remote": false, "workplaceType": "hybrid",
"department": "Advertising", "team": "Advertising Sales - Emerging and Scaled Sales", "employmentType": "Full-time", "seniority": "director",
"salaryMin": 137999.0, "salaryMax": 197142.0, "salaryCurrency": "USD", "salaryInterval": "year",
"salaryMinYearly": 137999.0, "salaryMaxYearly": 197142.0,
"salaryText": "$137,999 - $197,142", "salarySource": "description",
"descriptionText": "Spotify's Emerging & Scaled (E&S) business is growing rapidly across the US and Canada, an ...",
"jobUrl": "https://jobs.lever.co/spotify/47aeb6ee-f8c9-4f1e-9197-25c4c5676e5d",
"applyUrl": "https://jobs.lever.co/spotify/47aeb6ee-f8c9-4f1e-9197-25c4c5676e5d/apply",
"postedAt": "2026-10-23T13:35:03Z", "updatedAt": null,
"firstSeenAt": "2026-10-30T18:43:59Z"
}

A closed job (incremental mode, when a job you received is no longer on its board). This one is illustrative: the job above is still open, and the dates show the format.

{
"recordType": "closed",
"jobId": "lever:spotify:47aeb6ee-f8c9-4f1e-9197-25c4c5676e5d", "ats": "lever", "companySlug": "spotify", "atsJobId": "47aeb6ee-f8c9-4f1e-9197-25c4c5676e5d",
"company": "Spotify", "title": "Director of Sales - Emerging & Scaled (New Business)",
"jobUrl": "https://jobs.lever.co/spotify/47aeb6ee-f8c9-4f1e-9197-25c4c5676e5d",
"location": "New York, NY",
"firstSeenAt": "2026-10-30T18:43:59Z", "lastSeenAt": "2026-11-12T07:00:00Z", "closedAt": "2026-11-13T07:00:00Z"
}

Every job row has the same fields: recordType, jobId, ats, company, companySlug, atsJobId, title, location, locations, country, remote, workplaceType, department, team, employmentType, seniority, salaryMin, salaryMax, salaryCurrency, salaryInterval, salaryMinYearly, salaryMaxYearly, salaryText, salarySource, descriptionText, descriptionHtml, jobUrl, applyUrl, postedAt, updatedAt, firstSeenAt. A field is null when the posting doesn't include it. Closed rows carry only the fields shown in the second example.

Salary. Structured pay data from the posting is used first (salarySource: "ats"). If there isn't any, the Actor looks for a pay range written in the description, such as "$150,000 - $200,000" (salarySource: "description"). Equity, bonus and stipend amounts are ignored. Parsed salaries are best-effort, so check the job page before relying on them.

Normalization. salaryInterval is always one of hour, day, week, month or year, and salaryCurrency is an upper-case ISO code. salaryMinYearly/salaryMaxYearly are estimates in the job's own currency (hour × 2,080, day × 260, week × 52, month × 12); they are not currency-converted.

Seniority (intern, entry, mid, senior, staff, lead, manager, director, vp, executive) is taken from the job title first (e.g. "Senior", "Staff", "Principal", "Head of", "Engineer II"). It is null when there is no signal; "Product Manager" and similar titles are not tagged as people managers.

Workplace type is remote, hybrid or onsite, from the Lever or Ashby posting where it has one, otherwise inferred from the location and title text.

Test results (build 0.1.9, Oct 30, 2026)

  • Both starter lists (16 Lever and 20 Ashby boards), no descriptions: 6,053 jobs (Lever 3,440, Ashby 2,613), 0 board errors, 49 seconds. 2,435 of them (40%) had a salary range.
  • Mixed input with full descriptions (https://jobs.lever.co/spotify, https://jobs.ashbyhq.com/openai, ashby:notion, the bare slug ramp and an unknown slug): 1,221 jobs in about 4 seconds. ramp was auto-detected on Ashby; the unknown slug was skipped for free and reported in SUMMARY.
  • Filtered run ("data" / "machine learning", US plus remote, last 30 days, 36 starter boards): 64 jobs.
  • Incremental: a second onlyNew run with the same stateKey returned only jobs the first run had not delivered (no overlap).
  • Unsupported input: a run listing a non-Lever/Ashby board or a careers page stops before fetching anything, with 0 jobs charged.

Use cases

  • Job alerts and niche job boards. Schedule a daily run with onlyNew: true and send new jobs to Slack, email, Google Sheets or your own site.
  • Recruiting and sourcing. Watch target companies for specific roles, teams or locations.
  • Sales and market intelligence. Hiring is a buying signal. A burst of "Data Engineer" or "Salesforce Admin" openings tells you what a company is investing in.
  • Labour-market and salary research. Pay ranges published on Lever and Ashby postings, in one schema.

Incremental mode

With onlyNew: true (the default), job IDs are stored in a named key-value store (career-site-jobs-feed-state) under your stateKey. Later runs skip jobs that were already delivered. A job is forgotten 45 days after it was last seen on its board, so long-open roles are never re-sent. Use a different stateKey for each saved task.

Closed jobs. With trackClosedJobs: true (the default in incremental mode), each run compares every board's full public list (not just your filtered matches) with the jobs you've received. A job that is gone gets one record with recordType: "closed" and closedAt. If a board returns no jobs at all (an outage or a removed board), closed detection is skipped for that board so you don't get false closures. Filter on recordType (or use the Closed jobs dataset view) to separate the two record types.

Known limits

  • Only Lever and Ashby. Other job boards and companies' own careers pages are not read; a run that lists one fails at the start with no job charges.
  • Company name. Lever's and Ashby's feeds don't include the company's display name, so it comes from the starter list when the company is on it, otherwise from the slug (openai becomes "Openai"). companySlug is always exact.
  • country is passed on as the board publishes it: usually a two-letter code on Lever (US) and a country name on Ashby (United States).
  • Seniority and yearly pay are derived values. Treat them as labels for filtering, not as facts published by the employer. Salaries parsed from descriptions are best-effort.
  • includeRemoteWithLocation keeps all remote jobs, including ones restricted to other countries ("Remote UK"). Add a country to excludeKeywords or check location if that matters.
  • Personal email addresses in descriptions are redacted by pattern, so this is best effort.
  • 0 jobs? Since build 0.1.10 the status message says why. Either no listed job matched your filters (it names the active ones, e.g. keywords, locations, remoteOnly, postedWithinDays, so you know what to loosen), or every match was already delivered under this stateKey in onlyNew mode (turn onlyNew off or use a new stateKey), or the boards have no open jobs. A 0-job run charges no job events.
  • The jobs are the companies' own postings. Respect each company's terms when republishing them, and link back with jobUrl.

How much does it cost?

Pay per event: you pay only for the events below plus Apify's $0.00005 run-start fee. Platform compute is included in the price.

  • $2 per 1,000 jobs ($0.002 per job delivered). In incremental mode you pay only for jobs you haven't received before.
  • $0.001 per closed-job record (incremental mode with trackClosedJobs on), only when a job you received disappears from its board. Turn trackClosedJobs off to skip them.

Real examples from our test runs:

  • Quick-start input (product designer jobs at Spotify, OpenAI and Linear): 10 jobs in our Oct 30 test = 10 × $0.002 = about $0.02; maxItems 20 caps it at $0.04.
  • Both starter lists (36 Lever and Ashby boards), once: 6,053 jobs in our Oct 30 test = about $12.11. Use keywords, locations or maxItems to take only what you need.
  • Daily incremental alert: you pay only for new jobs, so 5 new postings a day = 5 × $0.002 = about $0.01 a day.
  • Filtered search (data and machine-learning roles, US or remote, last 30 days, 36 starter boards): 64 jobs = about $0.13.

Use maxItems and Apify's per-run spending limit to cap spend; the Actor stops cleanly when the limit is reached.

Dates, time zones and currency

  • postedAt, updatedAt, firstSeenAt, lastSeenAt and closedAt are ISO 8601 in UTC (Z). When a board gives only a date, it becomes midnight UTC that day.
  • salaryCurrency is the ISO 4217 code for salaryMin/salaryMax (e.g. EUR, GBP, USD). When the pay appears only as a symbol in the description, $ is read as USD, £ as GBP and € as EUR.

Other languages and regions

Works for Lever and Ashby boards in any country, including EU-hosted Lever boards (jobs.eu.lever.co). country and salaryCurrency come from each posting.

Also searched as: ofertas de empleo, vacantes, bolsa de trabajo (ES) · vagas de emprego, ofertas de trabalho (PT) · offres d'emploi (FR) · Stellenangebote, Jobbörse (DE).

FAQ

Which job boards are supported?
Lever (jobs.lever.co, read through Lever's public postings API at api.lever.co/v0/postings) and Ashby (jobs.ashbyhq.com, read through Ashby's public job posting API). Other job boards and companies' own careers pages are not read: a run that lists one stops before fetching anything and is not charged, and the message tells you which entries to change.

Can it tell me when a job closes?
Yes. In incremental mode (onlyNew) with trackClosedJobs on, a job you received that disappears from its board comes back once as a recordType: "closed" row with closedAt, at $0.001 each. Empty boards are skipped so an outage doesn't look like mass closures.

How are salary and seniority normalized?
Pay periods become hour, day, week, month or year with an upper-case currency code, plus estimated yearly figures (salaryMinYearly, salaryMaxYearly) in the job's own currency. Seniority (intern to executive) comes from the title; it is null when there is no signal.

Do I need an API key or a login?
No. The Actor reads only the public job-posting feeds that Lever and Ashby publish for each company's board, with no login.

How do I get only new jobs every day?
Turn on onlyNew, save a Task and schedule it daily. Each run returns only jobs you haven't received.

Does it include salary?
When the company publishes it: as a structured range where the Lever or Ashby posting has one, otherwise parsed from the description where possible.

Does it return recruiter names or emails?
No. Recruiter and hiring-manager names are not output, and personal email addresses inside a description are replaced with [email removed] (shared addresses such as jobs@ or careers@ are kept).

Who owns the job postings?
The employers. The Actor passes on what each company publishes on its public Lever or Ashby board, with a link back to the original posting.

Reliability

HTTP only, with no browser and no login. Requests identify the Actor with a descriptive User-Agent that includes a contact address, each job-board host gets its own polite rate limit (at least 0.25 s between requests, 0.5 s by default, at most 4 boards in parallel), and errors are retried with backoff. One failing board never fails the run: its error is recorded in the SUMMARY record (boardErrors, perBoard) and the run continues.

Measured on Apify as of Oct 29, 2026: 3 of 4 of our own test runs succeeded (75%), with a median run time of 5 seconds (longest 15 s) on small test inputs. It is a small sample from a new Actor; we will update it as runs accumulate. Build 0.1.9 local tests, Oct 30, 2026: both starter lists (36 Lever and Ashby boards) returned 6,053 jobs in 49 seconds with 0 board errors; a mixed input of Lever and Ashby URLs, an ashby: slug and a bare slug returned 1,221 jobs in about 4 seconds; an incremental rerun returned 5 new jobs with no overlap.

Use it from AI agents (MCP)

Add this Actor as a tool in Claude Desktop, Cursor or any MCP client through the Apify MCP server:

{
"mcpServers": {
"career-site-jobs-feed": {
"url": "https://mcp.apify.com?tools=fedsignals/career-site-jobs-feed",
"headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
}
}
}

Use it from code (API)

One call runs the Actor and returns the dataset items. maxTotalChargeUsd caps what the run can charge.

Python:

import requests
items = requests.post(
"https://api.apify.com/v2/acts/fedsignals~career-site-jobs-feed/run-sync-get-dataset-items",
params={"maxTotalChargeUsd": 1},
headers={"Authorization": "Bearer YOUR_APIFY_TOKEN"},
json={"companies": ["https://jobs.lever.co/spotify", "https://jobs.ashbyhq.com/openai", "https://jobs.ashbyhq.com/linear"], "keywords": ["product designer"], "onlyNew": False, "maxItems": 20},
timeout=300,
).json()
print(len(items), "items")

JavaScript (Node 18+):

const res = await fetch(
"https://api.apify.com/v2/acts/fedsignals~career-site-jobs-feed/run-sync-get-dataset-items?maxTotalChargeUsd=1",
{
method: "POST",
headers: { Authorization: "Bearer YOUR_APIFY_TOKEN", "Content-Type": "application/json" },
body: JSON.stringify({"companies": ["https://jobs.lever.co/spotify", "https://jobs.ashbyhq.com/openai", "https://jobs.ashbyhq.com/linear"], "keywords": ["product designer"], "onlyNew": false, "maxItems": 20}),
}
);
const items = await res.json();
console.log(items.length, "items");

Feedback

Found a bug or need a filter or source? Open an issue on the Issues tab or email fedsignals.alerts@gmail.com.

This Actor is not affiliated with or endorsed by Lever, Ashby or the listed companies. Job posting content belongs to the employers that published it.