ATS Jobs Scraper | Greenhouse, Lever and Ashby avatar

ATS Jobs Scraper | Greenhouse, Lever and Ashby

Pricing

from $3.40 / 1,000 results

Go to Apify Store
ATS Jobs Scraper | Greenhouse, Lever and Ashby

ATS Jobs Scraper | Greenhouse, Lever and Ashby

Search job listings published on company career sites running Greenhouse, Lever, Ashby, SmartRecruiters, or Recruitee. Filter by keyword, location, remote status, and posting date, and get full job descriptions with stable IDs, ideal for job boards, recruiters, and sales hiring signal tracking.

Pricing

from $3.40 / 1,000 results

Rating

0.0

(0)

Developer

SilentFlow

SilentFlow

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

a day ago

Last modified

Share

ATS Jobs Scraper

Search the jobs companies publish on their own career sites, by keyword, location and date, without knowing which companies to look at. One input, five hiring systems (Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee), full descriptions included. A keyword search returns matching jobs in seconds, not after an afternoon of career page checks.

How it works

How it works

  1. Enter keywords, a location, a date window or a list of companies.
  2. The scraper searches a daily rebuilt index of jobs published on company career sites.
  3. Every returned job comes back as one structured row, with its full description fetched live.

โœจ Why teams choose this over other ATS scrapers

Still finding out about openings after everyone else? Tired of aggregators that lag by days and cut descriptions short? Do you know which hiring system each company uses? Nobody does, and you should not have to.

  • ๐Ÿ”Ž Search without naming a company. Type backend engineer and Berlin and get every matching job across every indexed company. Other career site scrapers need the company name and its system first.
  • ๐Ÿงฉ Five systems, one set of fields. Greenhouse, Lever, Ashby, SmartRecruiters and Recruitee jobs come back with the same 14 fields, so one script handles all of them.
  • ๐Ÿ“„ Full descriptions, fetched live. The description is pulled from the career site during the run, never from a stale copy. In the reference run, 22 of 25 jobs came back with their complete description.
  • ๐Ÿ†” Stable IDs and permanent URLs. platformId is the employer's own job ID and url is the career site page, so deduplication and archiving just work.
  • ๐Ÿ“… Fresh by design. The index is rebuilt every day and results are sorted newest first, with a postedDate in RFC 3339 for every job.
  • ๐ŸŒ Country codes on every job. countryCode is normalized to ISO codes and isRemote is set from the employer's own flag, so filtering by geography takes one line.
  • ๐Ÿšซ No login, no API key. Career site data is public. You start a run and get rows.

๐ŸŽฏ What you can do with ATS job data

TeamWhat they build
Job boardsA niche board fed with jobs that reach aggregators days later, refreshed every morning
Recruiting agenciesA daily list of new openings matching their placements, with the employer's own job ID to avoid double outreach
SalesHiring signals: which companies opened engineering, sales or finance roles this week, by country
InvestorsHeadcount velocity per portfolio company or target, tracked from their own career sites
Career coachesRemote roles for a skill, posted in the last 3 days, with full descriptions for tailoring applications
HR analyticsTime to fill and posting patterns per platform, department and country
Newsletter authorsA weekly digest of new remote jobs in one function, generated from a single run

๐Ÿ“ฅ Input parameters

FieldTypeDefaultWhat it does
keywordsarray of stringsnoneWords matched against the job title and department. Any one keyword matching is enough.
locationstringnoneCity, region or country. A country name also matches its country code.
remoteOnlybooleanfalseKeep only jobs the employer flagged as remote.
companiesarray of stringsnoneRestrict the search to these company names as they appear on their career site.
postedSince24h, 3d, 7d, 30d, any30dOnly jobs published within this window. any returns every open job.
platformsarray of greenhouse, lever, ashby, smartrecruiters, recruiteeall fiveRestrict the search to these systems.

Output control

FieldTypeDefaultWhat it does
maxItemsinteger100Maximum number of jobs to return, newest first.
includeDescriptionbooleantrueFetch the full description of every returned job. Turn off for faster, lighter runs.
debugModebooleanfalseVerbose diagnostics in the log.

Leave every field empty to get the freshest jobs across all indexed companies.

๐Ÿ“Š Output data

Every job is one row. With includeDescription on:

{
"platform": "greenhouse",
"slug": "stripe",
"platformId": "7954688",
"title": "Engineering Manager, Abuse Control Engineering",
"company": "Stripe",
"location": "Seattle, SF, NYC, Remote in the US",
"countryCode": "US",
"isRemote": true,
"department": "Engineering",
"postedDate": "2026-09-02T17:12:35Z",
"url": "https://boards.greenhouse.io/stripe/jobs/7954688",
"description": "Who we are. About Stripe. Stripe is a financial infrastructure platform for businesses...",
"scrapedAt": "2026-09-16T16:23:49Z",
"dataType": "job"
}

