Career Site Jobs Scraper: 41 ATS & Job Sites avatar

Career Site Jobs Scraper: 41 ATS & Job Sites

Pricing

from $1.00 / 1,000 job results

Go to Apify Store
Career Site Jobs Scraper: 41 ATS & Job Sites

Career Site Jobs Scraper: 41 ATS & Job Sites

Career page and ATS jobs scraper for 41 systems: Workday, SuccessFactors, Greenhouse, Lever, Phenom, iCIMS, Taleo, Oracle Recruiting, Eightfold, SmartRecruiters, Refline, Prospective and more. Returns title, company, location, department, apply URL and description. HTTP-only, pay per result.

Pricing

from $1.00 / 1,000 job results

Rating

0.0

(0)

Developer

NanoScrape

NanoScrape

Maintained by Community

Actor stats

3

Bookmarked

92

Total users

6

Monthly active users

6 minutes ago

Last modified

Share

Career Site Jobs Scraper: 41 ATS Platforms and Career Sites

Extract job listings from company career pages built on 41 job systems (ATS platforms and career sites) covering ~60% of the Fortune 500. Returns title, location, department, employment type, remote flag, apply URL, and full description. No login required. HTTP-only, no browser overhead.

Supported Platforms

41 job systems are supported: 40 ATS platforms and 1 config-only career site. Pass the platform value in the table, or just a company URL and the actor detects the system automatically.

Standard ATS (18)

Platformplatform valueExampleData and notes
Leverleverhttps://jobs.lever.co/spotifyTitle, location, department, employment type, description, dates. Lever EU boards (jobs.eu.lever.co/{company}) are read from api.eu.lever.co; a bare company id that is not on the global instance is retried there.
Greenhousegreenhousehttps://boards.greenhouse.io/anthropicTitle, location, department, description, dates
Ashbyashbyhttps://jobs.ashbyhq.com/rampTitle, location, department, employment type, remote, description, dates
Workableworkablehttps://apply.workable.com/ometriaTitle, location, department, remote, dates
Teamtailorteamtailorhttps://career.teamtailor.comTitle, location, department, remote, description, dates. A career site on the employer's own domain works with {"platform":"teamtailor","company":"https://jobs.liip.ch"} (read through its /jobs.rss feed).
Personiopersoniohttps://personio-gmbh.jobs.personio.deTitle, location, department, employment type
SmartRecruiterssmartrecruitershttps://jobs.smartrecruiters.com/BoschGroupTitle, location, department, employment type, remote, dates
BambooHRbamboohrhttps://freshworks.bamboohr.com/careers/listTitle, location, department, employment type
Workdayworkdayhttps://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSiteTitle, location, employment type, remote, description, dates
iCIMSicimshttps://careers-costco.icims.com/jobs/searchTitle, location (best-effort HTML extraction)
Recruiteerecruiteehttps://everdrop.recruitee.comTitle, location, department, employment type, remote, description, dates
JOINjoinhttps://join.com/companies/agicapTitle, location, department, employment type, dates
Pinpointpinpointhttps://edenred.pinpointhq.comTitle, location, department, employment type, description
Ripplingripplinghttps://ats.rippling.com/rippling/jobsTitle, location, department, employment type, remote, description, dates
JazzHRjazzhrhttps://agatlaboratories.applytojob.com/applyTitle, location, department
Comeetcomeethttps://www.comeet.com/jobs/fiverr/60.002Title, location, department, employment type, remote, dates
B-ITEbitehttps://recruiting.fz-juelich.deGerman recruiting platform (Forschungszentrum Jülich, Helmholtz Munich and other research centres and employers). Pass the tenant URL (https://recruiting.fz-juelich.de) or the employer's career page that links its postings ({"platform":"bite","company":"https://www.helmholtz-munich.de/karriere/stellenangebote"}; the tenant is found from the page). Reads the tenant's sitemap (one request, titles are not in it), then each posting's JSON-LD: title, employer, city, country, published date, employment type, apply URL, full description with lists. The sitemap has neither titles nor dates, so every posting is opened (6 at a time, newest edits first, stopping once the cap is filled); the keyword, location and posted-within filters run before a row is pushed or charged.
d.vincidvincihttps://jobs.dkfz.deGerman recruiting software (DKFZ, DZNE, KIT and many other German employers, each on its own host). Pass the tenant URL (https://jobs.dkfz.de) or the employer's career page that embeds the job widget ({"platform":"dvinci","company":"https://www.kit.edu/karriere/stellenangebote.php"}; the tenant is found from the page). Widget v2 pages (Doppelmayr: https://www.doppelmayr.com/karriere/offene-stellen/) are found too, including a feed under a portal path (https://doppelmayr.dvinci-hr.com/portal/dgw/jobPublication/list.json, which can also be passed directly); a group tenant names the employer per posting (Garaventa AG, CWA). A tenant with no open postings (career.cordenpharma.com) answers no_jobs_found. Reads the widget's job feed in one request that already carries the posting text, no posting page is opened. Title, employer, department, city, country, employment type, created date (the pages show no posting date), apply URL, full description with lists. The feed has no server-side filter: keyword, location and date filters run before a row is pushed or charged.

Enterprise ATS (10)

