ATS Jobs Feed & Hiring Signals: Greenhouse, Lever, Ashby avatar

ATS Jobs Feed & Hiring Signals: Greenhouse, Lever, Ashby

Pricing

from $1.50 / 1,000 job delivereds

Go to Apify Store
ATS Jobs Feed & Hiring Signals: Greenhouse, Lever, Ashby

ATS Jobs Feed & Hiring Signals: Greenhouse, Lever, Ashby

Live job postings from company career pages on Greenhouse, Lever and Ashby via their official public APIs. One unified schema, salary when published, and an only-new-jobs mode for daily feeds.

Pricing

from $1.50 / 1,000 job delivereds

Rating

0.0

(0)

Developer

Sirak Alem

Sirak Alem

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

16 hours ago

Last modified

Share

ATS Jobs Feed: Greenhouse, Lever & Ashby jobs (only new jobs mode)

👋 Hi! Give this Actor a list of companies and it brings you their open jobs, fresh from their own career pages: same format for every company, salary when they publish it, and an "only new jobs" mode so tomorrow you only see what was posted since today. Or switch to company hiring signals and get one row per company: open roles by function (sales, SDRs, engineering...), new roles this week, remote share and an explained hiring score.

It works with any company whose careers page runs on Greenhouse, Lever or Ashby, which is a lot of tech companies and startups (GitLab, Ramp, Zoox and thousands more).

Why I built it

I'm an independent developer from Italy who builds small automation tools. When I looked at the existing job scrapers for these platforms, many runs failed or returned duplicates and stale data. So I kept this one simple and boring on purpose: it reads the official public APIs, it does one job, and it tells you clearly when something goes wrong. If it doesn't work for you, tell me (see the bottom of this page) and I'll fix it.

In short

  • Data comes from the official public job board APIs of each ATS (the same APIs companies use to build their own career pages). No login, no proxies, no browser, no scraping of HTML.
  • Live, not a stale database: every run reads the boards at that moment.
  • No duplicates: every job has a stable id (platform:company:jobId).
  • One wrong slug never breaks your run: it is reported in RUN_SUMMARY and the other companies are processed normally.
  • You pay only for jobs delivered. Errors, empty boards and filtered-out jobs cost nothing.

What you can use it for

  • Daily alerts of new openings at a list of target companies (recruiters, job seekers, sales teams selling to companies that are hiring).
  • Hiring signals for sales and lead generation: which companies are hiring SDRs, AEs or a VP of Sales right now, which teams are growing, which roles just closed (see Hiring signals).
  • Salary benchmarks from Ashby and Lever postings that publish pay ranges.
  • Feeding a job board, a Slack channel, a Google Sheet or a CRM through Apify integrations.

Input

You only need the companies. The slug is the part of the career page URL after the domain:

PlatformCareer page URLSlug
Greenhousehttps://boards.greenhouse.io/gitlab or https://job-boards.greenhouse.io/gitlabgitlab
Leverhttps://jobs.lever.co/palantir (EU: https://jobs.eu.lever.co/...)palantir
Ashbyhttps://jobs.ashbyhq.com/linearlinear

Not sure about the slug? Paste the career page URL into Career page URLs and the platform is detected for you.

Run it with an empty input and you get a small demo: 3 jobs each from GitLab, Palantir and Linear (9 jobs, about $0.01).

FieldTypeDescription
greenhouselist of stringsGreenhouse board slugs (URLs accepted)
leverlist of stringsLever site names (EU boards detected automatically)
ashbylist of stringsAshby job board names
careerPageUrlslist of stringsAny mix of career page URLs, platform auto-detected
outputModejobs / companySignalsOne row per job (default) or one row per company with hiring signals
onlyNewbooleanOutput only jobs not returned in previous runs (default false)
stateIdstringName of the feed, to keep several independent feeds (default default)
includeUnchangedCompaniesbooleanCompany signals + only new: also output companies with no change (default false)
titleKeywordslist of stringsKeep jobs whose title contains any of these words (case-insensitive)
locationKeywordslist of stringsKeep jobs whose location or country contains any of these words
remoteOnlybooleanKeep only remote jobs
maxJobsPerCompanyintegerCap per company, most recent first (0 = no cap). Jobs mode only
descriptionFormattext / html / noneJob description as plain text (default), original HTML, or omitted

Example input

