Greenhouse Jobs Scraper & Change Monitor avatar

Greenhouse Jobs Scraper & Change Monitor

Pricing

$10.00 / 1,000 board checkeds

Go to Apify Store
Greenhouse Jobs Scraper & Change Monitor

Greenhouse Jobs Scraper & Change Monitor

Scrape public Greenhouse job boards and track new, updated, removed, and reappearing jobs across runs. Export job details and descriptions for recruitment workflows, hiring analysis, and job alerts. Pay per successful board check, regardless of job count.

Pricing

$10.00 / 1,000 board checkeds

Rating

0.0

(0)

Developer

Flowmint

Flowmint

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Export public Greenhouse job listings or track how selected boards change across runs. This Greenhouse jobs scraper uses the public job board API, without a browser, Greenhouse login, or candidate data. The job change monitor maintains a complete baseline for each board and emits changes into an Apify dataset.

You supply the boards. This Actor does not discover every company or claim complete coverage of the hiring market. It is an independent product with no official Greenhouse affiliation.

Three-minute quick start

In Apify Console, enter a board token such as stripe, choose Snapshot, and start the Actor. Open Output, select Snapshot jobs, and export JSON or CSV. Read Run summary for successful checks and source errors.

For monitoring, choose Monitor, enter a stable ID such as daily-greenhouse, and run again with that same ID. The first successful check initializes each board. Existing jobs are labeled initial; they are not presented as newly published. Later checks can emit added, changed, removed, or reappeared. An empty event dataset is a normal result when nothing changed.

Locally, use Node.js 22.14+ or Node.js 24 LTS:

npm ci
npm run check
npm start -- examples/snapshot-input.json
npm start -- examples/monitor-input.json
npm start -- examples/monitor-input.json

Each direct local invocation creates a separate storage/datasets/run-<runId>/ and storage/key_value_stores/run-<runId>/. The log prints the run ID through the summary and output location. Named monitor stores persist under storage/key_value_stores/gh-monitor-v1-<hash>/. Keep the storage directory between monitor runs. On Apify, results and SUMMARY use the run's default storages.

Input

FieldDefaultMeaning
boardsrequired1–100 unique tokens or approved URLs after deduplication; at most 1000 raw entries
modesnapshotCurrent job records or persistent monitoring events
monitorIdrequired in monitor mode1–64 safe letters/digits/underscores/hyphens; starts with a letter or digit
titleKeywords[]Case-insensitive substring phrases; OR within the list
locationKeywords[]Same matching rule against source location; AND with title filter
includeDescriptiontrueShow full snapshot descriptions or monitor excerpts; comparison always includes descriptions
firstRunOutputallinitial events or none, independently for each newly initialized board
removalConfirmations22–5 complete successful checks before removal is confirmed
maxConcurrency31–5 simultaneous HTTP fetches; commits and charges are sequential
requestTimeoutSeconds305–120 seconds per attempt, including response body

Keyword lists allow up to 100 nonempty phrases, each at most 200 characters. Unknown input fields are rejected. Snapshot mode ignores monitoring-specific behavior and never reads or changes monitor history.

Approved inputs include stripe, https://boards.greenhouse.io/stripe, https://boards.greenhouse.io/stripe/jobs/123, and https://boards-api.greenhouse.io/v1/boards/stripe/jobs. Tracking queries and fragments are ignored; even a job URL selects the whole board. Only the constructed HTTPS API endpoint is fetched. Encoded paths, credentials, custom ports, unrelated company domains, regional endpoints, and other hosts, including job-boards.greenhouse.io, are outside the verified v1 input allowlist. Tokens are canonicalized to lowercase. region: "global" identifies the supported API endpoint; it does not classify a job's geography.

Output

Snapshot datasets contain only job records. Monitor datasets contain only event records. Errors and totals are stored in SUMMARY.json in the default key-value store, using the API record key SUMMARY. All boards failing makes the run fail. A mix of successful and source-failing boards preserves good results with a partial-success report. Budget exhaustion stops further checks and is explained in the report.

Job records contain source, boardToken, region, boardName, jobId, globalId, internalJobId, title, location, departments, offices, language, jobUrl, optional descriptionHtml and descriptionText, sourceUpdatedAt, firstSeenAt, lastSeenAt, fetchedAt, and metadata. Missing nullable values are null; missing collections are []. Board names are used only when supplied by the response, otherwise null. sourceUpdatedAt is an update timestamp, not a publication date. Snapshot firstSeenAt and lastSeenAt are null.

