ATS Jobs Scraper & Hiring Signals - Greenhouse, Lever, Ashby avatar

ATS Jobs Scraper & Hiring Signals - Greenhouse, Lever, Ashby

Pricing

from $5.00 / 1,000 job scrapeds

Go to Apify Store
ATS Jobs Scraper & Hiring Signals - Greenhouse, Lever, Ashby

ATS Jobs Scraper & Hiring Signals - Greenhouse, Lever, Ashby

Turn company domains into live hiring data. Auto-detects Greenhouse, Lever, Ashby, SmartRecruiters, Workable, Recruitee and Breezy, then returns every open role plus a scored hiring-signal report per company: open roles, new postings, momentum and team breakdowns.

Pricing

from $5.00 / 1,000 job scrapeds

Rating

0.0

(0)

Developer

Amit Mudaliyar

Amit Mudaliyar

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

ATS Jobs Scraper & Hiring Signals — Greenhouse, Lever, Ashby, Workday & more

Give it a list of company domains. Get back every open job they're advertising — plus a scored hiring-signal report for each company.

No board tokens to look up. No LinkedIn scraping. No proxies. You paste stripe.com, this Actor works out that Stripe hires on Greenhouse, pulls all 569 open roles from the official public board API, and hands you clean, normalized, enriched data.

Nine ATS platforms supported, including Workday — so the large enterprises that Greenhouse and Lever don't cover are in scope too.

Input: ["stripe.com", "openai.com", "figma.com"]
Output: 1,468 open jobs + 3 hiring-signal reports

Why this beats a job-board scraper

Most job scrapers fight LinkedIn or Indeed for the same public postings, get rate-limited, and hand you whatever survived. This Actor goes to the source: the official, public, unauthenticated job-board APIs that Greenhouse, Lever, Ashby, SmartRecruiters, Workable, Recruitee, Breezy, Workday and Personio publish so companies can embed job lists on their own careers pages.

That means:

  • It doesn't break. No headless browsers, no anti-bot arms race, no proxy bills.
  • It's complete. You get the company's real, current req list — not a stale aggregator index.
  • It's fast. Hundreds of jobs per company in well under a second.
  • It's first-party data. Straight from the system the recruiter actually posts into.

What you can do with it

Sales & GTM — hiring is the strongest public buying signal there is. A company that just opened 12 sales roles is building a sales org, and needs sales tooling now. Feed your target account list in, sort by signalScore, and work the top of the list.

Recruiting & talent intelligence. Track competitor headcount plans, spot teams that are scaling, find live reqs the moment they're posted.

Investors & market research. Hiring velocity is a leading indicator. newJobsLast30Days and momentum tell you who's accelerating before it shows up anywhere else.

Job boards & aggregators. Build a niche board on clean, first-party listings with working apply links.

AI agents & RAG. Turn on includeDescription for full job text, ready to embed.

Pairs with Tech Stack Lookup — this Actor tells you who a company is hiring; that one tells you what they buy, detecting their AI tools, CRM, security and analytics vendors from public DNS records. Same domain list in, two halves of the same account picture out.


Input

The only required field is companies. Everything else is an optional filter.

{
"companies": ["stripe.com", "openai.com", "anthropic.com"],
"jobFunctions": ["engineering", "ai-data-science"],
"workplaceType": "remote",
"postedWithinDays": 14,
"includeHiringSignals": true
}

Ways to name a company

FormatExampleNotes
Domainstripe.comRecommended. ATS auto-detected.
Company nameStripeWorks when the name matches the board token.
Explicit boardgreenhouse:stripeSkips detection — fastest and exact.

Use the explicit form (ats:slug) when a company's board token differs from its domain, or when you want to guarantee zero detection overhead.

Key options

OptionDefaultWhat it does
companiesrequiredDomains, names, or ats:slug pairs.
keywords[]Keep jobs whose title contains any of these.
excludeKeywords[]Drop jobs whose title contains any of these.
locations[]Substring match on location, e.g. "London".
jobFunctions[]engineering, ai-data-science, sales, design, …
seniorityLevels[]executive, vp, director, principal, manager, senior, mid, junior, intern.
workplaceTypeanyremote, hybrid, or onsite.
postedWithinDays0Only jobs posted in the last N days.
includeDescriptionfalseAdds full job text + HTML.
includeHiringSignalstrueAdds one analytics report per company.
outputJobstrueTurn off to score a large account list cheaply.

Tip: To score 500 accounts for buying intent as cheaply as possible, set outputJobs: false and includeHiringSignals: true. You get one compact scored row per company instead of thousands of job rows.


Output

Two record types land in the same dataset, tagged by a type field. The dataset has prebuilt Open jobs and Hiring signals views so you can flip between them in the UI.

type: "job"

{
"type": "job",
"companyName": "Figma",
"companyDomain": "figma.com",
"ats": "greenhouse",
"boardUrl": "https://job-boards.greenhouse.io/figma",
"jobId": "5364702004",
"title": "Account Executive, Emerging Enterprise (Berlin, Germany)",
"jobFunction": "sales",
"seniority": "mid",
"department": "Sales",
"location": "Berlin, Germany",
"country": "DE",
"workplaceType": "onsite",
"isRemote": false,
"employmentType": null,
"salaryRaw": null,
"postedAt": "2024-11-01T10:05:10.000Z",
"daysSincePosted": 657,
"applyUrl": "https://boards.greenhouse.io/figma/jobs/5364702004",
"scrapedAt": "2026-08-20T23:21:48.626Z"
}