With includeDescription off, the same row without the description field:

{
"platform": "lever",
"slug": "spotify",
"platformId": "3c2b0a55-1e2f-4d7a-9c11-2b5a0c1d9e77",
"title": "Backend Engineer, Personalization",
"company": "spotify",
"location": "Stockholm",
"countryCode": "SE",
"isRemote": false,
"department": "Engineering",
"postedDate": "2026-09-10T08:41:12Z",
"url": "https://jobs.lever.co/spotify/3c2b0a55-1e2f-4d7a-9c11-2b5a0c1d9e77",
"scrapedAt": "2026-09-16T16:23:49Z",
"dataType": "job"
}

๐Ÿ—‚๏ธ Data fields

14 fields per job. description is the only one that can be missing, when the career site does not serve it at run time.

CategoryFieldTypeNotes
Identityplatformstringgreenhouse, lever, ashby, smartrecruiters or recruitee
IdentityslugstringThe company's identifier on its hiring system
IdentityplatformIdstringThe employer's own job ID, stable across runs
JobtitlestringJob title as published
JobcompanystringCompany name as shown on the career site
JobdepartmentstringDepartment or team, when the employer sets one
JobdescriptionstringFull description as plain text, fetched live
PlacelocationstringLocation text as published
PlacecountryCodestringISO 3166 two letter code, other when the employer gives none
PlaceisRemotebooleanThe employer's own remote flag
TimepostedDatestringRFC 3339 timestamp of the publication
TimescrapedAtstringRFC 3339 timestamp of the run
LinksurlstringPermanent job page on the career site
MetadataTypestringAlways job

๐Ÿš€ Examples

Get the newest jobs everywhere

{
"maxItems": 100
}

Find remote Go jobs posted this week

{
"keywords": ["golang", "go engineer"],
"remoteOnly": true,
"postedSince": "7d",
"maxItems": 200
}

Watch every opening at a list of companies

{
"companies": ["stripe", "ramp", "spotify"],
"postedSince": "any",
"includeDescription": false,
"maxItems": 1000
}

Sales roles in the United Kingdom, Greenhouse and Lever only

{
"keywords": ["account executive", "sales development"],
"location": "United Kingdom",
"platforms": ["greenhouse", "lever"],
"postedSince": "30d",
"maxItems": 300
}

Yesterday's engineering jobs, titles only, for a daily digest

{
"keywords": ["engineer", "developer"],
"postedSince": "24h",
"includeDescription": false,
"maxItems": 500
}

Data roles in Germany, remote or on site, with full descriptions

{
"keywords": ["data engineer", "data scientist", "analytics"],
"location": "Germany",
"postedSince": "3d",
"includeDescription": true,
"maxItems": 150
}

๐Ÿค– Copy to your AI assistant

Paste this block into Claude, ChatGPT or Cursor to give it full context about this scraper:

You have access to the ATS Jobs Scraper on Apify: silentflow/ats-jobs-scraper
Input schema:
- keywords (array of strings): words matched against job title and department, any match is enough
- location (string): city, region or country
- remoteOnly (boolean, default false)
- companies (array of strings): restrict to these company slugs
- postedSince (string, one of 24h | 3d | 7d | 30d | any, default 30d)
- platforms (array of strings, values greenhouse | lever | ashby | smartrecruiters | recruitee, default all)
- maxItems (integer, default 100): newest jobs first
- includeDescription (boolean, default true): fetch the full description live
- debugMode (boolean, default false)
Output per job (14 fields):
- platform, slug, platformId (strings, stable identity of the job on its hiring system)
- title, company, department, description (strings; description may be absent)
- location (string), countryCode (ISO 3166 code or "other"), isRemote (boolean)
- postedDate, scrapedAt (RFC 3339 strings)
- url (permanent job page), dataType ("job")
No login or API key is needed. Use apify-client for Python or JavaScript.

๐Ÿ’ป Integrations

Feed a job board with fresh remote roles (Python)

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("silentflow/ats-jobs-scraper").call(run_input={
"keywords": ["frontend", "react"],
"remoteOnly": True,
"postedSince": "3d",
"maxItems": 300,
})
jobs = list(client.dataset(run["defaultDatasetId"]).iterate_items())
# keep one row per employer job ID, newest first, and hand it to your board
seen, fresh = set(), []
for job in sorted(jobs, key=lambda j: j["postedDate"], reverse=True):
key = (job["platform"], job["platformId"])
if key not in seen:
seen.add(key)
fresh.append({"title": job["title"], "company": job["company"], "url": job["url"], "posted": job["postedDate"]})
print(f"{len(fresh)} new remote frontend jobs")

