Company Jobs Scraper for 5 ATS Platforms avatar

Company Jobs Scraper for 5 ATS Platforms

Pricing

from $1.50 / 1,000 results

Go to Apify Store
Company Jobs Scraper for 5 ATS Platforms

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

Samo Karapetyan

Maintained by Community

Actor 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 platform to group/filter it.
  • RESULTS in the default key-value store: schemaVersion, filters and a platforms array, each with platform, 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:

FieldsMeaning
schemaVersion, recordId, platform, sourceJobIdSchema version, stable record key, source platform and original ID
companyName, companyWebsite, boardUrlVerified publishing organization and source board
title, locations, departmentsSource job title and lists of locations/departments
employmentType, workplaceTypeEmployment and workplace information when explicit
descriptionText, descriptionHtmlComplete available description in original language
salaryText, salaryMin, salaryMax, salaryCurrency, salaryPeriodExplicit available compensation; missing information is not inferred
jobUrl, applyUrlOriginal announcement and application links
publishedAt, updatedAt, scrapedAtSource 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

StatusMeaning
successAt least one job collected with no reported errors/limits
no_jobsA matching board explicitly returned an empty open-jobs list
not_foundNo matching board was found; this does not prove the company has no jobs
partialUseful results or a verified empty board exist, but errors or limits prevent a complete claim
blockedRequests were blocked and no successful board was processed
errorCollection/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:

FieldMeaning
companyPresencefound: 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.
careerUrlsAll verified matching board URLs, including boards with zero open jobs
totalJobsUnique open listings on the verified boards, independent of the optional global result limit; null if the count cannot be established
returnedJobsJobs actually returned in this run
boardsPer-board companyName, boardUrl, totalJobs; multiple same-name organizations remain separate
countScopeverified_boards: counts describe discovered, verified boards, not a guarantee of exhaustive platform coverage
discoveryLimitedSearch 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 ApifyClient
client = 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.