Platformplatform valueExampleData and notes
ADPadphttps://workforcenow.adp.com/mascsr/...?cid=GUID3 F500 companies. Two portal types: WorkforceNow (public OData) and MyJobs (Bearer token).
Taleotaleohttps://textron.taleo.net/careersection/textron/jobsearch.ftl2 F500 companies (modern API portals). Classic FTL portals require browser rendering, see Enterprise ATS Jobs Scraper for those deployments.
Avatureavaturehttps://ally.avature.net/careers/SearchJobs/3 F500 companies. HTML scraping with JSON-LD detail enrichment. Supports cross-domain redirects.
Brassringbrassringhttps://sjobs.brassring.com/TGnewUI/Search/Home/Home?partnerid=25526&siteid=50327 F500 companies. Session-based Ajax API. Pagination at 50/page, no cap.
SuccessFactorssuccessfactors_rmkhttps://careers.company.com/search/23 F500 companies via RMK-branded career sites. RSS/sitemap-based extraction. Provide the branded company career URL. The vendor portal (careerNN.successfactors.eu or sapsf.eu, path /career?company=) is the separate system successfactors_classic.
TalentBrew (Radancy)talentbrewhttps://jobs.walgreens.com/en22 F500 companies. AJAX JSON+HTML pagination.
Oracle Recruiting Cloudoracle_recruitinghttps://eeho.fa.us2.oraclecloud.com/hcmUI/CandidateExperience/...27 F500 companies. REST finder API with comma-separated params.
Eightfoldeightfoldhttps://careers.nyl.eightfold.ai/careers15 F500 companies. PCSX + apply/v2 dual API fallback.
Phenomphenom{"platform":"phenom","company":"https://jobs.cvshealth.com"}35 F500 companies. SSR inline JSON extraction. Pass as object with platform+company.
iCIMS Jibeicims_jibe{"platform":"icims_jibe","company":"https://careers.costco.com"}Career sites built on iCIMS Jibe (careers.costco.com, jobs.booking.com, careers.amd.com, careers.petsmart.com). Reads the site's own JSON API, not the blocked iCIMS portal. Pass the career site URL with platform icims_jibe (aliases jibe, icims-jibe); the URL cannot be detected from the host alone. Title, location (additional locations on multi-location postings), department, employment type, apply URL, posted date, description.

Swiss ATS and career sites (13)

