ATS Job Monitor: Greenhouse, Lever & Ashby Scraper
Pricing
from $1.00 / 1,000 job events
ATS Job Monitor: Greenhouse, Lever & Ashby Scraper
Get live jobs from Greenhouse, Lever and Ashby in one exportable feed. Track new, changed, reopened and removed listings with cautious history checks. No login or proxy needed.
Pricing
from $1.00 / 1,000 job events
Rating
0.0
(0)
Developer
Antonio Mancuso
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Get live job postings from company career boards in one consistent feed. Export current jobs, or schedule a feed of new, changed, reopened and removed listings for a job board, recruiting workflow or hiring research.
Paste board URLs, choose your filters, and download JSON, CSV or Excel from Apify. No source API key, browser or proxy is needed.
Quick start
- Copy a company's Greenhouse, Lever or Ashby job-board URL.
- Add it under Company job boards and click Start.
- Open Job events to inspect or download your results. Open Run summary for coverage and board health.
{"boards": ["https://boards.greenhouse.io/stripe","https://jobs.lever.co/leverdemo","https://jobs.ashbyhq.com/Ashby"],"mode": "snapshot","maxResults": 5000}
These providers were validated on Apify cloud on October 17, 2026. Availability and job counts change.
Monitor new and removed jobs
{"boards": ["greenhouse:stripe", "ashby:Ashby"],"mode": "changes","historyKey": "daily-hiring","titleKeywords": ["engineer", "data"],"maxJobsPerBoard": 5000,"maxResults": 10000}
Save this input as an Apify task and schedule it daily. Reuse the history name in your account. The first complete run returns matching jobs as new. Later runs skip unchanged jobs in changes mode. Apify integrations can deliver the dataset to your own database, n8n, Make or Google Sheets.
Use one schedule per history name. A server-managed lock protects the entire monitoring run. An overlapping run exits with HISTORY_BUSY, reads no boards and incurs no board or row fees; the automatic start fee still applies. After an abrupt stop, the lock can take up to two minutes to expire. Different history names operate independently.
Changing title/location/remote filters or removal-confirmation settings creates a fresh baseline. Changing description visibility or switching output mode preserves it. Use a new history name to reset monitoring. A deleted history cannot be reconstructed.
Pricing
Launch pricing (configured and verified privately on Apify):
| Event | Price | What it covers |
|---|---|---|
| Readable board scan | $0.015 | A valid source read and a board report, including empty or unchanged boards |
| Job event | $0.001 | One current job or lifecycle row saved to the dataset |
| Actor start | $0.00005 | Apify's automatic event per container start at 512 MB, including resurrection |
Examples: one board with 100 returned jobs costs $0.11505; the same unchanged board in changes mode costs $0.01505. Ten boards with 1,000 total job events cost $1.15005. Pay per event + usage is disabled. Source errors and malformed feeds have no board-scan charge; the start event still applies. A readable board over your job limit is a charged scan with a partial snapshot in snapshot mode and no rows in changes mode.
Analyzed jobs are not charged per row. In snapshot mode every matching current job is returned and charged. In changes mode only matching new, changed, reopened or newly confirmed removed rows are returned and charged. For example, scanning 1,000 unchanged jobs on one board costs $0.01505 in changes mode, versus $1.01505 for an unfiltered snapshot. The scan fee makes periodic monitoring sustainable even when there are no changes. The first monitoring baseline is charged for its returned new rows.
Set Maximum cost per run in Apify Run options, as well as maxResults. Maximum at default input limits: boards × $0.015 + maxResults × $0.001 + $0.00005. Source failures can make a run unproductive; use board reports to correct invalid URLs. Budget-limited boards do not advance history when output is incomplete. A new run is a separately billed scan and can repeat rows from an incomplete baseline. To recover a crashed run, use Resurrect on that same run instead of Start.
Supported input
| Source | Accepted board reference |
|---|---|
| Greenhouse | greenhouse:stripe, https://boards.greenhouse.io/stripe, https://job-boards.greenhouse.io/stripe |
| Lever global | lever:leverdemo, https://jobs.lever.co/leverdemo |
| Lever EU | lever-eu:company, https://jobs.eu.lever.co/company |
| Ashby | ashby:Ashby, https://jobs.ashbyhq.com/Ashby |
Slugs retain their case. A supported job-detail URL is reduced to its board. Only listed API hosts are contacted; arbitrary company websites are not crawled. Lever EU must be selected explicitly. An empty list, unknown host or invalid option stops the run before source requests. Duplicate board references are removed.
You supply the companies. There is no global job search or company discovery. Workday, LinkedIn, Indeed and applicant/candidate data are outside this product's scope.
| Option | Default | Meaning |
|---|---|---|
mode | snapshot | Current matching jobs; with history, also freshly confirmed removals |
historyKey | empty | Optional persistent history name; required for changes |
titleKeywords, locationKeywords | empty lists | Case-insensitive OR within each list; AND between the two lists |
remoteOnly | false | Require a source remote label or “remote” in the location |
includeDescription | true | Plain text, email addresses masked, maximum 8,000 characters |
maxJobsPerBoard | 3,000 | Maximum processed jobs per board; allowed 1–5,000 |
maxResults | 10,000 | Total saved job rows; allowed 1–20,000 |
maxRunSeconds | 300 | Application time budget, 10–1,800 seconds |
requestTimeoutSeconds | 25 | Per-attempt timeout, 2–60 seconds |
missingConfirmations | 2 | Complete missing readings before removal, 2–5 |
minMissingIntervalSeconds | 3,600 | Minimum spacing between missing readings, 300–86,400 seconds |
Up to 50 boards per run. Transient network errors, HTTP 429 and selected server errors receive up to two retries. Long Retry-After values stop that board instead of retrying early. A response may contain up to 20 MiB of decoded JSON. HTTP 401/403, HTML challenges and redirects are not bypassed.
Output
Each dataset row is a job or job lifecycle event, with a stable id, a deterministic eventId, source, board, title, department, location, workplace type, source dates, URLs, description and observation dates. Missing values are null.
| Field | Interpretation |
|---|---|
changeType | snapshot, new, changed, unchanged, removed, reopened |
firstSeenAt, lastSeenAt | Your monitor's observations, not source publication dates |
publishedAt, updatedAt | Source dates when available; never invented |
salaryMin, salaryMax, salaryCurrency, salaryInterval | Source-structured pay fields when exposed, mainly Lever; no estimated or annualized salaries |
compensationText | Ashby's published compensation summary when available |
descriptionTruncated | Whether the displayed description was shortened |
contentHash | Detects meaningful normalized changes, including text beyond display truncation |
Greenhouse's list endpoint does not provide the detail endpoint's pay-transparency ranges; those are left null. Ashby's compensation bands are not flattened into a guessed global numeric range. company is normally the board slug rather than a verified legal company name. Country and seniority are not inferred. Unknown remote status stays unknown; a location-text match is a heuristic.
Full schema: schemas/job.schema.json. Real local sample: reports/sample-jobs.json in the source package. Apify provides CSV/XLSX export automatically; use full JSON when you need all fields, or choose columns for a spreadsheet export.
The run key-value store contains RUN_SUMMARY, BILLING_AUDIT and one BOARD-… report per visited board. analyzedJobs counts all normalized current postings before filters and caps; rows counts delivered dataset rows; emittedEventCounts breaks those rows down by type. newJobsDetected counts new postings, while actualChangesDetected counts changed, reopened and removed postings before output filters. lifecycleCounts classifies processed postings; for a size-limited board it only covers the processed slice. chargeableBoards counts valid readable scans; billedBoards counts scans submitted under PPE, and BILLING_AUDIT records the SDK event counters. Non-monetized runs have zero billed counters. Board reports remain available even when no job matches.
How removal detection works
A posting is marked removed only after it is absent from multiple complete, successful source reads with the configured spacing. Missing from a public board does not prove that a vacancy was filled. Failures, malformed feeds, job caps and incomplete output never advance the board's history.
If at least half of a previously active board with 10 or more jobs disappears, a consistent extra reading is required before missing confirmations begin. This also delays removal when an employer legitimately empties its board. Reappearing removed jobs become reopened. Removed metadata is retained for 90 days, then discarded; later appearances become new. Old descriptions are not stored in history, so removal rows contain metadata and description: null.
History stores at most 20,000 entries per board. Cloud runs save their work plan and operation journal before delivering or billing results. Resurrecting the same run ID resumes the frozen plan, verifies an interrupted append against the existing dataset and never resubmits a previously attempted board or row charge. This protection remains effective beyond Apify's three-minute API idempotency window. A completed run can be resurrected without creating another scan or another copy of its rows.
Charges with an uncertain outcome are never retried; an unconfirmed fee may be waived in the customer's favor. Apify automatically charges another $0.00005 start event on resurrection; the Actor reserves it within the remaining budget. If an interrupted append cannot be verified, the run stops with RECOVERY_UNCERTAIN, preserving history and attempting no additional row write or fee. Inspect that run before starting a fresh scan. The default dataset is append-only, so the product prioritizes preventing duplicate delivery and charges over silently retrying an ambiguous write. A recovery may wait up to about two minutes for the previous process's lock to expire.
Keep the run's key-value storage intact until recovery is complete. Missing journals, changed input or a conflicting newer history stop recovery safely. Runs created before the recovery upgrade cannot be resurrected with the new build if they already contain data or charges: they stop with LEGACY_RUN_CANNOT_RESUME. New run IDs have independent billing; the protection is not an unlimited free rescan across distinct runs. eventId remains useful for downstream deduplication.
Data access and responsible use
The Actor reads the documented public Greenhouse Job Board API, Lever Postings API and Ashby Job Postings API. It does not authenticate, submit applications, collect candidates or circumvent access controls. Public access does not grant unrestricted reuse rights: use boards and job content only as permitted by the source, employer and applicable terms. Email masking reduces incidental exposure; descriptions can still contain names or other personal information. Review retained data and your reuse rights before redistribution.
Limited Apify permissions are sufficient. History and its lock queue are created in the running user's account. Store names hash the Actor ID, running user ID and history name; different users and different monitors have separate namespaces. No data is sent to an external analytics service. Stop the schedule and delete its named history store and lock queue to remove retained metadata; manage dataset and run-storage retention in your Apify account separately. This product is independent of the ATS vendors.
Troubleshooting
HTTP_404: verify the board's exact slug and region. A company may have moved ATS.HTTP_401/HTTP_403: access was denied; the Actor stops that source.INVALID_SCHEMA/INCOMPLETE_SOURCE: the source changed or returned incomplete data; history is preserved.PARTIAL_SOURCE_LIMIT: increasemaxJobsPerBoardwithin the hard limit, or monitor a smaller board. Snapshot mode returns a partial untracked snapshot; changes mode returns no rows for that board. History stays unchanged.HISTORY_BUSY: another run holds this monitor's lock. Retry after it finishes; allow two minutes after a crash.RECOVERY_UNCERTAIN: an interrupted append has no verifiable receipt. It was not repeated or billed again; inspect existing output, then start a fresh scan if needed.RECOVERY_HISTORY_CONFLICT/RECOVERY_IDENTITY_MISMATCH: history or input changed while the run was interrupted. Recovery stops without overwriting newer data.LEGACY_RUN_CANNOT_RESUME: start a new run with the current build; the older run has no recovery journal.PARTIAL_OUTPUT_LIMIT/LIMIT_REACHED: raise your result, time or cost limit for a complete board sync.- No changes: inspect the board reports; unchanged boards still produce scan reports and charges.
When every board fails, the run fails. Mixed source failures produce a usable partial run with PARTIAL_FAILURE in RUN_SUMMARY. Monitor this summary in addition to Apify run status. Report an issue with your run ID and a non-sensitive board URL.
Developer commands
pnpm install --frozen-lockfile --ignore-scriptspnpm testpnpm checknode scripts/run-local.js examples/snapshot.jsonpnpm smoke
smoke reads live public sources without calling Apify runs. It uses in-memory state and simulated event charges. Deployment, prices, operational checks and private cloud acceptance evidence are documented in docs/ and reports/cloud/. The private validation harness is excluded from the customer Actor. Monetization activation and paid receipts are separate from technical acceptance; see the current launch report.