Greenhouse, Lever & Ashby Job Scraper & Monitor
Pricing
Pay per usage
Greenhouse, Lever & Ashby Job Scraper & Monitor
Track job postings at your target companies. Get NEW, CHANGED and confirmed CLOSED events from Greenhouse, Lever and Ashby, with stable event IDs for deduplication. Ready for n8n and Slack. Free Actor; Apify platform usage applies.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Oleg Testov
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Share
Monitor a recruiter watchlist daily and get only new, changed and confirmed closed jobs from Greenhouse, Lever and Ashby. Connect the feed to n8n, Slack or Google Sheets. The Actor is free; Apify platform usage applies.
Quick start
- Run the sample watchlist and inspect CURRENT jobs.
- Replace it with your companies and save an Actor task.
- Schedule the task daily with the same Monitor ID. Later runs return only NEW, CHANGED and CLOSED rows; send them to Slack, Google Sheets, n8n or a webhook with Apify integrations.
The sample input has Show current jobs on the first run turned on, so the first run lists every open job as CURRENT. CURRENT rows are a baseline, not new-job alerts. Every later run with the same Monitor ID returns only what changed since the previous run; an empty dataset means nothing changed.
Who uses it
- Recruiters and staffing agencies: see new roles at target accounts the day they are posted, and know when a posting is taken down.
- Sales and growth teams: hiring signals. A company opening five data-engineer roles is a lead for a data tool.
- Job boards and job-alert products: a deduplicated feed of new postings straight from the employer's board.
- Investors and market analysts: new teams and new locations across a portfolio.
- AI agents (MCP): "which roles did these companies open or close since the last check?"
Example events
The three rows below are made-up examples (company "Acme"); real rows have the same fields.
A new job:
{"changeType": "NEW","eventId": "5c1f0e9a7b2d4c6e8a10","company": "Acme","ats": "greenhouse","title": "Senior Data Engineer","locations": ["Madrid, Spain"],"workplaceType": "hybrid","department": "Engineering","url": "https://job-boards.greenhouse.io/acme/jobs/1234567","postedAt": "2026-10-06T09:12:00Z","checkedAt": "2026-10-07T06:00:00Z"}
A changed job, with the old value:
{"changeType": "CHANGED","eventId": "9d2a4b6c8e0f1a3b5c7d","company": "Acme","ats": "ashby","title": "Staff Backend Engineer","changedFields": ["title"],"previousValues": {"title": "Senior Backend Engineer"},"url": "https://jobs.ashbyhq.com/acme/0b6e7c1a-4d2f-4e8a-9c3b-2f1d5a7e9c11","checkedAt": "2026-10-07T06:00:00Z"}
A closed job:
{"changeType": "CLOSED","eventId": "e4f6a8b0c2d4e6f8a0b2","company": "Acme","ats": "lever","title": "Account Executive, DACH","url": "https://jobs.lever.co/acme/7a1c3e5b-9d2f-4b6a-8c0e-1f3a5c7e9b2d","firstSeenAt": "2026-09-14T06:00:00Z","closedAt": "2026-10-07T06:00:00Z","checkedAt": "2026-10-07T06:00:00Z"}
| changeType | Meaning |
|---|---|
NEW | The job appeared since the previous run |
CHANGED | Title, department, team, location, workplace type, employment type or salary changed. changedFields and previousValues show what changed |
CLOSED | The posting disappeared from the board and the closure was confirmed (closedAt is set) |
CURRENT | Snapshot mode, or the first run when Show current jobs on the first run is on |
All fields: eventId (stable id of this change, for de-duplication), changeType, company, ats, boardId, boardUrl, detection, checkedAt, jobId, title, url, applyUrl, department, team, locations, workplaceType (onsite / hybrid / remote), employmentType, postedAt, updatedAt, salaryMin, salaryMax, salaryCurrency, salaryPeriod, salaryText, requisitionId, changedFields, previousValues, firstSeenAt, closedAt, and description (empty unless you turn on Include job description).
Input
- Companies to watch, one per line. Board URLs are most reliable:
https://job-boards.greenhouse.io/stripe,https://jobs.lever.co/palantir,https://jobs.ashbyhq.com/ramp. A company name (Stripe), a domain or careers page (ramp.com) or an explicit board (greenhouse:stripe,lever-eu:<slug>) also work; check what was detected in the run'sSUMMARYbefore you schedule. Optional label:Stripe | stripe.com. - Monitor ID identifies this watchlist's saved history in your Apify account. Keep it unchanged for recurring checks; use another ID (for example
recruiter-watchlist) for a separate watchlist. Changing it starts a new baseline. - Show current jobs on the first run: on in Apify Console. API calls and tasks that leave it out keep it off, and the first run then only saves the baseline.
- Optional filters: title keywords (
engineer,data), excluded words (intern), location (Spain,remote), department. Filters only reduce output rows. - Output mode = Full snapshot every run returns every open job each time instead of changes.
The saved state lives in a named key-value store ats-job-monitor-<id>-<hash> in your own Apify account (the exact name is in the run's SUMMARY); delete it to start over. The SUMMARY record lists every input line with its status, detected board, open jobs and counts.
API and AI agents
- API: the API tab on this page shows ready-made calls.
run-sync-get-dataset-itemsstarts a run and returns its rows in one request. - MCP: connect your AI client to the Apify MCP server (
https://mcp.apify.com) and find this Actor with thesearch-actorstool ("greenhouse lever ashby job monitor"). The first call with a new Monitor ID only saves a baseline (pass"emitBaselineOnFirstRun": trueto also get the current jobs); an agent cannot get yesterday's changes without an earlier run.
Price
The Actor has no fee. Apify charges your account for compute, storage and other applicable platform usage. We will announce any Actor fee at least 14 days before enabling it.
Delivery
Delivery is at-least-once. If the rows were written but saving the state failed, the next run sends the same changes again with the same eventId. De-duplicate by eventId if your destination must not see a change twice. A later, separate occurrence of the same change (for example a title that changes back and forth) gets a new eventId. A missing or damaged saved state (new Monitor ID, deleted store, or a record with the wrong structure) starts a new baseline with new eventId values. If the saved state cannot be read at all (a storage error), that company's check fails for this run: no rows, no charge, and the state is left as it was.
Safety against false "closed" alerts
Closures require two missing observations and an additional check. Large disappearances are held for review. CLOSED means the posting disappeared; it does not establish that someone was hired.
- A failed or detectably bad read is an error for that company and changes nothing: HTTP 403 or 429, timeouts, a Greenhouse response whose
meta.totalis missing or differs from the jobs returned, an error response, postings without id or title, or the same id twice. - A job is reported
CLOSEDonly after it has been missing in 2 runs in a row (set Confirm closure after N runs). Before closing, the board is read once more; a job present in that read stays open and its count starts over. A job that reappears in any later run starts over too. - Mass disappearances are held, not closed. When 3 or more jobs and more than 30% of a board vanish in one check, they stay pending: no
CLOSEDrows,pendingClosuresin the run summary. A source that keeps returning the same cut-down list looks exactly like this, and the Actor cannot tell the two apart. Turn on Report mass disappearances as closed if you prefer those closures. - If the saved state is missing or damaged, the run saves a new baseline and reports no changes.
Sources and compliance
- Only the official public job-board APIs that employers use to publish their jobs: Greenhouse Job Board API, Lever Postings API and Ashby Job Posting API. No login, no cookies, no browser, no proxy.
- To find a company's board, the Actor reads robots.txt first and fetches at most four pages of the company website (the given URL,
/careers,/jobs, the home page). The result is cached for 30 days. - No personal data fields. Email addresses and phone numbers are removed from every text field (title, department, team, locations, salary text, company name, your input labels, descriptions, the run summary and error texts), in the output and in the saved state. Fields that are not plain text or numbers are dropped. A job URL must be https with a normal host and no contact in its path or parameters; otherwise the Actor uses the board's standard posting URL (apply URLs are dropped). Job descriptions are off by default; a description may still name a contact person if the employer wrote it there. Every dataset row, every record the Actor stores and every log line passes the same contact filter on the way out (URL-encoded text is decoded first; runs of 9+ digits count as phone numbers unless they are the posting's own id). Number ranges without a currency ("45.000 - 55.000") are removed from free text as possible phone numbers, but kept in the structured
salaryTextfield when each amount has a thousands separator, a currency or a "k", and the text names no contact. Phone detection is pattern-based: it covers common formats but cannot promise to catch every way a number can be written. - Requests are rate-limited per host.
- The Actor runs with limited permissions: it uses only its own storages in your account.
Limits
- Supported job boards: Greenhouse, Lever, Ashby. Other systems (Workday, Workable, Recruitee, SmartRecruiters, Personio and others) are reported as "not supported in this version".
- One run works for at most 1 hour (or until its run timeout, if shorter). Shortly before that it stops starting new companies and saves nothing more, and at the limit it stops the company in progress. Companies it did not finish are listed as skipped in
SUMMARYwith what was really done; if rows were output but the state was not saved, the next run sends those changes again with the sameeventId. Split very long watchlists into several tasks with different Monitor IDs. - Don't run two copies on the same Monitor ID at once; the second one exits without changes. It checks whether the run recorded in the Monitor ID's state is still running. If that run's status cannot be read, the second run stops until 5 minutes after the first run's time limit and says when to retry. This is a check, not a lock: two runs started at the same moment can both proceed, and then they may report the same changes twice or overwrite each other's saved state. In a rare case a save that the first run sent just before its time limit can still be stored after the second run has started; the effect is the same (changes reported again with the same
eventId, or one run's saved state replaced by the other's). - Detection by name or domain can miss companies that embed jobs with custom code. Pass the board URL then. Rows found by guessing a name are marked
detection: "slug-guess". - Structured salary comes from Ashby and Lever where the employer publishes it; salary text changes are reported too. Greenhouse usually puts salary only in the description.
FAQ
Why is my dataset empty? Nothing changed since the previous run with this Monitor ID, or it was the first run with Show current jobs on the first run off (then it only saved the baseline). The run's status message and SUMMARY show the counts per company.
Can I get the same change twice? Yes, rarely: after a failed state save the next run re-sends it with the same eventId.
Can I get the full list every run? Yes: Output mode = Full snapshot every run.
How many companies per run? Up to 5,000 lines; 5 companies are checked in parallel by default. A run stops after 1 hour; split longer watchlists.
My company is not found. Open its careers page, click any job, and paste that board URL (for example https://jobs.lever.co/acme). If it uses another system, open an issue and tell us which one.