Platformplatform valueExampleData and notes
Reflinereflinehttps://apply.refline.ch/673276/search.htmlSwiss ATS (Empa, Eawag, WSL, SIB and many Swiss employers; company sites embed it from pub.refline.ch/{id}/refline.js). Pass the apply.refline.ch/{id} list or job URL (or the embed script URL). Reads the full server-rendered list in one request, then each posting page. Title, location, workload percentage, employment type, posted date (list order is not by date, the actor sorts newest first), apply URL, description. A job published in several languages is returned once (first language variant).
Prospectiveprospectivehttps://ohws.prospective.ch/public/v2/careercenter/1002007/Swiss ATS and job-portal vendor (Uni Zürich, Uni Bern, Uni Basel, the federal job portal jobs.admin.ch, SRG SSR, BKW, Kanton Solothurn, Pilatus and many other Swiss employers). Pass the careercenter id or URL, the ohws.prospective.ch URL from the company page iframe, or the portal URL with {"platform":"prospective","company":"https://jobs.admin.ch"} (the id is read from the page, from the host's /jobabo page, or from the job-subscription page it links to). Reads the portal's open JSON API in one pass (newest first, no detail requests); portals that refuse the API are read from their careercenter list (any template that links postings as /offene-stellen/{slug}/{uuid}) and posting pages. Also accepts a company page that lists the postings (https://sro.ch/sro/karriere/stellenangebote/, a vanity host without a portal id such as https://jobs.sympany.ch) and the legacy {tenant}.prospective.ch portal (https://pilatus.prospective.ch/wl_jobabo.cfm, paged list). Title, employer (office, university or the group company named on the posting), location, department, workload percentage, employment type, published date, apply URL, full description. Lists that omit place or date (no descriptions requested) get them from the posting page when descriptions are on. Keywords filter on the title.
Abacus Umantisumantishttps://recruitingapp-2800.umantis.com/Jobs/AllSwiss and German eRecruiting system (Kanton St.Gallen, Kanton Aargau, Swiss TPH, FiBL, Viollier, Insel Gruppe and many other Swiss employers). Pass the recruitingapp-{id}.umantis.com job list URL, or the career site of a customer that serves Umantis under its own host ({"platform":"umantis","company":"https://jobs.swisstph.ch/"}; the tenant is found from the page). Reads the public job list page by page (no JSON feed exists), then each posting page. Title, employer, department, location, workload percentage, employment type, published date (where the tenant shows it), apply URL, full description. Customers that redirect postings to their own site keep the list data without a description.
Abacus Job Portalabacushttps://app.jobportal.abaservices.ch/job-overview/d9c5a048-f665-4e64-a2c7-cdd8231bac77Abacus Research AG job portal (app.jobportal.abaservices.ch), used by Swiss municipalities, banks, utilities and schools such as CSEB, Stadt Wil, Kellenberger, Thermoplan and Abacus itself. This is NOT Abacus Umantis, which is the separate system umantis. Pass the portal URL (https://app.jobportal.abaservices.ch/job-overview/{portal-id}), a slug URL such as https://jobs.cseb.ch/job-overview/CSEB, or the bare portal id. An employer on its own domain or a career page that links the portal needs {"platform":"abacus","company":"https://jobs.shkb.ch"} (the portal id is found from the page). Reads the whole job list with full texts in one request (no paging, no server-side filter), one row per job even when it is published in several languages. Title, employer, location, country, workload percentage, published date, apply URL, full description. The older server-rendered AbaCity portals ({x}.abacuscity.ch/de/jobportal) are not read and end with the reason unsupported_variant.
Soliquesoliquehttps://live.solique.ch/ksw/Swiss e-recruiting system (solique.ch) behind the job pages of hospitals, utilities, cantons and industrials such as Kantonsspital Winterthur, Spital Emmental, Spital Muri, Spitalverbund Appenzell Ausserrhoden, ipw, EBL, BLT, GVZ, Kanton Zürich, the St.Galler Stadtwerke, Rieter and Swiss Steel Group. Pass the tenant URL (https://live.solique.ch/ksw/, https://live.solique.ch/STSG/de/ORG20/), the tenant name with platform solique ({"platform":"solique","company":"ksw"}), or the employer's own job page that links or embeds live.solique.ch ({"platform":"solique","company":"https://www.rieter.com/careers/open-positions"}; the tenant is found in the page). Reads the tenant's whole open job list in one request (no paging, no server-side filter), whichever of the four Solique list formats the tenant uses, then each posting page for the description. Title, employer (the lists carry no company name, so the tenant's display name or the group company named on the posting is used), location, department, workload percentage, employment type, published date, apply URL, full description. Country is Switzerland unless the posting names another (Rieter and Swiss Steel Group list jobs in several countries). Tenants with an undated list (Rieter, Swiss Steel Group, EHB) return no published date and are not sortable by date; rows without a date are kept by a posted-within filter.
Jobalinojobalinohttps://my.jobalino.ch/custel_jobExternalList/de/medisyn-saSwiss recruiting software hosted at my.jobalino.ch (medica.ch, medisyn.ch, Dr. Risch and other Sonic Suisse laboratories). Pass the company slug, the my.jobalino.ch job list URL, or the employer's own jobs page that embeds the list ({"platform":"jobalino","company":"https://www.risch.ch/jobs"}; the slug is found from the page). Reads the open job list in one request (no paging, no total), then each posting's JSON-LD for the description. Title, employer (a list can carry sister companies), location, department, workload percentage, employment type, published date, apply URL, full description. The list has no date, so the posting is read before the filter when a posted-within or newest-first request needs it.
Dualoodualoohttps://jobs.dualoo.com/portal/etge4wyfSwiss recruiting portal for jobs and apprenticeships (Hänseler, Dottikon, IOB, Neurimmune and others). Pass the portal code or URL (https://jobs.dualoo.com/portal/{code}), the employer's career page that links or embeds the portal (the code is found from the page), or a single posting link (jobs.dualoo.com/link/{id}). Reads the portal list in one request (no paging, no total), then each posting's JSON-LD for the description (description, responsibilities, profile and benefits). Title, employer, location, workload percentage, employment type, published date, apply URL, full description. The list shows only the start date, so the posting is read before the filter when a posted-within, location or newest-first request needs it. An employer can run several portals (jobs and apprenticeships): pass each code.
SAP SuccessFactors (classic career portal)successfactors_classichttps://career55.sapsf.eu/career?company=BLSSAP SuccessFactors classic career portal (careerNN.successfactors.eu or .com, careerNN.sapsf.eu or .com), used by SBB, BLS, Repower, Sefar, Swissgrid, Biotronik and USZ. Pass the portal URL (list or posting link), host/companyId such as career55.sapsf.eu/BLS, or an employer career page that links the portal; a bare company id is rejected because the portal host is needed. Reads the portal's external job feed once per posting language (default, en_US, de_DE, de_CH, fr_FR, it_IT and extra languages of the portal) and merges the answers by requisition id, so every job appears once. Then reads each posting page for city, country, posted date and employer, only for the jobs that pass the filters and the cap. Title, employer, city, country, department and employment type where the portal publishes them, workload from the title, posted date, apply URL, full description. Not the branded Career Site Builder on a company domain, which is successfactors_rmk.
ETH Zurich Jobsethzhttps://jobs.ethz.ch/Config-only site (sites/ethz.json, no Go). Reads the server-rendered list of all open ETH positions in one request, filters keywords / location / posted date locally, sorts newest first (the site order is not by date), then each posting page for the full description and the online application link. Platform name ethz.
Onlyfy (by XING)onlyfyhttps://infoguard-ag.onlyfy.jobs/Onlyfy (formerly Prescreen, by XING / New Work SE), the hosted career pages at <company>.onlyfy.jobs used by Bitcoin Suisse, InfoGuard, Inventx, Leica Geosystems, the VITREA rehab clinics and Spitex Zuerich. Pass the career page (https://infoguard-ag.onlyfy.jobs/; any job, apply or language link of the same host is reduced to it) or the tenant name with platform onlyfy ({"platform":"onlyfy","company":"infoguard-ag"}). The onlyfy marketing site (onlyfy.com) and an employer page are rejected with a clear message. Reads the career page list page by page (newest first), then each posting page for the description. Title, employer (the legal entity or clinic named on the posting, so a shared group board such as VITREA shows the clinic), city, country, employment type, published date, apply URL, full description. Open applications (Initiativbewerbung) are dropped.
Rexx Systemsrexxhttps://jobs.green.ch/stellenangebote.htmlGerman e-recruiting suite (rexx-systems.com) behind many Swiss and German career portals on the employer's own host (Green, Stadt Chur, Gemeinde Horgen, Viseca, Zehnder, PH St. Gallen, Stadt Winterthur, GVB, RBS). Pass the portal's job list URL (https://jobs.green.ch/stellenangebote.html); a URL ending in /stellenangebote.html or in a -de-j123.html posting is recognised on any host, other hosts need {"platform":"rexx","company":"https://jobs.viseca.ch/"}. Reads the list (with load-more paging) and each posting's JobPosting data. Title, employer, location, employment type, published date, apply URL, full description.
Ostendisostendishttps://www.bernaville.ch/stellenSwiss recruiting software (ostendis.com) whose job list is embedded in the employer's own career page (Arkadis, Bernaville, Siloah, Swiss Cancer Institute, Maerki Baumann, Regionalspital Surselva, Pro Helvetia). Pass the employer page that embeds the list ({"platform":"ostendis","company":"https://www.bernaville.ch/stellen"}); the 32 character place token is read from the page, or pass the token itself. Pages that only link single postings on link.ostendis.com (schuetzen-rheinfelden.ch, sonnmatt.ch, thurvita-jobs.ch) are read posting by posting. A bare link.ostendis.com cvdropper or publication link names no job list and is rejected with a clear message. Reads the whole list in one request, then each posting's JSON-LD for the description. Title, employer, city, country, published date, workload percentage, employment type, department, apply URL, full description.
publicjobs.chpublicjobshttps://www.publicjobs.ch/karriereseite/Gemeinde-Meilen/~art569publicjobs.ch, the Swiss public-sector job board used by municipalities, schools and hospitals (Gemeinde Meilen, Muttenz, Thalwil, Steffisburg, Reinach, GZO Spital Wetzikon, Koeniz). Pass the employer's publicjobs.ch career page (https://www.publicjobs.ch/karriereseite/<name>/~art<N>, the ~art number is required) or the employer's own page that shows the publicjobs.ch job list or frames the career page ({"platform":"publicjobs","company":"https://www.gzo.ch/karriere/offene-stellen"}). A single posting or application link names no list and is rejected with a clear message. Reads every list on the page (a municipality and its school are two lists) page by page, then each posting page for the description. Title, employer, city, country, published date, workload percentage, employment type, field of work, apply URL, full description.

