Career Site Jobs Scraper: 41 ATS & Job Sites
Pricing
from $1.00 / 1,000 job results
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
Maintained by CommunityActor stats
3
Bookmarked
92
Total users
6
Monthly active users
6 minutes ago
Last modified
Categories
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)
| Platform | platform value | Example | Data and notes |
|---|---|---|---|
| Lever | lever | https://jobs.lever.co/spotify | Title, 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. |
| Greenhouse | greenhouse | https://boards.greenhouse.io/anthropic | Title, location, department, description, dates |
| Ashby | ashby | https://jobs.ashbyhq.com/ramp | Title, location, department, employment type, remote, description, dates |
| Workable | workable | https://apply.workable.com/ometria | Title, location, department, remote, dates |
| Teamtailor | teamtailor | https://career.teamtailor.com | Title, 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). |
| Personio | personio | https://personio-gmbh.jobs.personio.de | Title, location, department, employment type |
| SmartRecruiters | smartrecruiters | https://jobs.smartrecruiters.com/BoschGroup | Title, location, department, employment type, remote, dates |
| BambooHR | bamboohr | https://freshworks.bamboohr.com/careers/list | Title, location, department, employment type |
| Workday | workday | https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite | Title, location, employment type, remote, description, dates |
| iCIMS | icims | https://careers-costco.icims.com/jobs/search | Title, location (best-effort HTML extraction) |
| Recruitee | recruitee | https://everdrop.recruitee.com | Title, location, department, employment type, remote, description, dates |
| JOIN | join | https://join.com/companies/agicap | Title, location, department, employment type, dates |
| Pinpoint | pinpoint | https://edenred.pinpointhq.com | Title, location, department, employment type, description |
| Rippling | rippling | https://ats.rippling.com/rippling/jobs | Title, location, department, employment type, remote, description, dates |
| JazzHR | jazzhr | https://agatlaboratories.applytojob.com/apply | Title, location, department |
| Comeet | comeet | https://www.comeet.com/jobs/fiverr/60.002 | Title, location, department, employment type, remote, dates |
| B-ITE | bite | https://recruiting.fz-juelich.de | German 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.vinci | dvinci | https://jobs.dkfz.de | German 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)
| Platform | platform value | Example | Data and notes |
|---|---|---|---|
| ADP | adp | https://workforcenow.adp.com/mascsr/...?cid=GUID | 3 F500 companies. Two portal types: WorkforceNow (public OData) and MyJobs (Bearer token). |
| Taleo | taleo | https://textron.taleo.net/careersection/textron/jobsearch.ftl | 2 F500 companies (modern API portals). Classic FTL portals require browser rendering, see Enterprise ATS Jobs Scraper for those deployments. |
| Avature | avature | https://ally.avature.net/careers/SearchJobs/ | 3 F500 companies. HTML scraping with JSON-LD detail enrichment. Supports cross-domain redirects. |
| Brassring | brassring | https://sjobs.brassring.com/TGnewUI/Search/Home/Home?partnerid=25526&siteid=5032 | 7 F500 companies. Session-based Ajax API. Pagination at 50/page, no cap. |
| SuccessFactors | successfactors_rmk | https://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) | talentbrew | https://jobs.walgreens.com/en | 22 F500 companies. AJAX JSON+HTML pagination. |
| Oracle Recruiting Cloud | oracle_recruiting | https://eeho.fa.us2.oraclecloud.com/hcmUI/CandidateExperience/... | 27 F500 companies. REST finder API with comma-separated params. |
| Eightfold | eightfold | https://careers.nyl.eightfold.ai/careers | 15 F500 companies. PCSX + apply/v2 dual API fallback. |
| Phenom | phenom | {"platform":"phenom","company":"https://jobs.cvshealth.com"} | 35 F500 companies. SSR inline JSON extraction. Pass as object with platform+company. |
| iCIMS Jibe | icims_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)
| Platform | platform value | Example | Data and notes |
|---|---|---|---|
| Refline | refline | https://apply.refline.ch/673276/search.html | Swiss 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). |
| Prospective | prospective | https://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 Umantis | umantis | https://recruitingapp-2800.umantis.com/Jobs/All | Swiss 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 Portal | abacus | https://app.jobportal.abaservices.ch/job-overview/d9c5a048-f665-4e64-a2c7-cdd8231bac77 | Abacus 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. |
| Solique | solique | https://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. |
| Jobalino | jobalino | https://my.jobalino.ch/custel_jobExternalList/de/medisyn-sa | Swiss 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. |
| Dualoo | dualoo | https://jobs.dualoo.com/portal/etge4wyf | Swiss 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_classic | https://career55.sapsf.eu/career?company=BLS | SAP 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 Jobs | ethz | https://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) | onlyfy | https://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 Systems | rexx | https://jobs.green.ch/stellenangebote.html | German 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. |
| Ostendis | ostendis | https://www.bernaville.ch/stellen | Swiss 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.ch | publicjobs | https://www.publicjobs.ch/karriereseite/Gemeinde-Meilen/~art569 | publicjobs.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:
| ATS | Description | Notes |
|---|---|---|
| Lever, Greenhouse, Ashby, Teamtailor, Recruitee, Pinpoint | Yes, from the listing | 0% missing |
| Workday | Yes, one detail request per job | Detail 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. |
| Rippling | Yes, one detail request per job | 0% missing |
| SuccessFactors (RMK sites) | Yes, one detail page per job | 0% missing; the location and date are also taken from the listing row |
| SuccessFactors (classic portal) | Yes, from the feed | The 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 |
| Phenom | Yes, from the listing | 0% missing on the tested tenant |
| iCIMS Jibe | Yes, from the listing | Full HTML description in the same API response |
| Oracle Recruiting | Yes, one detail request per job | Read from the requisition details endpoint (description, responsibilities and qualifications joined). The listing alone carries no text on many tenants (for example Southern Company). |
| Eightfold | Yes, one detail request per job | Read from the position details endpoint, with the apply API as fallback |
| SmartRecruiters | Yes, one detail request per job | Read from the posting endpoint (company, job description, qualifications and additional information sections) |
| Refline, Prospective, ETH Zurich Jobs | Yes, one detail request per job (Prospective: from the portal API in one pass) | Full description from the posting page |
| Personio | No | Listing only |
| JOIN | No | Listing only |
| Comeet | No | Listing only |
| JazzHR | No | Listing only |
| Taleo | No | Listing only |
| Brassring | No | Listing only; the listing also has no location, so a location filter drops every row (counted in jobs_location_unknown) |
| Workable, BambooHR, iCIMS, TalentBrew, Avature, ADP | Not confirmed | Not 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):
| Company | Platform | Reason |
|---|---|---|
| American Airlines | SuccessFactors | WAF blocks TLS-fingerprinted requests |
| Corning | SuccessFactors | WAF blocks TLS-fingerprinted requests |
| Edison International | SuccessFactors | WordPress CWS career site, JavaScript-only job loading |
| Valero Energy | Taleo | Classic FTL portal requires browser-initialized session |
| D.R. Horton | Taleo | Classic FTL portal requires browser-initialized session |
| Cincinnati Financial | Taleo | Classic FTL portal requires browser-initialized session |
| Vulcan Materials | Taleo | Classic FTL portal requires browser-initialized session |
| NVR | Taleo | TBE variant, DWR facade has no job search method |
| Delta Airlines | Avature | AWS WAF JavaScript challenge |
| Jacobs Solutions | Avature | AWS WAF JavaScript challenge |
| Progressive | Jobvite | Cloudflare JavaScript challenge |
| SAIC | Jobvite | Cloudflare 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-scraperto 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-scraperto scrape job listings from Spotify (Lever), Rippling (Rippling), and Fiverr (Comeet). Which companies have the most remote roles?"
"Use
career-site-jobs-scraperto 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
| Field | Example |
|---|---|
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) |
remote | false |
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_locations | Workday 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
| Platform | location | department | type | remote | description | dates |
|---|---|---|---|---|---|---|
| Lever | Y | Y | Y | Y | Y | Y |
| Greenhouse | Y | Y | - | - | Y | Y |
| Ashby | Y | Y | Y | Y | Y | Y |
| Workable | Y | Y | - | Y | - | Y |
| Teamtailor | Y | Y | - | Y | Y | Y |
| Personio | Y | Y | Y | - | - | - |
| SmartRecruiters | Y | Y | Y | Y | - | Y |
| BambooHR | Y | Y | Y | - | - | - |
| Workday | Y | - | Y | Y | Y | Y |
| iCIMS | Y | - | - | - | - | - |
| Recruitee | Y | Y | Y | Y | Y | Y |
| JOIN | Y | Y | Y | - | - | Y |
| Pinpoint | Y | Y | Y | - | Y | - |
| Rippling | Y | Y | Y | Y | Y | Y |
| JazzHR | Y | Y | - | - | - | - |
| Comeet | Y | Y | Y | Y | - | 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.
| Event | Price | Description |
|---|---|---|
| Actor start | $0.001 | One-time per run |
| Job scraped | $0.001 each | Per 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
| Field | Type | Description | Default |
|---|---|---|---|
queries | array | Career page URLs or {platform, company} objects. An object may add country (ISO 3166-1 alpha-2) and employer (see below). | required |
maxJobsPerCompany | integer | Max jobs per company. 0 = all jobs (hard safety limit of 5000 per company, logged when hit). | 500 |
keywords | array | Only 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 |
location | string | Only jobs in this city, region or country. Uses the ATS location facets where available. | none |
postedWithinDays | number | Only jobs posted in the last N days. Jobs without a posting date are kept. | none |
sortBy | string | newest or relevance. | site order |
includeSummaryRows | boolean | Emit one job_extraction_done row per company. On automatically when any new input is used or the cap is 0. | auto |
residentialFallback | string | auto or off. Controls the proxy ladder for sites that block the normal connection (see below). off never uses residential proxies. | auto |
maxResidentialHosts | integer | Most different career-site hosts that may use residential proxies in one run. Empty = no limit. | unlimited |
includeDescription | boolean | Include full HTML job description in output | true |
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 afilter_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_atis 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
maxJobsPerCompany0 (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:
- Direct (the normal connection).
- Apify datacenter proxy (one attempt per request; Apify picks the datacenter group, and its pool is US only, so there is no country pin).
- 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.comhttps://{company}.jobs.personio.dehttps://jobs.smartrecruiters.com/{company}https://{company}.bamboohr.com/careers/listhttps://{company}.wd{N}.myworkdayjobs.com/{site}https://careers-{company}.icims.com/jobs/searchhttps://{company}.recruitee.comhttps://join.com/companies/{slug}https://{company}.pinpointhq.comhttps://ats.rippling.com/{company}/jobshttps://{company}.applytojob.com/applyhttps://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,atsorats_system; the address iscompany,urlorats_url. - Names are matched without regard to case.
successfactorsis the same assuccessfactors_rmk, andradancyis the same astalentbrew. - A name this actor does not read (for example
goldman_sachs) ends with reasonunsupported_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:
- 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. - 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. - Check the network tab: open browser DevTools (F12), go to Network, reload the careers page, and look for API requests to known ATS domains.
- Look at job listing URLs: click any open position. If it redirects to
jobs.lever.co/...orapply.workable.com/..., that's your ATS. - 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.
Related actors
- Job Feed: one input fans out to 100+ job boards plus company career sites, deduplicated, and uses this actor internally.
- Website Job Extractor: any company website to its careers page, job system and jobs. A browser variant handles JavaScript-rendered sites.
- Indeed Scraper: Indeed job listings in 60+ countries.
- Glassdoor Scraper: Glassdoor jobs with employer ratings and salary estimates.
- LinkedIn Jobs Scraper: public LinkedIn job listings, no login.
- StepStone Scraper: StepStone.de, Germany's largest job portal.
- Jobs.ch Scraper: jobs.ch, Switzerland's largest job board.
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.