{
"careerPageUrls": [
"https://job-boards.greenhouse.io/gitlab",
"https://jobs.lever.co/zoox",
"https://jobs.ashbyhq.com/ramp"
],
"titleKeywords": ["engineer"],
"maxJobsPerCompany": 2,
"descriptionFormat": "text"
}

Output

One item per job. All platforms share the same fields; a field is null when the ATS does not publish it.

Real output of the example above (run on 2026-10-23, description shortened):

{
"id": "ashby:ramp:29a5da77-37f0-402a-92bc-072778e77ed8",
"platform": "ashby",
"companySlug": "ramp",
"jobId": "29a5da77-37f0-402a-92bc-072778e77ed8",
"title": "Software Engineer, Forward Deployed",
"companyName": "ramp",
"department": "Engineering",
"team": "Engineering",
"location": "New York, NY (HQ)",
"locations": ["New York, NY (HQ)", "San Francisco, CA"],
"country": "USA",
"remote": false,
"workplaceType": "hybrid",
"employmentType": "full-time",
"salaryMin": 168000,
"salaryMax": 285000,
"salaryCurrency": "USD",
"salaryInterval": "year",
"salaryText": "$168K - $285K",
"url": "https://jobs.ashbyhq.com/ramp/29a5da77-37f0-402a-92bc-072778e77ed8",
"applyUrl": "https://jobs.ashbyhq.com/ramp/29a5da77-37f0-402a-92bc-072778e77ed8/application",
"postedAt": "2026-10-22T19:20:16Z",
"updatedAt": null,
"description": "ABOUT RAMP\n\nRamp is building the smart infrastructure for finance teams...",
"isNew": null,
"scrapedAt": "2026-10-23T19:00:47Z"
}
{
"id": "lever:zoox:09924dfa-16b4-415a-828e-4ae7d903ecc2",
"platform": "lever",
"title": "Senior Radar Engineer",
"department": "Advanced Hardware Engineering",
"team": "Sensor Engineering",
"location": "Foster City, CA",
"country": "US",
"workplaceType": "onsite",
"employmentType": "full-time",
"salaryMin": 199999,
"salaryMax": 271000,
"salaryCurrency": "USD",
"salaryInterval": "year",
"salaryText": "USD 199,999 - 271,000 per year",
"url": "https://jobs.lever.co/zoox/09924dfa-16b4-415a-828e-4ae7d903ecc2",
"postedAt": "2026-10-22T20:15:21Z"
}
{
"id": "greenhouse:gitlab:8899972002",
"platform": "greenhouse",
"companyName": "GitLab",
"title": "Engineering Manager, Tenant Scale: Gitaly",
"department": "Tenant Scale Engineering",
"location": "Remote, United Kingdom",
"locations": ["Remote, United Kingdom", "United Kingdom"],
"remote": true,
"workplaceType": "remote",
"url": "https://job-boards.greenhouse.io/gitlab/jobs/8899972002",
"postedAt": "2026-10-23T16:05:57Z",
"updatedAt": "2026-10-23T16:05:57Z"
}

Which fields each ATS fills

Measured on 3,615 real jobs from 12 companies (4 per platform) on 2026-10-23:

FieldAshby (1,144 jobs)Lever (635)Greenhouse (1,836)
postedAt100%100%100%
department100%51%100%
employmentType100%99%not published
workplaceType74%100%inferred from location ("remote")
country100%100%not published
salary min/max70%35%not published as a field

Run summary

Each run also stores RUN_SUMMARY in the key-value store: status per company (ok / error / skipped), number of open jobs, jobs that matched your filters, jobs delivered, and in only-new mode the number of new and closed jobs since the previous run. Wrong slugs get a clear message, for example:

Board "acme" not found on ashby (check the slug in the career page URL; the company may have changed ATS)

Only new jobs (feed mode)

  1. Turn on Only new jobs since the last run.
  2. The first run returns all open jobs: that is your baseline.
  3. Schedule the Actor (for example daily). Each next run returns only jobs that were not there before.

The list of already-seen jobs is kept in a named key-value store called ats-jobs-feed-state in your Apify account (the Actor needs only the standard, limited permissions). Use a different Feed name (stateId) to run independent feeds, for example one per client. If a run stops because you reached your maximum cost per run, the jobs that were not delivered are not marked as seen: you get them on the next run.

Hiring signals: one row per company