Pass any mix of company URLs: the actor detects the system automatically and normalises output across all 41 supported systems.

Descriptions by ATS

includeDescription (default true) controls whether the description is returned. What each ATS can deliver, measured on a 20 job sample per company:

ATSDescriptionNotes
Lever, Greenhouse, Ashby, Teamtailor, Recruitee, PinpointYes, from the listing0% missing
WorkdayYes, one detail request per jobDetail requests are throttled by some tenants (NVIDIA after about 450 requests). The actor lowers its concurrency, honours Retry-After and retries blocked requests through a rotating residential connection. Rows whose detail page still fails are pushed without description and counted in the summary message.
RipplingYes, one detail request per job0% missing
SuccessFactors (RMK sites)Yes, one detail page per job0% missing; the location and date are also taken from the listing row
SuccessFactors (classic portal)Yes, from the feedThe list is the portal XML feed (read once per language and merged by requisition id). The place comes from the feed or the posting page. A country filter without a cap, or with a cap, reads the posting pages to find the place; with includeDescription off and no cap a location filter cannot resolve places on tenants whose feed has none
PhenomYes, from the listing0% missing on the tested tenant
iCIMS JibeYes, from the listingFull HTML description in the same API response
Oracle RecruitingYes, one detail request per jobRead from the requisition details endpoint (description, responsibilities and qualifications joined). The listing alone carries no text on many tenants (for example Southern Company).
EightfoldYes, one detail request per jobRead from the position details endpoint, with the apply API as fallback
SmartRecruitersYes, one detail request per jobRead from the posting endpoint (company, job description, qualifications and additional information sections)
Refline, Prospective, ETH Zurich JobsYes, one detail request per job (Prospective: from the portal API in one pass)Full description from the posting page
PersonioNoListing only
JOINNoListing only
ComeetNoListing only
JazzHRNoListing only
TaleoNoListing only
BrassringNoListing only; the listing also has no location, so a location filter drops every row (counted in jobs_location_unknown)
Workable, BambooHR, iCIMS, TalentBrew, Avature, ADPNot confirmedNot covered by the sample (empty or blocked tenants); treat the description as best effort

Known Unsupported Deployments

12 Fortune 500 companies use deployment-specific anti-bot configurations that prevent HTTP-only scraping. For SuccessFactors, Taleo and Avature the platforms themselves are supported and these are individual deployment limitations. Jobvite is not supported at all (see Coming Soon):

CompanyPlatformReason
American AirlinesSuccessFactorsWAF blocks TLS-fingerprinted requests
CorningSuccessFactorsWAF blocks TLS-fingerprinted requests
Edison InternationalSuccessFactorsWordPress CWS career site, JavaScript-only job loading
Valero EnergyTaleoClassic FTL portal requires browser-initialized session
D.R. HortonTaleoClassic FTL portal requires browser-initialized session
Cincinnati FinancialTaleoClassic FTL portal requires browser-initialized session
Vulcan MaterialsTaleoClassic FTL portal requires browser-initialized session
NVRTaleoTBE variant, DWR facade has no job search method
Delta AirlinesAvatureAWS WAF JavaScript challenge
Jacobs SolutionsAvatureAWS WAF JavaScript challenge
ProgressiveJobviteCloudflare JavaScript challenge
SAICJobviteCloudflare JavaScript challenge

Other known gaps: the older server-rendered AbaCity portals of Abacus ({x}.abacuscity.ch/de/jobportal) are not read and end with the reason unsupported_variant; the newer Abacus Job Portal (app.jobportal.abaservices.ch) is supported.

To check whether a specific company is supported before scraping, run Website Job Extractor on its website. It finds the careers page and reports the job system in ats_system, with ats_supported_by_csj telling you whether this actor can read it (see "Find a company's job system" in the FAQ below).

Coming Soon

These platforms are on the roadmap for future releases:

  • Jobvite: browser-based handler for Cloudflare-protected portals
  • Breezy HR: REST API investigation in progress
  • Zoho Recruit: API-based extraction planned

Use with AI Agents (MCP)

Connect this actor to any MCP-compatible AI client, such as Claude Desktop, Claude.ai, Cursor, VS Code, LangChain, LlamaIndex, or custom agents.

