Multi-ATS Jobs + Company Emails Scraper avatar

Multi-ATS Jobs + Company Emails Scraper

Pricing

from $2.50 / 1,000 jobs

Go to Apify Store
Multi-ATS Jobs + Company Emails Scraper

Multi-ATS Jobs + Company Emails Scraper

Live jobs from any company across 10 ATS platforms — Greenhouse, Lever, Ashby, Workday & more — fetched at run time, not served from a stale database. Paste URLs, company names, or a sheet; get one unified schema with full descriptions, plus the hiring company's contact email for lead gen.

Pricing

from $2.50 / 1,000 jobs

Rating

0.0

(0)

Developer

Muhamed Didovic

Muhamed Didovic

Maintained by Community

Actor stats

0

Bookmarked

27

Total users

23

Monthly active users

9 days ago

Last modified

Categories

Share

The fastest way to turn a list of companies into live, structured job data — plus a contact email for outreach. Point it at any company across 10 major ATS platforms — Greenhouse, Lever, Ashby, SmartRecruiters, Workday, Workable, Recruitee, Breezy, Personio, BambooHR — by board URL, bare company name, or an uploaded sheet of links. Every job is fetched live from the company's own ATS at run time, normalized to one schema, and optionally paired with the hiring company's public contact email.

Unlike pre-indexed job databases, nothing here is served from a cache: no stale postings, no missing companies, no "job not in our database yet." If the role is on the company's board right now, you get it.

How the Multi-ATS Jobs + Emails Scraper works


Why Use This Scraper?

  • Live results, not a stale database — every row is fetched from the company's ATS at the moment you run, so closed roles disappear and new roles appear instantly
  • 10 ATS platforms, one schema — Greenhouse, Lever, Ashby, SmartRecruiters, Workday, Workable, Recruitee, Breezy, Personio, BambooHR, all normalized so you write one parser
  • Any company, not a fixed index — job database APIs only cover companies they've already crawled; here you name the company and it's covered
  • ATS auto-detection — paste a bare company name and the actor probes the platforms to find its board; or paste any board URL and it routes by host
  • Company contact email — flip on enrichEmails to turn a job feed into a lead list with a best-effort public contact address per company
  • Filters applied before billing — title, keywords, location, department, remote, posted-after; you only pay for rows that match
  • Bulk input via spreadsheet — feed an Excel/CSV/Google Sheet of career links or company names for hands-off list processing

Overview

The Multi-ATS Jobs + Company Emails Scraper is built for recruiting teams, sales teams using hiring as a buying signal, and job-board or talent-intelligence builders who need structured job data straight from company career sites.

The output is job-shaped rows: one dataset row per open position. Whether you start from a board URL, a bare company name, or an uploaded sheet, the resulting dataset is a single stream of normalized job rows — tagged with inputIndex so rows stay traceable to the input that produced them.

Two things distinguish it from job-database APIs on the Store. First, coverage is whatever you ask for: databases can only return companies they already index, and their public issue trackers fill up with "this job is missing" reports — here there is no index to be missing from. Second, freshness is run-time: publishedAt, locations, and descriptions come from the ATS response at the moment of your run, not from the last crawl cycle.


Supported Inputs

ATS board URLs

ATSInput exampleNotes
Greenhousehttps://boards.greenhouse.io/stripe or stripeFull content inline
Leverhttps://jobs.lever.co/spotify or spotifyFull content inline
Ashbyhttps://jobs.ashbyhq.com/ramp or rampFull content inline
SmartRecruitershttps://careers.smartrecruiters.com/BoschGroup or BoschGroupCompany ID is case-sensitive
Workdayhttps://{tenant}.wd5.myworkdayjobs.com/{Site}URL only (needs tenant + site)
Workablehttps://apply.workable.com/pearltalent or pearltalentDetail fetched per job
Recruiteehttps://{company}.recruitee.com or {company}Full content inline
Breezyhttps://{company}.breezy.hr or {company}Description from posting page
Personiohttps://vodeno.jobs.personio.com or vodenoPublic XML feed
BambooHRhttps://soundstripe.bamboohr.com or soundstripeCareers API

Copy-pasteable startUrls

{
"startUrls": [
"https://boards.greenhouse.io/stripe",
"https://jobs.lever.co/spotify",
"https://jobs.ashbyhq.com/ramp"
]
}

Company-name mode (ATS auto-detected)

{
"organizations": ["stripe", "notion", "ramp"]
}

Spreadsheet mode

{
"inputUrl": "https://docs.google.com/spreadsheets/d/…/edit"
}

Cells may hold board URLs and/or bare company names; the sheet is parsed and merged with startUrls / organizations. All three modes can be mixed in one run.

Unsupported inputs

  • ❌ Job boards outside the 10 ATS platforms above (LinkedIn, Indeed, company sites with fully custom career pages)
  • ❌ "All companies on Greenhouse" — ATSs publish no public directory of boards; you supply the companies
  • ❌ Content behind a login wall or internal/private postings

Use Cases