Entity arrays contain {id, name, location, parentId, childIds}. Metadata contains {id, name, valueType, value}; value remains source JSON. There is no inferred salary, seniority, or remote-work status. The Actor does not call the individual-job endpoint to obtain salaries or first-publication dates.

Events contain eventId, eventType, observedAt, previousObservedAt, globalId, boardToken, region, job, changedFields, and snapshotKey. The monitor's nested job has a maximum 500-character text excerpt when descriptions are enabled. Full descriptions remain in the unfiltered KV snapshot and monitor baseline. Description diffs contain before/after SHA-256 hashes and readable excerpts of at most 500 characters around the difference. Other diffs contain the actual before/after values.

See examples/snapshot-output.json and examples/monitor-output.json; both are generated from deterministic fixtures, not customer data. On Console, use the Monitor events view for nested event fields. JSON preserves arrays and objects. For CSV, select fields such as eventType,boardToken,job.title,job.location,eventId; complex values should be retained as JSON or flattened by your downstream tool. API exports support pagination; do not assume the first response page contains every result.

Large KV records are JSON envelopes with _format: "greenhouse-json-gzip-v1", a checksum, logical byte length, and gzipBase64. Download and decode a snapshot or baseline with:

node scripts/unpack-record.mjs downloaded-record.json decoded-record.json

Small KV records, including SUMMARY, remain plain JSON. The dataset itself always contains normal JSON records.

Monitoring rules

The baseline contains the entire board, independently of output filters. Changing filters does not reclassify existing jobs as new or removed. changed is emitted when title, location, departments, offices, description HTML/text, or job URL changes after canonicalization. Arrays and object keys are ordered and incidental whitespace is normalized; numbers and meaningful text are retained. A change to sourceUpdatedAt, metadata, language, or internal ID alone does not trigger an event.

removed means no longer listed on the source board. It does not prove that someone was hired or recruitment permanently ended. Failed checks do not increase absence counters. A return before confirmation resets the counter; a return after confirmation produces reappeared. Confirmed tombstones expire after 90 days, on the next complete check; a later return can then be added.

Run one active Actor per monitorId. Best-effort leases detect common conflicts but are not atomic locks. Use one sequential task/schedule and avoid manual or API runs that overlap it. docs/MONITORING.md cover journals, migration, recovery, retention, and reset.

Billing and limits

When PPE is enabled, the only paid event is board-checked, charged once per unique successfully processed board in a run. A check is billable even if the board is empty, the filters match nothing, or no job changed. Input errors, failed/incomplete fetches, and HTTP retries are not charged. Local runs never issue real charges; private free cloud runs remain uncharged by this adapter.

Results are durably prepared and delivered before charging and committing the baseline. A budget refusal leaves the baseline uncommitted. Delivery is at least once; deduplicate events by eventId. Dataset, KV, and billing are separate systems. An ambiguous charge stops processing and may require manual review; exactly-once billing and output are not claimed.

The proposed launch price is $10 per 1000 board checks ($0.01 each), pending private cloud cost measurements and approval. At that proposal, 10 boards checked daily for 30 days cost $3 in event fees. This is a proposal, not an active paid offering or a measured cloud cost. docs/PRICING.md separates measurements, estimates, and Console configuration.

Safety ceilings are 20,000 raw jobs and 32 MiB of HTTP response per board; logical journals/state are capped at 48 MiB and compressed stored records at 8 MiB. Exceeding any ceiling makes the board incomplete without advancing its baseline. Lists are never truncated to simulate a complete check. HTML is parsed as data, never executed; consumers should treat exported HTML and URLs as untrusted source content.

Deployment and responsible use

docs/DEPLOYMENT.md explains private upload, limited permissions, two sequential cloud tests, and publication. docs/VALIDATION_REPORT.md records what was actually executed. Use Apify Tasks, Schedules, and its Integrations tab for automation; this Actor sends no emails or arbitrary webhooks itself.

Use source listings for job portals, recruiting research, and market analysis with appropriate attribution and retention. Respect source terms and applicable rights. Descriptions can include publicly provided contact information; restrict access and retain only what your workflow needs. Monitoring stores full descriptions even if includeDescription=false. No candidate profiles, applications, or private Harvest API data are collected.

Original project code is MIT licensed. Dependency licenses remain applicable; see docs/DEPENDENCY_LICENSES.md.