Example prompts once connected:

"Use career-site-jobs-scraper to get all open engineering roles at Anthropic (Greenhouse) and Ramp (Ashby). Return as a table with title, location, and apply URL."

"Use career-site-jobs-scraper to scrape job listings from Spotify (Lever), Rippling (Rippling), and Fiverr (Comeet). Which companies have the most remote roles?"

"Use career-site-jobs-scraper to scrape jobs from NVIDIA (Workday), Bosch (SmartRecruiters), and everdrop (Recruitee). Filter for roles in Germany."

Configure MCP server with Career Site Jobs Scraper. Get a ready-to-use configuration for your MCP client with the Career Site Jobs Scraper preconfigured at mcp.apify.com?tools=santamaria-automations/career-site-jobs-scraper. You can connect to the Apify MCP Server using clients like Tester MCP Client, or any other MCP client of your choice.

{
"mcpServers": {
"apify": {
"command": "npx",
"args": [
"mcp-remote",
"https://mcp.apify.com/?tools=santamaria-automations/career-site-jobs-scraper",
"--header",
"Authorization: Bearer <YOUR_API_TOKEN>"
]
}
}
}

For per-tool schemas and copy-paste snippets for MCP clients, see the MCP tab.

See the auto-generated API tab for language-specific examples (cURL, JS, Python, .NET, Ruby, PHP).

Features

  • 41 job systems: 40 ATS platforms plus 1 config-only career site(s); the ATS platforms cover ~302 Fortune 500 companies (~60% of F500)
  • Auto-detection: paste any career page URL; platform detection is automatic
  • Normalised output: consistent field names across all platforms
  • Full pagination: follows all pages; no hidden caps (Brassring verified at 23K+ jobs)
  • Deduplication: duplicate job IDs are automatically excluded
  • Optional descriptions: toggle full HTML descriptions on/off to control payload size
  • No credentials needed: all platforms use public endpoints (ADP MyJobs auto-acquires Bearer token)
  • Pay-per-result: only pay for jobs you receive

Data Extracted