Turn openings into hiring signals for sales (JavaScript)

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const { defaultDatasetId } = await client.actor('silentflow/ats-jobs-scraper').call({
keywords: ['sales', 'account executive', 'revenue'],
postedSince: '7d',
includeDescription: false,
maxItems: 1000,
});
const { items } = await client.dataset(defaultDatasetId).listItems();
// companies that opened three or more sales roles this week, by country
const counts = {};
for (const job of items) {
const key = `${job.company} (${job.countryCode})`;
counts[key] = (counts[key] || 0) + 1;
}
const hot = Object.entries(counts).filter(([, n]) => n >= 3).sort((a, b) => b[1] - a[1]);
console.log(hot.slice(0, 20));

Export a company watchlist to CSV every morning (Apify CLI)

apify call silentflow/ats-jobs-scraper --input '{"companies":["stripe","ramp"],"postedSince":"24h","includeDescription":false,"maxItems":500}' --wait
apify datasets get-items --format csv > openings-$(date +%F).csv

Schedule the same input from the Apify Console and receive the CSV by webhook or in your bucket.

๐Ÿ“ˆ Performance

MetricValue
Time to first results2 to 3 seconds after the run starts
Descriptionsfetched in parallel, most runs finish in under a minute for a few hundred jobs
Description coverage22 of 25 jobs in the reference run
Freshnessindex rebuilt daily, descriptions live at run time
Results per runno fixed limit, maxItems is yours to set

๐Ÿ’พ Data export

Every run's dataset is available as JSON, CSV, Excel, XML, HTML table or RSS from the run's dataset page, or straight from the API:

https://api.apify.com/v2/datasets/{DATASET_ID}/items?format=csv&token=YOUR_TOKEN

Swap csv for json, xlsx or xml. The same URL works from Google Sheets, Make, Zapier or a cron job.

๐Ÿ’ก Tips for best results

  1. Combine a keyword with a location or a date window. engineer alone matches hundreds of jobs; engineer plus Netherlands plus 7d gives you a list you can act on.
  2. Turn off includeDescription for monitoring runs. Titles, companies and dates are enough to detect new openings; fetch descriptions only when you need the text.
  3. Deduplicate on platform plus platformId. The pair is the employer's own identity for the job and does not change between runs.
  4. Use postedSince: "any" for a full snapshot of a company. The default 30 day window is meant for fresh jobs, not for a complete catalogue.
  5. Match companies to the slug on the career site. It is the identifier in the career page URL, for example stripe in boards.greenhouse.io/stripe.

โ“ FAQ

What exactly does this scraper return? Jobs published by employers on their own career sites through Greenhouse, Lever, Ashby, SmartRecruiters or Recruitee, with 14 fields per job including the full description.

Do I need an account, a key or a login? No. Career site listings are public. You give an input and get rows.

How fresh is the data? The index of jobs is rebuilt every day. Descriptions are fetched live from the career site during your run, so the text you get is the text currently online.

Which companies are covered? Companies that publish their jobs through one of the five supported systems and are part of the index. Coverage grows as new career sites are added. To check a specific company, run a search with companies set to its slug and postedSince set to any.

Can I search several keywords at once? Yes. keywords is a list and any one match is enough. Add location, platforms or remoteOnly to narrow the result.

How do filters combine? All filters apply together. keywords: ["engineer"] plus location: "Germany" plus postedSince: "3d" plus remoteOnly: true returns remote engineering jobs in Germany published in the last three days.

Why is description missing on some jobs? A small share of career pages do not serve the description at run time. The job row still ships with its title, company, location, date and URL.

Is the url permanent? Yes. It is the job page on the company's career site, which stays valid as long as the job is open. platformId stays the same across runs.

Why does countryCode say other? The employer did not give a recognizable country in the location text. The location field still has what they wrote.

What about Workday, Taleo or SAP SuccessFactors? Not covered yet. The scraper focuses on the five systems above, which share the same public structure.

Is this legal? The scraper reads job listings that employers publish for the public. See the Legal section below for your obligations.

This Actor extracts publicly available job listings from company career sites. It does not bypass any login, paywall or CAPTCHA. Users are responsible for complying with the terms of service of the sites they collect from and with applicable data protection laws (GDPR, CCPA, and PIPL where relevant). Job listings are company data; they do not contain candidate profiles or personal data. The data returned is informational; verify accuracy for regulated use cases.

๐Ÿ“ฌ Support

Need something this scraper doesn't do yet? We ship features fast.

  • Feature requests go straight to our backlog
  • Enterprise needs? We do custom integrations and high-volume plans
  • Pricing questions? Check the Monetization tab on the actor page

Response time: usually under 24 hours.

Check out our other scrapers: silentflow on Apify