jobFunction, seniority, workplaceType and country are derived by this Actor — ATS platforms don't provide them consistently, so they're inferred from the title and location. That's what makes the data filterable and comparable across companies.

type: "hiring-signal"

One per company — the part you can't get from a plain scraper:

{
"type": "hiring-signal",
"companyName": "Notion",
"companyDomain": "notion.so",
"ats": "ashby",
"totalOpenJobs": 128,
"newJobsLast7Days": 11,
"newJobsLast30Days": 44,
"medianPostingAgeDays": 38,
"signalScore": 81,
"momentum": "steady",
"remoteJobs": 12,
"remoteShare": 0.09,
"executiveOpenings": 2,
"engineeringJobs": 51,
"salesJobs": 23,
"aiDataScienceJobs": 9,
"jobsByFunction": { "engineering": 51, "sales": 23, "…": 0 },
"jobsBySeniority": { "mid": 70, "senior": 24, "…": 0 },
"jobsByCountry": { "US": 96, "UK": 12, "…": 0 },
"jobsByDepartment": { "Engineering": 44, "Go To Market": 31 },
"topLocations": { "San Francisco": 61, "New York City": 22 }
}

signalScore (0–100) blends hiring volume with recency. A company with 40 open roles where half were posted this month scores far higher than one sitting on 40 stale reqs. momentum is a plain-language read: accelerating, steady, stale, or not-hiring.


Supported ATS platforms

ATSDetectionCoverage
GreenhouseAuto from domainFull board + departments
AshbyAuto from domainFull board + native remote/hybrid flags
LeverAuto from domainFull board
SmartRecruitersAuto from domainFull board, paginated to 2,000 roles
WorkableAuto from domainFull board
RecruiteeAuto from domainFull board
Breezy HRAuto from domainFull board
WorkdayBoard URL requiredUp to 1,000 roles per board
PersonioAuto from domainBest effort — see below

Workday — pass the board URL

Workday powers most large enterprises, and it's supported — but it can't be auto-detected from a domain. Workday boards are addressed by three parts (tenant, data centre, site), and big careers pages are JavaScript-rendered, so the board reference isn't in the HTML. Detecting it would require a headless browser, which is exactly what keeps this Actor fast and reliable.

So give it the board URL, which you can copy from the company's careers page:

{
"companies": [
"https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
"workday:salesforce/wd12/External_Career_Site"
]
}

Both forms work. Two Workday caveats worth knowing:

  • Posting dates are approximate. Workday reports age as prose ("Posted 30+ Days Ago") rather than a timestamp, so dates are reconstructed. Those rows carry postedAtIsApproximate: true; every other ATS reports exact dates.
  • Locations are sometimes given as an aggregate ("5 Locations"). That label is kept in locationSummary, and one real location is recovered from the job URL.

Personio — best effort

Personio serves a clean XML feed, but many tenants sit behind a WAF that blocks non-browser traffic. When that happens the company is simply reported as unresolved — and you aren't charged. Treat Personio coverage as a bonus, not a guarantee.


Companies that don't resolve are listed in the run summary under unresolvedCompanies, each with a specific reason — and you are never charged for them.

How detection works

  1. Slug guess. stripe.com → try stripe against each ATS. One request, and a hit is self-verifying because the API returns the jobs directly. This resolves the large majority of companies.
  2. Careers-page discovery. If that misses, the Actor fetches the company's /careers page and looks for an embedded board link (boards.greenhouse.io/…, jobs.lever.co/…, and friends).

Pricing

Pay per event — you're billed for delivered results, not for compute time:

EventWhat triggers it
company-resolvedA company was successfully matched to a live ATS board.
job-scrapedOne job row delivered to your dataset.
hiring-signalOne company analytics report delivered.

Companies that can't be resolved cost you nothing. Set Max total charge on the run to cap spend on any single run.


Run it from code

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('amitmudaliyar/company-jobs-hiring-signals').call({
companies: ['stripe.com', 'openai.com', 'figma.com'],
jobFunctions: ['engineering'],
postedWithinDays: 30,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const hot = items
.filter((i) => i.type === 'hiring-signal')
.sort((a, b) => b.signalScore - a.signalScore);
console.table(hot.map(({ companyName, totalOpenJobs, newJobsLast7Days, signalScore }) =>
({ companyName, totalOpenJobs, newJobsLast7Days, signalScore })));

Notes on data

  • Only public job postings are collected — the same listings any visitor sees on the company's careers page. No logins, no personal data, no candidate information.
  • postedAt is the ATS's own first-published date. Long-lived evergreen reqs legitimately show large daysSincePosted values; use postedWithinDays to filter for fresh activity.
  • Hiring-signal reports always describe the company's whole board, so scores stay comparable even when you apply job filters.

Support

Found a company that should resolve but doesn't, or want another ATS supported? Open an issue on the Actor's Issues tab with the company domain — detection coverage improves with every report.


More from this creator

Three Actors, one account-intelligence picture — all built on official public APIs, no proxies:

ActorAnswers
ATS Jobs Scraper & Hiring Signals (this one)Who is a company hiring? Open roles from nine ATS platforms plus a scored hiring-momentum report.
Tech Stack LookupWhat does a company buy? AI tools, CRM, security and analytics vendors, detected from public DNS records.
App Store Intelligence & ASOHow does an app perform? Ratings, rankings and ASO across every country storefront.