FieldExample
id"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
title"Senior Software Engineer"
company"spotify"
ats_platform"lever"
location"San Francisco, CA"
city"San Francisco" (read from the location text, null when unclear)
country"US" (ISO 3166-1 alpha-2 read from the location text, null when unknown)
country_source"query-default" (only present when the country was derived or taken from the query's country)
department"Engineering"
employment_type"Full-time"
workload"80% - 100%" (Refline and Prospective only)
remotefalse
description"<div>We are looking for...</div>"
apply_url"https://jobs.lever.co/spotify/a1b2c3d4/apply"
job_url"https://jobs.lever.co/spotify/a1b2c3d4"
additional_locationsWorkday multi-location postings: the other locations of the job
created_at"2026-01-15T09:00:00Z"
posted_at_text"Posted 3 Days Ago" (the site's own date text, when created_at was parsed from it)
updated_at"2026-04-01T12:00:00Z"
scraped_at"2026-04-25T14:00:00Z"

Data availability by platform

Platformlocationdepartmenttyperemotedescriptiondates
LeverYYYYYY
GreenhouseYY--YY
AshbyYYYYYY
WorkableYY-Y-Y
TeamtailorYY-YYY
PersonioYYY---
SmartRecruitersYYYY-Y
BambooHRYYY---
WorkdayY-YYYY
iCIMSY-----
RecruiteeYYYYYY
JOINYYY--Y
PinpointYYY-Y-
RipplingYYYYYY
JazzHRYY----
ComeetYYYY-Y

Y = available for most companies. Blank = not provided by the platform's public API.

Pricing

Pay-per-result pricing. You only pay for jobs you receive.

EventPriceDescription
Actor start$0.001One-time per run
Job scraped$0.001 eachPer job listing returned ($1 / 1,000 jobs)

Examples:

  • 200 jobs from 4 companies = $0.20 total
  • 1,000 jobs across 10 companies = $1.00 total
  • 10,000 jobs across 20 companies = $10.00 total

No monthly fees. No minimum spend.

Input

FieldTypeDescriptionDefault
queriesarrayCareer page URLs or {platform, company} objects. An object may add country (ISO 3166-1 alpha-2) and employer (see below).required
maxJobsPerCompanyintegerMax jobs per company. 0 = all jobs (hard safety limit of 5000 per company, logged when hit).500
keywordsarrayOnly jobs whose title matches any keyword (OR, case and accent insensitive). Keywords of 4 or more characters match anywhere in the title; keywords of 3 or fewer characters must match as a whole word.none
locationstringOnly jobs in this city, region or country. Uses the ATS location facets where available.none
postedWithinDaysnumberOnly jobs posted in the last N days. Jobs without a posting date are kept.none
sortBystringnewest or relevance.site order
includeSummaryRowsbooleanEmit one job_extraction_done row per company. On automatically when any new input is used or the cap is 0.auto
residentialFallbackstringauto or off. Controls the proxy ladder for sites that block the normal connection (see below). off never uses residential proxies.auto
maxResidentialHostsintegerMost different career-site hosts that may use residential proxies in one run. Empty = no limit.unlimited
includeDescriptionbooleanInclude full HTML job description in outputtrue

Filters, pagination and summary rows

All new inputs are optional. Without them the actor behaves as before (500 jobs per company, site order, no summary rows).

Filters run before the cap and before charging, so you only pay for jobs that match. Where the ATS supports it the search runs server side (Workday search text and location facets, Oracle, Eightfold, SmartRecruiters, Phenom keywords, TalentBrew, Taleo single keyword), then a light local check is applied. Single response boards (Greenhouse, Lever, Ashby, Personio) are filtered locally. Other paged ATSs are filtered page by page and stop as soon as the cap is filled, so a filtered run reads only a few pages. Keywords match the job title only. Rule: a keyword of 4 or more characters (after case and accent folding) matches anywhere inside the title; a keyword of 3 or fewer characters (for example TA, QA, PM) must match as a whole word, meaning the characters before and after it in the title are not letters or digits. So TA matches 'Lab TA (m/w/d)' and 'Biologielaborant/TA' but not 'Universitat' or 'Sanitar'.

Per-query default country: some boards give no country and no place for a posting (Umantis and SuccessFactors tenants of Swiss cities and hospitals), so a country location such as Switzerland drops those rows as location unknown. Add country to the query, for example {"platform":"successfactors_rmk","company":"https://jobs.stadt-zuerich.ch","country":"CH"}. Rows whose country is still unresolved after the posting page get that country and country_source is query-default; rows with a known other country are dropped, also when no location is set (the row is never pushed or charged); the summary row counts them in jobs_dropped_by_country and, when they are all there is, reports filtered_out_by_country. A country counts as known only from a structured country (code or a German, French, Italian or English name) or a location text that resolves to one country; a text that also names the query's country ("Zurich, Switzerland / Berlin, Germany") is kept. Liechtenstein (LI) rows are kept on a CH query (Swiss job seekers treat Vaduz, Schaan and Balzers as local) and keep their own country LI; a LI query stays strict and drops CH rows. A row whose place the tables cannot resolve is kept; SuccessFactors classic and RMK leave its country empty instead of copying the query's when the posting names a place. Without country nothing changes, so leave it out for global boards. Only set it for a board that really sits in that country.

Per-job employer: rows of Workday (with job details), iCIMS Jibe, Prospective, Onlyfy, Ostendis, Rexx and SuccessFactors carry hiring_organization, the legal entity the posting names. On a board shared by several entities it differs per job while company stays the board name used for grouping. The field is absent when the site gives no employer per job.

Per-query employer filter: a shared portal serves the postings of several employers on one board (the VITREA onlyfy tenant runs five rehab clinics; group portals of other cantons and hospital groups do the same). Add employer to the query, for example {"platform":"onlyfy","company":"vitrea-gesundheit","employer":"Rehaklinik Seewis"}, and only rows whose company matches are delivered. Matching ignores case, accents and punctuation and ignores legal forms (AG, GmbH, SA); every word of the filter must occur in the company, or the whole filter without spaces must (laborteam matches Labor Team W AG). Rows of other employers are dropped before the push, so they are not charged; the summary row counts them in jobs_dropped_by_employer and shows the filter in filters_employer. The key ats_employer of a website-job-extractor summary row is accepted as an alias, so a handover row can be passed straight in. The same board may be listed once per employer, each read delivers only its own rows. On boards that learn the employer only from the posting page, rows are judged after that page, and with a maxJobsPerCompany cap the result can then hold fewer rows than the cap although more match further down (onlyfy narrows the list by the clinic server side, so it is not affected). Such a board reads the posting pages for the employer filter even when includeDescription is false.

What newest means per ATS (with a cap, maxJobsPerCompany above 0):

  • Server order, paging stops at the cap: Workday without keywords (the cxs API lists the board by posting date, newest first) and iCIMS Jibe (sortBy=posted_date, checked to be date ordered over thousands of rows; keywords and location are filtered locally, so a rare keyword on a very large site can run into the 5000 row window of the site's API and the summary row then carries a filter_note). Jibe has no tiebreaker for jobs posted in the same minute, so such rows can swap places between pages; duplicates are removed.
  • Server sort used as a hint only: Oracle (POSTING_DATES_DESC), Eightfold (timestamp) and Phenom (Most recent). The ATS sort is requested, but rows are still collected and sorted by their parsed date before the cap (the cap plus 3 further pages with nothing newer), so rows are always pushed newest first. On Phenom, created_at is the site's posted date, which is what its "Most recent" sort uses.
  • No date ordering on the ATS (Workday with keywords, Greenhouse, Lever, Ashby, Personio, SmartRecruiters, Taleo, iCIMS, Brassring, SuccessFactors and the rest): the actor reads the listing (no detail requests), keeps the newest N by posted date and only then fetches details for those N. Reading stops once the cap is filled and 3 further pages bring nothing newer, and never goes past a hard bound of 20 listing rows per cap slot (at least 400, at most 5000 rows). If that bound is hit, the summary row says so in filter_note. Rows are pushed in date order. Relative dates such as "Posted 30+ Days Ago" sort after exact dates, and rows of the same day keep the ATS order.
  • Listings without any dates (for example Avature): rows are streamed in site order.
  • With maxJobsPerCompany 0 (all jobs) rows are streamed as soon as they are ready, in completion order.

Greenhouse boards are sorted by first_published (the posting date; updated_at changes on every edit). created_at is one ISO form: RFC 3339 in UTC such as 2026-09-17T09:12:17Z (or YYYY-MM-DD for date-only values), wherever the site's date text can be parsed (MM/DD/YYYY on US TalentBrew sites, DD/MM/YYYY on European ones, "Oct. 05, 2026", Workday "Posted Today", "Posted Yesterday", "Posted 3 Days Ago" relative to the scrape time). The original text is kept in posted_at_text. Open-ended texts such as "Posted 30+ Days Ago" give a null created_at and keep the text in posted_at_text.

Companies share the run time: each company may use the time left divided by the companies left, and time it does not use passes to the next ones. Every request, retry and detail read of a company is bounded by its share. A company that reaches its share ends with the reason company_time_budget and an honest partial list instead of starving the others. jobs_total_reported_by_site keeps the first non-zero total the ATS reported (some ATSs report it on page 1 only).

Open applications (titles such as Initiativbewerbung, Spontanbewerbung, Candidature spontanee, Unsolicited application) are not real vacancies. They are dropped before the push, are not charged and do not count against the cap; the summary log counts them in open_applications_dropped.

If a location filter is set and the site gives no location at all for a job (even after its detail page, where one is fetched), the job is not pushed and not charged. The summary row counts these in jobs_location_unknown and explains them in filter_note.

Each company gets a job_extraction_done row (never charged) with company (the query target), company_name (the employer's display name, the same name its job rows carry; on a board shared by several brands the one matching the query URL; null when the board has no jobs and no known name), reason, jobs_seen, jobs_after_filters, jobs_pushed, jobs_total_reported_by_site (null when the ATS exposes no total), filter_mode (server, local or none) and pages_fetched. A company with zero matches has a reason such as filtered_out_by_location, so an empty result is explained.

Limits: Workday returns at most 2000 results per search, so larger tenants are split by a facet automatically. iCIMS and a few legacy ATSs expose one page or limited location data, and location filtering there is best effort.

Every row is pushed to the dataset and charged on its own the moment it is ready (after its detail page where the ATS needs one), never held until the end. Detail pages are fetched concurrently, so rows arrive in completion order. The filters, the duplicate check and the per-company cap are applied per row before the push, so the cap is never exceeded and a job is never pushed twice. If the run is aborted, the rows already pushed stay and each company gets a summary row with reason aborted. Workday, Rippling, Oracle Recruiting, Eightfold and SmartRecruiters descriptions are fetched with bounded concurrency. If the run gets within a minute of its timeout the actor stops fetching, pushes what it has and writes the summary row with reason timeout_wind_down. When a Workday site's own location list has nothing matching your location, the company returns at once with reason no_location_match_on_site. Workday multi-location postings expose additional_locations, and a location filter matches all of them.

Coverage note: most NHS trusts recruit through Trac or NHS Jobs, which this actor does not cover. Private UK healthcare groups on Workday, Oracle or Pinpoint work.

Blocked sites and proxies

There is no proxy input. The actor goes direct first. When a site refuses the connection (timeout, reset, HTTP 403 or 429) it climbs a ladder:

  1. Direct (the normal connection).
  2. Apify datacenter proxy (one attempt per request; Apify picks the datacenter group, and its pool is US only, so there is no country pin).
  3. Apify residential proxy, the costly tier. A residential session is kept while it works and replaced by a new one (new IP) only when it gets blocked.

A site stays on the tier that worked for the rest of that company, and nothing is escalated before it fails. The run log has one line per host with the final tier, for example [PROXY-TIER] host=careers.mt.com tier=residential, and every company summary row carries proxy_tier (direct, datacenter or residential, the highest tier its hosts needed).

residentialFallback: "off" keeps the actor off residential proxies: a company that only residential can read ends as blocked, and the summary row says why. maxResidentialHosts does the same for every host beyond the limit. It defaults to 2 hosts per run, because residential traffic costs more than the per-job price; raise it (for example to 1000) to allow more. A host beyond the limit ends with reason blocked_residential_cap and a message telling you to raise maxResidentialHosts. If the Apify proxy rejects the credentials (HTTP 407) the actor logs an error and switches that tier off for the run; it does not silently go direct.

Supported URL formats

https://jobs.lever.co/{company}
https://boards.greenhouse.io/{company}
https://apply.workable.com/{company}
https://jobs.ashbyhq.com/{company}
https://{company}.teamtailor.com
https://{company}.jobs.personio.de
https://jobs.smartrecruiters.com/{company}
https://{company}.bamboohr.com/careers/list
https://{company}.wd{N}.myworkdayjobs.com/{site}
https://careers-{company}.icims.com/jobs/search
https://{company}.recruitee.com
https://join.com/companies/{slug}
https://{company}.pinpointhq.com
https://ats.rippling.com/{company}/jobs
https://{company}.applytojob.com/apply
https://www.comeet.com/jobs/{company}/{uid}

Alternatively, pass an object:

{"platform": "lever", "company": "stripe"}

Usage Examples

Scrape a single company (Lever)

{
"queries": ["https://jobs.lever.co/spotify"],
"maxJobsPerCompany": 200
}

Scrape multiple companies across several platforms

{
"queries": [
"https://jobs.lever.co/spotify",
"https://boards.greenhouse.io/anthropic",
"https://jobs.ashbyhq.com/ramp",
"https://apply.workable.com/ometria",
"https://career.teamtailor.com",
"https://personio-gmbh.jobs.personio.de",
"https://jobs.smartrecruiters.com/BoschGroup",
"https://freshworks.bamboohr.com/careers/list",
"https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
"https://everdrop.recruitee.com",
"https://join.com/companies/agicap",
"https://edenred.pinpointhq.com",
"https://ats.rippling.com/rippling/jobs",
"https://agatlaboratories.applytojob.com/apply",
"https://www.comeet.com/jobs/fiverr/60.002"
],
"maxJobsPerCompany": 500,
"includeDescription": false
}

Use explicit platform + company

{
"queries": [
{"platform": "greenhouse", "company": "anthropic"},
{"platform": "lever", "company": "spotify"},
{"platform": "ashby", "company": "ramp"},
{"platform": "workable", "company": "ometria"},
{"platform": "teamtailor", "company": "career"},
{"platform": "personio", "company": "personio-gmbh"},
{"platform": "smartrecruiters", "company": "BoschGroup"},
{"platform": "bamboohr", "company": "freshworks"},
{"platform": "recruitee", "company": "everdrop"},
{"platform": "join", "company": "agicap"},
{"platform": "pinpoint", "company": "edenred"},
{"platform": "comeet", "company": "fiverr/60.002"}
],
"maxJobsPerCompany": 100
}

Pass a company-page result straight in (ats / ats_system names)

An entry can name the job system and the address instead of platform and company. This is the shape the Website Job Extractor summary rows carry, so they can be forwarded as they are.

{
"queries": [
{"url": "https://boards.greenhouse.io/figma", "ats": "greenhouse"},
{"ats_system": "successfactors", "ats_url": "https://jobs.lear.com/search/"},
{"platform": "radancy", "company": "https://jobs.genpt.com"}
]
}
  • Keys: the name is platform, ats or ats_system; the address is company, url or ats_url.
  • Names are matched without regard to case. successfactors is the same as successfactors_rmk, and radancy is the same as talentbrew.
  • A name this actor does not read (for example goldman_sachs) ends with reason unsupported_platform. Nothing is fetched or charged for it.

Output

Results are exported to the default dataset. The All fields table view shows title, company, ATS platform, location, department, employment type, remote status, and apply link at a glance.

Export to JSON, CSV, Excel, or connect via the Apify API.

FAQ

Do I need API keys for any of the platforms? No. All supported platforms expose their job board data through public unauthenticated endpoints designed for job aggregators and career site widgets.

What if a company isn't found? The actor logs a warning and continues to the next query. It does not fail the entire run.

How do I know why a run returned zero jobs? The run status line (top of the run page and the statusMessage field of the run API object) states the reason per company, for example 0 jobs. personio/flixbus: blocked (The ATS refused the request (HTTP 429, Vercel Security Checkpoint).). Reasons: blocked (401/403/429 or a bot challenge), blocked_residential_cap (the site needs a residential proxy and the run already used its maxResidentialHosts budget, default 2), dns_error, http_error:<code> (for example http_error:404), board_not_found (the ATS answered 404: the board does not exist under that name or URL), unsupported_platform (the job system name is not one this actor reads; nothing is fetched or charged), duplicate_query (the same board was already read for an earlier entry in this run; it is read once), invalid_query (the entry could not be read, or the URL is not a job list and names no board; the summary row says what was expected. A posting URL of Greenhouse, Lever, Ashby, SmartRecruiters or Workday is reduced to its board and read), parse_error (the page or response could not be read, for example a career page whose job list is not in the HTML), connection_error, and no_jobs_found (the board was read and holds zero open positions). The actor still exits successfully and only pushes real job rows to the dataset, so downstream code that counts dataset items is not affected.

Are descriptions always available? Greenhouse, Lever, Ashby, Teamtailor, Recruitee, Pinpoint, and Rippling include descriptions when includeDescription is true. Workday, Oracle Recruiting, Eightfold, SmartRecruiters and SuccessFactors return descriptions via individual job detail requests. Workable, Personio, BambooHR, iCIMS, JOIN, JazzHR, and Comeet do not return descriptions from their public listing endpoints.

How fresh is the data? The actor fetches live data at run time. Jobs posted or closed within the last hour will be reflected immediately.

Can I mix URL formats and explicit platform objects in the same run? Yes. Every entry in queries is parsed independently.

Which platforms are best for the DACH market? Personio is especially popular with German, Austrian, and Swiss companies. SmartRecruiters is used by large European employers like Bosch. Teamtailor, Recruitee, and JOIN are widely used across Europe.

Which platforms are best for Fortune 500 companies? Workday is the dominant ATS for Fortune 500 enterprises (NVIDIA, Salesforce, etc.). iCIMS is also widely used by large US corporations. SmartRecruiters serves large European enterprises.

Are there any limitations with iCIMS or BambooHR? iCIMS portals are JavaScript-rendered SPAs. The actor extracts what it can from the HTML source, but some portals behind AWS WAF may not yield results. BambooHR has been deprecating public career page endpoints, so some companies may return empty results or redirects.

How do I find the ATS career page URL for a company?

Most companies link to their career page from their website footer ("Careers", "Jobs", "Join us"). Once on the career page, check where the jobs are actually hosted:

  1. Check the URL in your browser: if you see jobs.lever.co/company, boards.greenhouse.io/company, company.bamboohr.com, apply.workable.com/company, etc., you already have the URL. Just paste it.
  2. Right-click "View Page Source": search for domains like lever.co, greenhouse.io, ashbyhq.com, personio.de, teamtailor.com, etc. Many companies embed their ATS as an iframe or link.
  3. Check the network tab: open browser DevTools (F12), go to Network, reload the careers page, and look for API requests to known ATS domains.
  4. Look at job listing URLs: click any open position. If it redirects to jobs.lever.co/... or apply.workable.com/..., that's your ATS.
  5. Let Website Job Extractor find it: see "Find a company's job system" below.

Find a company's job system

Website Job Extractor takes any company website, finds the careers page and detects the job system. Each result row carries ats_system, ats_url and ats_supported_by_csj. Rows with ats_supported_by_csj: true can be passed straight into this actor as queries (see "Pass a company-page result straight in" above). Companies on unsupported or custom systems are extracted by Website Job Extractor itself. It runs in managed mode with no key of your own, and you can optionally use your own LLM key (Gemini, Groq or OpenRouter); see its README for details.

Support

  • Questions or issues? Email contact@nanoscrape.com, we typically reply within 6 hours. You can also open a ticket in the Issues tab on the actor page.
  • Missing a company or job system? Open a ticket in the Issues tab or email contact@nanoscrape.com with the company's careers page URL. We add new job systems regularly.
  • Need a scraper for a job board we don't cover yet? Email contact@nanoscrape.com with the target site and your rough usage volume.