Company Jobs Scraper for 5 ATS Platforms
Pricing
from $1.50 / 1,000 results
Company Jobs Scraper for 5 ATS Platforms
Search a company's jobs across Greenhouse, BambooHR, Comeet, JazzHR, and Jobvite. Get verified career links, ATS job counts, and standardized openings for recruiting research, lead generation, job boards, JSON/CSV exports, and API workflows. Actively maintained, with more ATS platforms planned.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
Samo Karapetyan
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
17 hours ago
Last modified
Categories
Share
Company Jobs Scraper for Greenhouse, BambooHR, Comeet, JazzHR & Jobvite
Use this company jobs scraper and ATS job scraper API to search a company name once and get its verified career pages, open-job counts and standardized vacancies across Greenhouse, BambooHR, Comeet, JazzHR and Jobvite. Build recruiting research, job-market intelligence, lead generation, job boards and automated JSON/CSV/API workflows without finding each career page manually.
Actively maintained and expanding
This Actor is actively maintained. We will continue improving its discovery and adding support for more ATS and career platforms while keeping the standardized output stable. Have a platform or improvement to suggest? Open a request in the Issues tab. We'll be happy to review customer feedback and prioritize additions that benefit the community.
Pricing
The launch price is $0.01 per run plus $1.50 per 1,000 saved jobs ($0.0015 per Dataset item). Platform usage is included in the event price. An optional maxItems input controls the maximum number of paid job rows returned in a run; platform metadata still reports the full counts found on verified boards.
Input
{"filters": {"companyName": "Webflow"},"platforms": ["greenhouse", "bamboohr", "comeet", "jazzhr", "jobvite"]}
Only filters.companyName is required. The platform list defaults to all five. With no limit, every discovered job is returned.
maxItems is an optional positive integer limiting the combined job list across all platforms. It is allocated in the order of platforms. For example, if three platforms each have 600 jobs and maxItems is 1,000, metadata reports 600 / 600 / 600, while the job list returns 600 / 400 / 0. All platform metadata is still collected after the job limit is filled.
Company names match in full after Unicode normalization, case folding, punctuation removal, whitespace normalization and trailing legal-suffix removal. ACME, Inc. matches Acme; Acme Labs does not. All matching boards are retained; similarly named companies are never silently merged. The company is the organization publishing the board; for recruitment agencies, a job's client can differ and remains in the source description.
Discovery checks plausible ATS board addresses and queries DuckDuckGo's public HTML search. A search result is only a candidate: the company name must be confirmed by the source. Up to 20 candidates per platform are checked. Search can be blocked or incomplete, particularly for Comeet, whose company identifier cannot always be derived from its name.
Public sources do not guarantee complete discovery. No paid search service, source account or private ATS API key is required. No CAPTCHA solving is attempted. The Actor price is described above; post-run Dataset access or retention can still incur Apify's standard storage charges.
Extensible platform support
Each ATS integration is implemented as an adapter with the same discovery, collection and normalization contract. New platforms can therefore be added without changing the standardized job records or platform metadata returned to existing customers.
What can you build with this company job openings API?
- Recruiting research: see where a target company publishes vacancies and review all discovered openings in one table.
- Job boards and aggregators: export standardized records to JSON or CSV instead of maintaining five separate ATS parsers.
- Hiring and market intelligence: monitor hiring volume, departments and locations for companies you follow.
- Lead generation: identify organizations with active hiring and use verified career links in downstream enrichment workflows.
- ATS discovery: use platform metadata to learn which supported applicant tracking systems a company uses, even when a verified board currently has zero jobs.
The Actor searches public sources at run time. Treat the results as a current snapshot of discovered, verified boards rather than a guarantee that every page on the public web was found.
Results
- Default Dataset: one job per row, exportable to JSON/CSV. Use
platformto group/filter it. RESULTSin the default key-value store:schemaVersion,filtersand aplatformsarray, each withplatform,status,jobs,errors,truncated,metadata.RUN_SUMMARY: counts, duration, attempted/skipped boards, failures and discovery limits. Dataset and grouped JSON use the exact same records.
The fixed job contract is in schemas/job.schema.json:
| Fields | Meaning |
|---|---|
schemaVersion, recordId, platform, sourceJobId | Schema version, stable record key, source platform and original ID |
companyName, companyWebsite, boardUrl | Verified publishing organization and source board |
title, locations, departments | Source job title and lists of locations/departments |
employmentType, workplaceType | Employment and workplace information when explicit |
descriptionText, descriptionHtml | Complete available description in original language |
salaryText, salaryMin, salaryMax, salaryCurrency, salaryPeriod | Explicit available compensation; missing information is not inferred |
jobUrl, applyUrl | Original announcement and application links |
publishedAt, updatedAt, scrapedAt | Source dates and UTC collection timestamp |
Missing scalar values are null; missing lists are []. Source dates preserve their precision: a date-only value is not converted to an invented midnight timestamp. updatedAt is never substituted for publication time. Source HTML is not sanitized for embedding; sanitize it before displaying in your own application.
Record IDs derive from platform + canonical board URL + source job ID (or canonical job URL if no ID is available). Duplicates within a board/platform are removed. Cross-platform postings remain separate. Schema 1.0 fields and meanings are stable; adding a platform adds another element to the result array. Consumers should accept new platform names.
Statuses
| Status | Meaning |
|---|---|
success | At least one job collected with no reported errors/limits |
no_jobs | A matching board explicitly returned an empty open-jobs list |
not_found | No matching board was found; this does not prove the company has no jobs |
partial | Useful results or a verified empty board exist, but errors or limits prevent a complete claim |
blocked | Requests were blocked and no successful board was processed |
error | Collection/discovery failed and no successful board was processed |
Search blocking can make a platform partial even when its supplied board was completely collected. Inspect the per-board summary to distinguish discovery limitations from extraction errors. Boards after the shared optional limit is reached are not_attempted in the summary. If all platforms fail or are blocked, the Actor saves diagnostics and marks the run failed. A valid search with no match can succeed with zero rows.
Platform metadata
Each platform also returns metadata in RESULTS and RUN_SUMMARY:
| Field | Meaning |
|---|---|
companyPresence | found: company verified on a source board; not_found: no matching board found in the completed search; unknown: search/check failed or was blocked. not_found is not proof of absence from the entire platform. |
careerUrls | All verified matching board URLs, including boards with zero open jobs |
totalJobs | Unique open listings on the verified boards, independent of the optional global result limit; null if the count cannot be established |
returnedJobs | Jobs actually returned in this run |
boards | Per-board companyName, boardUrl, totalJobs; multiple same-name organizations remain separate |
countScope | verified_boards: counts describe discovered, verified boards, not a guarantee of exhaustive platform coverage |
discoveryLimited | Search failed, was blocked, or reached its candidate limit |
A known empty board has companyPresence: "found" and totalJobs: 0. An unavailable source has an unknown count (null), never an invented zero. A failed job-detail request does not erase a successfully established listing count. Listing counts are snapshots; a job can close between listing and detail requests.
The Actor enumerates listing pages for metadata even after the optional global detail limit is reached. This adds listing requests, but does not download every job's details. If a board count fails, its known presence/link is retained. Grouped results and summary use schema version 1.2; the job-row contract stays 1.0, with all 24 fields unchanged. Earlier saved result artifacts are historical and may not contain metadata or the current global-limit semantics.
Supported source surfaces
Greenhouse jobs scraper
Uses the public Greenhouse Job Board API, including the available job content. The Actor verifies the company identity before adding the board and standardizes every job into the shared output schema.
BambooHR jobs scraper
Reads public BambooHR careers listings and job-detail pages. Company identity comes from public page data, so a guessed subdomain is never accepted as proof of a match.
Comeet jobs scraper
Reads public hosted Comeet job pages and their embedded company and position data. Employee-only positions are excluded, and no private Comeet API token is required.
JazzHR jobs scraper
Collects public *.applytojob.com/apply boards using structured job data with an HTML fallback. The same standardized fields are returned as for every other supported ATS.
Jobvite jobs scraper
Collects public jobs.jobvite.com/{company}/jobs boards, follows category expansion and pagination links, and uses structured data with an HTML fallback. An unsupported legacy or custom layout is reported as an extraction error instead of a false empty result.
Browser rendering is attempted for unrecognized dynamic HTML boards/details. It only reads public pages, uses the same request limits and does not submit applications. Arbitrary custom ATS layouts are not guaranteed. Public boards may change during a run.
Run the Actor through the API
Replace YOUR_APIFY_TOKEN with your Apify API token. The synchronous endpoint below waits for the run and returns Dataset rows directly.
cURL
curl -X POST \"https://api.apify.com/v2/acts/samvelkarapetyan~company-jobs-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"filters":{"companyName":"Webflow"},"platforms":["greenhouse","bamboohr","comeet","jazzhr","jobvite"]}'
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("samvelkarapetyan/company-jobs-scraper").call(run_input={"filters": {"companyName": "Webflow"},"platforms": ["greenhouse", "bamboohr", "comeet", "jazzhr", "jobvite"],})jobs = list(client.dataset(run["defaultDatasetId"]).iterate_items())print(f"Collected {len(jobs)} jobs")
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('samvelkarapetyan/company-jobs-scraper').call({filters: { companyName: 'Webflow' },platforms: ['greenhouse', 'bamboohr', 'comeet', 'jazzhr', 'jobvite'],});const { items: jobs } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Collected ${jobs.length} jobs`);
Frequently asked questions
Do I need to know the company's careers URL or ATS?
No. Provide filters.companyName; the Actor searches the selected platforms, verifies matching public boards and returns discovered links in metadata.careerUrls and metadata.boards.
Can I use this as a career page scraper?
Yes. It discovers supported ATS career pages by company name and returns both board metadata and normalized jobs. A custom career site outside the supported ATS platforms is not collected in this version.
Does the Actor guarantee every job on the internet?
No. It reports every job found on the verified boards it discovers, but free public search can be blocked or incomplete. Check status, errors, countScope and discoveryLimited before making completeness claims.
What happens when a company has no open jobs?
A verified empty board is returned as companyPresence: "found", totalJobs: 0 and status no_jobs. This is different from not_found, which means that no matching board was discovered.
Can I limit the number of returned jobs?
Yes. Set the optional global maxItems. Platform metadata still reports the full listing counts found on verified boards, while the Dataset contains at most the requested number of job rows.
Which ATS platform will be supported next?
Lever, Ashby, Workday, SmartRecruiters and Workable are candidates for future adapters. Open an Issue to request a platform or describe an integration you need.
Changelog
- 0.3 — September 2026: name-only input, global optional result limit, verified platform metadata, stable cross-platform output and new Store presentation.
- Future releases will add and improve ATS adapters while preserving the existing standardized job and metadata contracts. Incompatible changes require a new
schemaVersion.
Local use
Python 3.12:
python -m venv .venv.venv/Scripts/python -m pip install -r requirements-dev.txt.venv/Scripts/python -m playwright install chromium.venv/Scripts/python -m pytest -q
Place input JSON at storage/key_value_stores/default/INPUT.json, then run python -m src. Use fresh local storage for each run; existing local Dataset rows can otherwise remain.
docker build -t company-jobs-scraper .docker run --rm -v "<absolute-storage-path>:/usr/src/app/storage" company-jobs-scraper
The Docker image installs Chromium and its system dependencies. Start with 1 GB memory and a 30-minute timeout when deploying privately, then tune from actual runs. Large descriptions, many boards or browser fallback can require more memory/time. Maximum jobs is not a spending cap.
Scheduling, application submission and historical new/closed-job tracking are not part of this version. See DEVELOPMENT.md and RELEASE.md for extension instructions and verification evidence.