AudienceUse case
Sales teamsHiring is a buying signal — pull open roles for target accounts and pair each with a contact email for outreach
Recruiting agenciesMonitor client and prospect boards live; catch new roles the day they open
Job boards & aggregatorsIngest fresh, structured roles from hundreds of companies without one integration per ATS
Talent-intelligence teamsHiring velocity, remote-vs-onsite mix, departments, and pay bands across a company portfolio
RevOps / CRM teamsAppend live hiring activity + a contact address to account lists on a schedule

How It Works

  1. Input — provide board URLs, bare company names, a spreadsheet of either, or any mix
  2. Detect — URLs route to their ATS by hostname; bare names are auto-detected by probing the supported platforms in order
  3. Fetch live — each company's jobs come from the ATS's own public API at run time (one call for inline ATSs; list + per-job detail for SmartRecruiters/BambooHR)
  4. Normalize & filter — every job is mapped to one common schema; title/keyword/location/department/remote/date filters run before billing
  5. Enrich & push (optional) — discover the company website, attach a public contact email, and push one row per job

Input Configuration

Input fields

FieldTypeDefaultDescription
startUrlsarrayATS board/job URLs (any of the 10 platforms)
organizationsarrayBare company names/slugs — ATS auto-detected
inputUrlstringPublic URL to an .xlsx / .csv / Google Sheet of career links or company names — parsed and merged with the lists
enrichEmailsbooleanfalseAttach company contactEmail + contactWebsite (lead-gen)
maxItemsinteger5000Hard cap on job rows across the whole run — use it to control billing
maxConcurrencyinteger10Companies processed in parallel
titleKeywordstringKeep only jobs whose title contains this text (case-insensitive)
keywordsstringKeep only jobs matching these keywords across title, detected skills, and description
locationstringKeep only jobs whose location contains this text, e.g. remote, London
departmentstringKeep only jobs whose department contains this text
employmentTypestringKeep only jobs whose employment type contains this stem, e.g. full
languagestringPreferred posting language (Personio returns it natively; SmartRecruiters filtered to it)
remoteOnlybooleanfalseKeep only jobs flagged remote
postedAfterstringKeep only jobs published on/after YYYY-MM-DD — ideal for scheduled monitoring
includeDescriptionbooleantrueOff = leaner rows (skips detail fetch for SmartRecruiters/BambooHR)
includeRawJsonbooleanfalseAttach the raw ATS payload under raw
proxyobjectLeave empty — traffic already routes through built-in residential proxy at no extra cost

Common scenarios

1. Lead-gen: engineering roles + contact emails for a target list

{
"organizations": ["stripe", "ramp", "vodeno"],
"enrichEmails": true,
"titleKeyword": "engineer",
"maxItems": 1000
}

2. Monitoring: only new roles since yesterday, lean rows

{
"startUrls": ["https://boards.greenhouse.io/stripe", "https://jobs.lever.co/spotify"],
"postedAfter": "2026-07-18",
"includeDescription": false
}

3. Bulk sheet of career links, remote roles only

{
"inputUrl": "https://docs.google.com/spreadsheets/d/…/edit",
"remoteOnly": true,
"maxItems": 5000
}

Output Overview

Each dataset item is a job row containing:

  • Core fields — title, department, employment type, workplace type, remote flag
  • Locations — primary location plus the full locations array
  • Content — full description as HTML and plain text (toggle with includeDescription)
  • Provenance — source ATS, company, stable globalId (ats:org:jobId) for cross-run dedup
  • Links & datesjobUrl, applyUrl, publishedAt, scrapedAt
  • Lead-gen enrichmentcontactEmail, contactWebsite, emailEnrichment (when enrichEmails is on)
  • TraceabilityinputIndex and jobsFound tie each row back to the input that produced it

Rows arrive in the same order as your inputs. All start modes (URL / company name / spreadsheet) resolve to the same job-row shape.


Output Samples

Company-name start, with email enrichment

{
"ats": "greenhouse",
"org": "stripe",
"company": "Stripe",
"globalId": "greenhouse:stripe:7954688",
"title": "Backend Engineer",
"department": "Engineering",
"workplaceType": "Hybrid",
"isRemote": false,
"location": "San Francisco, CA",
"locations": ["San Francisco, CA"],
"descriptionHtml": "<p>…</p>",
"descriptionText": "…",
"publishedAt": "2026-06-19T12:11:02-04:00",
"jobUrl": "https://stripe.com/jobs/search?gh_jid=7954688",
"applyUrl": "https://stripe.com/jobs/search?gh_jid=7954688",
"contactEmail": "careers@stripe.com",
"contactWebsite": "stripe.com",
"emailEnrichment": { "website": "stripe.com", "emails": ["careers@stripe.com"] },
"jobsFound": 495,
"inputIndex": 0,
"scrapedAt": "2026-06-20T00:00:00.000Z"
}

Key Output Fields

Job Core

  • title, department, employmentType, workplaceType, isRemote

Locations

  • location (primary), locations[] (all)

Content

  • descriptionHtml, descriptionText (present when includeDescription is on)
  • raw (original ATS payload, when includeRawJson is on)

