Career Site Jobs Watch: Greenhouse, Lever & Ashby
Pricing
from $2.00 / 1,000 job rows
Career Site Jobs Watch: Greenhouse, Lever & Ashby
Pull open roles from company career sites on Greenhouse, Lever and Ashby, and see what changed since your last run: new jobs, closed jobs and net hiring change per company. Clean job data, a hiring summary and a readable report.
Pricing
from $2.00 / 1,000 job rows
Rating
0.0
(0)
Developer
Sama Alabed
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Pull open roles directly from company career sites and track what changed between runs. Supports Greenhouse, Lever and Ashby. Get clean job data plus new, still-open and closed roles by company, a hiring-change summary and a readable report.
It answers one question: what changed at these companies since I last looked?
Who it is for
- Sales and GTM teams watching target accounts for hiring signals (a company opening 8 sales roles is a buying signal).
- Recruiters and agencies tracking which clients and competitors are hiring or freezing.
- Investors and analysts following portfolio or watchlist companies.
- Job seekers and job boards who want fresh roles from specific companies without re-reading every careers page.
- AI agents and automations that need clean, structured hiring data through one API call.
What you get
For every company you add:
- Current open jobs in one schema across all three job systems: title, department, team, location, workplace type, employment type, posted pay (when the company publishes it), posted date, job link and apply link.
- New jobs: jobs that appeared since the last run of your monitor.
- Closed jobs: jobs that were open last time and are gone now.
- A company summary: open, new, closed and net change, in plain language ("Acme added 8 jobs and closed 3 (net +5), 42 open jobs now.").
- A run summary: totals, companies hiring up or down, biggest increases and decreases, who is hiring the most, and which fetches failed.
- An HTML report (the
REPORTrecord in the run's key-value store) that answers the same questions at a glance.
Supported job systems
| Job system | Paste a link like | Notes |
|---|---|---|
| Greenhouse | https://job-boards.greenhouse.io/discord | Also accepts boards.greenhouse.io, EU boards, embed links and single job links. |
| Lever | https://jobs.lever.co/palantir | Global and EU (jobs.eu.lever.co) boards, posting and apply links. |
| Ashby | https://jobs.ashbyhq.com/linear | Board, job and application links. Unlisted (direct-link-only) jobs are skipped. |
You can also paste:
- A single job link. The whole board of that company is watched.
- A company's own careers page, such as
https://example.com/careers. It is read once and accepted only if it links to exactly one supported board. Many careers pages load jobs with JavaScript; if nothing is found, paste the board link itself. - A short form, such as
greenhouse:discord,lever:palantir,lever-eu:acmeorashby:linear.
Other systems (Workday, Workable, SmartRecruiters, iCIMS and more) are recognised and get a clear "not supported yet" status row. They are never silently dropped.
Input
{"companies": [{ "url": "https://job-boards.greenhouse.io/discord", "name": "Discord" },{ "url": "https://jobs.lever.co/palantir" },{ "url": "https://jobs.ashbyhq.com/linear" }],"monitorName": "my-watchlist","includeOpenJobs": true,"includeNewJobs": true,"includeClosedJobs": true,"includeDescriptions": false}
| Field | Default | What it does |
|---|---|---|
companies | required | List of { "url": "...", "name": "optional label" }. Plain URL strings also work through the API. |
monitorName | none | Use the same name on future runs to track new and closed jobs. Without a name, runs with the same set of companies share a monitor automatically. |
includeOpenJobs | true | Return jobs that were already open last time. Turn off to get only what changed. |
includeNewJobs | true | Return jobs that appeared since the last run. |
includeClosedJobs | true | Return jobs that disappeared since the last run. |
includeDescriptions | false | Add the full job description text. This makes results much larger. |
Output
The dataset is ordered for easy reading and parsing:
- Company rows (
record_type: "company"), one per company you entered, in your order. - Job rows (
record_type: "job"): new jobs first, then closed, then still open. - One summary row (
record_type: "summary") at the end.
Job row:
{"record_type": "job","monitor_id": "my-watchlist","company_id": "greenhouse:discord","company_name": "Discord","ats": "greenhouse","job_id": "greenhouse:discord:8806482002","source_job_id": "8806482002","status": "new","title": "Commercial Policy Lead","department": "Policy","team": null,"location": "San Francisco Bay Area","workplace_type": null,"employment_type": null,"compensation": null,"job_url": "https://job-boards.greenhouse.io/discord/jobs/8806482002","apply_url": null,"posted_at": "2026-09-15T16:52:11.000Z","first_seen_at": "2026-09-29T20:00:00.000Z","last_seen_at": "2026-09-29T20:00:00.000Z","closed_at": null,"fetched_at": "2026-09-29T20:00:00.000Z"}
Company row (abridged):
{"record_type": "company","company_name": "Linear","company_id": "ashby:linear","ats": "ashby","status": "ok","open_jobs": 28,"new_jobs": 1,"closed_jobs": 3,"net_change": -2,"change_summary": "Linear added 1 job and closed 3 jobs (net -2), 28 open jobs now."}
Summary row (abridged):
{"record_type": "summary","companies_checked": 3,"companies_succeeded": 3,"companies_failed": 0,"current_open_jobs": 396,"new_jobs": 4,"closed_jobs": 6,"net_job_change": -2,"companies_hiring_up": 1,"companies_hiring_down": 1,"headline": "4 new jobs and 6 closed jobs across 3 companies (net -2). 396 jobs open now. 1 hiring up, 1 hiring down."}
Nulls are honest. A field is null when the job board does not publish it. Nothing is guessed. Greenhouse, for example, publishes no workplace type or country, and its applications happen on the job page, so apply_url is null there.
Company status values
| Status | Meaning | Charged |
|---|---|---|
baseline | First successful check in this monitor. Jobs are saved; changes appear from the next run. | yes |
ok | Checked and compared with the last run. | yes |
empty | The board exists but has no open jobs. | yes |
held | The board suddenly returned no jobs. Closures wait for the next run to confirm (see below). | yes |
failed | The board could not be read (for example HTTP 503 after retries). | no |
not_found | No such board (HTTP 404). | no |
invalid_url | The link could not be understood. The message says how to fix it. | no |
unsupported | A job system we do not support yet, or a careers page without a supported board link. | no |
ambiguous | A careers page links to several boards; add the one you want. | no |
duplicate | The same board appears twice in your list. It is checked and charged once. | no |
not_checked | Over the run limit or your maximum cost per run. | no |
How monitoring works
- A monitor is your list of companies plus its history. History lives in a key-value store named
career-site-jobs-watch-historyin your own Apify account. Nothing is stored anywhere else. - For each company, the monitor keeps the ids of currently open jobs (with title, location, department and link) and the last 52 snapshots of what changed. Job descriptions are never stored.
- Jobs are identified by the job board's own id, never by title. Two roles with the same title are two jobs; a renamed job is still the same job.
- The first check of a company is a baseline: its jobs are reported as
open, notnew. - Schedule it (daily or weekly) in Apify Schedules with the same monitor name to get a steady change feed.
Failure safety
- One company failing never fails the run. It gets
status: "failed"and every other company is processed normally. - A failed fetch never marks jobs closed. The previous snapshot is kept untouched, and the next successful run compares with it.
- A board that returns zero jobs after having jobs is
held. Its jobs are marked closed only if the next run is empty too, because an empty answer can be a glitch. - A board larger than the per-company limit (5,000 jobs) is read up to the limit. New jobs are reported but closures are not, because the list is incomplete.
- If some new or closed rows cannot be returned (because of your maximum cost per run), that company's history is not advanced, so those changes are reported again next run instead of being lost.
Duplicates
- Repeated feed entries and page overlaps are merged by job id.
- If one role is published as several postings (for example one per city), each posting is kept, because the job board treats them as separate postings with their own links.
source_group_id(Greenhouse) andrequisition_idshow which postings belong together.
API usage
One JSON request is all you need:
curl -X POST "https://api.apify.com/v2/acts/koalabed~career-site-jobs-watch/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"companies":[{"url":"https://jobs.lever.co/palantir"}],"monitorName":"weekly-watch","includeOpenJobs":false}'
Filter rows by record_type. For changes only, set includeOpenJobs: false: you then get company rows, new and closed jobs, and the summary.
MCP / AI agents
The Actor works through the Apify MCP server, like any Apify Actor. Agents can call it with one JSON input (companies plus an optional monitorName) and read structured rows back. The summary row carries a plain-language headline, and each company row carries a change_summary, so an agent can answer "what changed at these companies?" without further processing.
Pricing
Pay per event. You pay for:
- each company whose job board was read (company checked), and
- each job row returned.
Companies that could not be checked (failed, not found, invalid, unsupported, duplicate, over a limit) are free. Choose only new and closed jobs (includeOpenJobs: false) to keep scheduled watches cheap. The current prices are on the Pricing tab. Set Maximum cost per run in the run options to cap any run: new and closed jobs are returned first when a cap applies.
Free Apify plan: up to 5 companies and 100 job rows per run.
Limits
- Up to 200 companies per run on paid Apify plans (5 on the free plan), and 25,000 job rows per run.
- Up to 5,000 jobs read per company.
- Only jobs the company has published on its public job board. Internal and unlisted postings are not visible.
- Job descriptions are optional and capped at 20,000 characters each.
- The HTML report lists up to 150 new and 150 closed jobs; the dataset has all of them.
- Workday, SmartRecruiters, Workable and others are not supported in this version.
Privacy and sources
- The Actor reads only public job-board feeds that companies publish for their own careers pages: the Greenhouse Job Board API, the Lever Postings API and the Ashby public Job Posting API. It never logs in, uses no credentials or cookies, and does not bypass any protection.
- Requests are polite: a few at a time, spaced per host (Lever's requested 1-second crawl delay is honoured), with a small number of retries and backoff.
- Job postings contain no personal data beyond what the employer chose to publish. Every job links back to its original posting.
- Your monitor history stays in your own Apify account.