Sometimes you don't want 700 job postings, you want to know what a company is doing: is it building a sales team, hiring its first marketing lead, slowing down? Set Output to Company hiring signals ("outputMode": "companySignals") and you get one row per company instead of one row per job.

I added this because, for sales teams and recruiters, the job list is only the raw material: the real question is "who is hiring SDRs right now?" or "which of my accounts just opened a VP of Sales role?". Each row tells you:

  • Open roles by function: sales, customerSuccess, marketing, engineering, data, product, design, people, finance, legal, operations, other.
  • Role types worth a call: SDR/BDR, account executives, sales leadership, engineering leadership, any leadership (VP, Head of, Director, C-level), internships.
  • Fresh roles: published in the last 7 and 30 days (from the publication date the ATS gives), and which functions they are in.
  • Where: share of remote roles, hybrid roles, top locations, countries and departments.
  • The 10 most recently published roles, with links.
  • A hiring score from 0 to 100, with the math next to it (see below).

Your filters still apply: with titleKeywords: ["SDR", "BDR", "sales development"] the row counts only those roles, so the score answers "how hard is this company hiring SDRs?".

The hiring score, explained

No black box. The score is the sum of 4 parts, and every row contains scoreBreakdown with the points and the reason:

PartMaxHow it is computed
volume30open roles: 1-4 = 5, 5-19 = 10, 20-49 = 18, 50-149 = 24, 150+ = 30
freshness30share of open roles published in the last 30 days; 50% or more = 30, linear below
velocity25roles published in the last 7 days: 1-2 = 5, 3-5 = 10, 6-14 = 15, 15-29 = 20, 30+ = 25
leadership and go-to-market153 points per leadership role + 1 per sales role, up to 15

Level: 0-24 low, 25-49 moderate, 50-74 high, 75-100 very high. Big companies naturally score higher on volume; sort by newLast7Days or by a single part of scoreBreakdown if you care about momentum only.

Functions come from simple keyword rules on the job title (then the department, then the team). They are right most of the time, not always: "Solutions Engineer" counts as sales (pre-sales), "Support Engineer" as customerSuccess, "Data Engineer" as engineering. If you see a role in the wrong bucket, open an issue with the title and I'll fix the rule.

What changed since the last run

Turn on Only new jobs since the last run together with company signals, schedule it daily or weekly, and each row also tells you:

  • newSinceLastRun and newRolesSinceLastRun: roles that appeared (title, function, location, link);
  • closedSinceLastRun and closedRolesSinceLastRun: roles that disappeared (filled, paused or pulled);
  • firstRun: true on the first run, which is the baseline.

A company with no change since the last run is not output and costs nothing (you still see it in RUN_SUMMARY). Want a row for every company on every run anyway? Turn on Company signals: also output companies with no change. The memory for company signals is separate from the one for jobs, so you can run both modes with the same feed name. If you change the filters, use a new Feed name, otherwise the next run will see the change as opened/closed roles.

Example

{
"greenhouse": ["gitlab", "anthropic", "stripe"],
"lever": ["palantir", "zoox"],
"ashby": ["ramp", "linear", "notion"],
"outputMode": "companySignals",
"onlyNew": true,
"stateId": "weekly-accounts"
}

Real output for Ramp from a run on 2026-10-24 (lists shortened):