Provenance & Dedup

  • ats (greenhouse / lever / ashby / smartrecruiters / workday / workable / recruitee / breezy / personio / bamboohr)
  • org, company, globalId (stable ats:org:jobId — dedup across runs)
  • jobUrl, applyUrl, publishedAt, scrapedAt

Lead-Gen Enrichment (when enrichEmails: true)

  • contactEmail, contactWebsite, emailEnrichment {website, emails[]}

Run Traceability

  • inputIndex, jobsFound

FAQ

How is this different from a job-database API?

Database-style actors serve rows from an index they crawled earlier — coverage is limited to companies already in the index, and freshness depends on their crawl cycle. This actor has no index: it calls each company's ATS live during your run, so any company on a supported platform is covered, and every row reflects the board's state right now.

How does ATS auto-detection work?

For a bare company name, the actor tries each supported ATS in order and uses the first that returns jobs. For a URL, it routes by hostname. SmartRecruiters company IDs are case-sensitive — pass the exact ID or a careers URL.

Can it scrape every company on an ATS?

No — ATS platforms publish no public directory of all boards. You supply the companies (names, URLs, or a spreadsheet). That's the flip side of live coverage: any company you name is reachable, but there's no "give me everything" mode.

How accurate is the contact email?

Best-effort. It discovers the company website and harvests publicly published addresses (typically general inboxes like careers@ / info@); many companies publish none, so coverage varies. Off by default since it adds time and cost.

How do I see which inputs worked?

Every run saves an INPUT-STATUS record to the run's key-value store — one entry per input with its detected ATS, status (ok / failed), and jobsFound. Open it (run → Storage → Key-value store) to spot inputs that returned nothing.

Can I get postings in English?

Set language to en. Personio returns English descriptions natively, and SmartRecruiters jobs are filtered to English. Other ATSs return whatever language the role was posted in — they aren't translated.

Do I need a proxy?

No. These ATS endpoints are public, and the actor already routes traffic through its own built-in residential proxy at no extra cost. Leave the proxy field empty.

Can I scrape private or internal postings?

No. The actor only reads publicly available postings from each ATS's public endpoints. Anything behind a login wall is out of scope.


Support

Found a bug or have a feature request? Open an issue on the actor's Issues tab — issues are typically answered within a day.

Additional Services

Need another ATS platform added, a custom export shape, or a scheduled monitoring pipeline delivered to your CRM? I do tailored work — open an issue or reach out via the actor's contact form.

Explore More Scrapers

If you found this useful, you might also like:

Full list at apify.com/memo23.


🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the Apify MCP server or the Apify API (actor: memo23/ats-jobs-scraper).

Purpose: fetch live job postings for named companies across 10 ATS platforms (Greenhouse, Lever, Ashby, SmartRecruiters, Workday, Workable, Recruitee, Breezy, Personio, BambooHR), normalized to one schema, optionally with a public company contact email.

Minimal input:

{ "organizations": ["stripe"], "maxItems": 25 }

Output: one dataset row per job — ats, org, company, globalId, title, department, employmentType, workplaceType, isRemote, location, locations[], descriptionHtml, descriptionText, publishedAt, jobUrl, applyUrl, jobsFound, inputIndex, scrapedAt, plus contactEmail / contactWebsite / emailEnrichment {website, emails[]} when enrichEmails is true.

Behaviors an agent should know:

  • Always set maxItems — a large company list can return tens of thousands of rows; the default cap is 5000.
  • Input modes merge: startUrls (board URLs), organizations (bare names, ATS auto-detected), and inputUrl (sheet of either) can be combined in one run.
  • Filters (titleKeyword, keywords, location, department, employmentType, remoteOnly, postedAfter) apply before billing — filtered-out jobs are never charged.
  • Billing: charged per job row pushed (primary event) plus a one-time actor-start event; enrichEmails adds a small per-company additional-data charge.
  • There is no "all companies" mode — the agent must supply company names or board URLs. Per-input success is reported in the run's INPUT-STATUS key-value record.
  • No proxy configuration needed; leave proxy empty.

⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Greenhouse Software, Inc., Lever (Employ Inc.), Ashby Inc., SmartRecruiters Inc., Workday, Inc., Workable Software Ltd., Recruitee B.V., Breezy HR, Inc., Personio SE & Co. KG, BambooHR LLC, or any of the companies whose job boards it reads. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available job-posting pages and endpoints exposed by each ATS's own public career-site interface, plus publicly published company contact details — no authenticated endpoints, paid features, or content behind any login wall. Users are responsible for ensuring their use complies with each platform's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization — especially when using contact data for outreach.


SEO Keywords

ats jobs scraper, multi-ats scraper, career site jobs api, career site job listing api, scrape greenhouse jobs, lever jobs scraper, ashby jobs scraper, workday jobs scraper, smartrecruiters scraper, applicant tracking system scraper, company career page scraper, live job listings api, job database alternative, hiring signal data, recruiting lead generation, jobs with contact email, sales intelligence hiring data, job market monitoring, talent intelligence data, hr tech data extraction