{
"recordType": "companySignal",
"id": "ashby:ramp",
"platform": "ashby",
"companySlug": "ramp",
"careersUrl": "https://jobs.ashbyhq.com/ramp",
"openJobsTotal": 167,
"jobsAnalyzed": 167,
"hiringScore": 77,
"hiringLevel": "very high",
"scoreBreakdown": [
{"part": "volume", "points": 30, "max": 30, "why": "167 open roles (1-4 = 5, 5-19 = 10, 20-49 = 18, 50-149 = 24, 150+ = 30)"},
{"part": "freshness", "points": 17, "max": 30, "why": "28% of open roles published in the last 30 days (50%+ = full points)"},
{"part": "velocity", "points": 15, "max": 25, "why": "11 roles published in the last 7 days (1-2 = 5, 3-5 = 10, 6-14 = 15, 15-29 = 20, 30+ = 25)"},
{"part": "leadershipAndGtm", "points": 15, "max": 15, "why": "8 leadership roles x 3 + 55 sales roles x 1"}
],
"byFunction": {"sales": 55, "engineering": 36, "customerSuccess": 17, "finance": 13, "people": 10, "product": 10, "marketing": 9, "data": 7, "legal": 4, "design": 3, "operations": 3},
"roleTypes": {"sdrBdr": 11, "accountExecutive": 10, "salesLeadership": 1, "engineeringLeadership": 0, "leadership": 8, "internship": 5},
"newLast7Days": 11,
"newLast30Days": 46,
"newLast30DaysByFunction": {"sales": 13, "engineering": 6, "customerSuccess": 5, "finance": 4, "legal": 4, "product": 4, "marketing": 3, "people": 3, "data": 2, "design": 2},
"remoteJobs": 13,
"hybridJobs": 137,
"remoteShare": 0.08,
"topLocations": [{"name": "New York, NY (HQ)", "jobs": 130}, {"name": "London, UK", "jobs": 12}, {"name": "San Francisco, CA", "jobs": 10}],
"topDepartments": [{"name": "Sales", "jobs": 69}, {"name": "Engineering", "jobs": 37}, {"name": "People & Talent", "jobs": 14}],
"newestPostedAt": "2026-10-23T19:41:17Z",
"latestRoles": [
{"title": "GTM Senior Business Systems Analyst, Marketing & Pre-Sales", "function": "sales", "location": "New York, NY (HQ)", "postedAt": "2026-10-23T17:17:16Z", "url": "https://jobs.ashbyhq.com/ramp/aa433e44-f095-484b-a46a-a330583d84b0"}
],
"newSinceLastRun": null,
"closedSinceLastRun": null,
"firstRun": true,
"scrapedAt": "2026-10-24T12:48:25Z"
}

Same run, all 9 companies in 17-70 seconds: GitLab 100, Stripe 89, Anthropic 87, Ramp 77, Zoox 75, Notion 71, Palantir 60, Linear 57. Mistral's Lever board exists but had 0 jobs (the company may have moved to another ATS): it is reported in the row and in RUN_SUMMARY, not counted as an error.

Pricing

Pay per event:

  • $1.50 per 1,000 jobs delivered to the dataset.
  • Company hiring signals: $0.01 per company ($0.0015 result + $0.0085 company signal). Companies with no change in only-new mode are free.
  • A tiny Actor start fee set by Apify (default $0.00005 per run).

Empty boards, wrong slugs and filtered-out jobs are free. In only-new mode you pay only for the new jobs, and for company signals only for the companies that changed. Use Max jobs per company or the maximum cost per run in Apify to cap your spend.

Speed and limits

  • About 1 second per company page (Lever returns 100 jobs per page). 12 companies and 3,615 jobs took 20 seconds in our test.
  • Requests are throttled to at most 1 per second per ATS host, with automatic retries and backoff on errors and rate limits.
  • Up to 500 companies per run.
  • Greenhouse boards hosted in the EU (job-boards.eu.greenhouse.io) are not supported: Greenhouse has no public EU Job Board API host.
  • Only jobs that companies publish publicly are returned. Internal postings and unlisted Ashby jobs are excluded.

The Actor reads only the public, documented job board endpoints:

  • Greenhouse Job Board API: "Job Board data is publicly available, so authentication is not required for any GET endpoints."
  • Lever Postings API: "all job postings in the published state are publicly viewable. These jobs may be scraped by third parties."
  • Ashby Public Job Posting API, documented at developers.ashbyhq.com.

It does not collect personal data such as recruiter names or e-mails. You are responsible for how you use the data; respect the terms of the companies whose postings you republish.

FAQ

Where do I find the slug? Open the company's careers page, click a job, and look at the URL: boards.greenhouse.io/<slug>, jobs.lever.co/<slug>, jobs.ashbyhq.com/<slug>. Or just paste the URL into Career page URLs.

A company returns 0 jobs. The board exists but has nothing published. The company may have moved to another ATS: check its career page URL.

Why is a role in the wrong function? Functions come from keyword rules on the title. Open an issue with the title and I'll adjust the rule.

Workday, SmartRecruiters, Workable? Not yet. Open an issue with the companies you need.

Found a problem or need a feature? Open an issue on the Issues tab with your input (no personal data). I read every issue myself and usually reply within 48 hours. Requests for new platforms are very welcome: they decide what I build next.


Thanks for trying it! If it saves you time, a short review on the Store helps a lot. 🙏