Greenhouse Jobs Feed + Lever, Ashby & Workable: New & Closed avatar

Greenhouse Jobs Feed + Lever, Ashby & Workable: New & Closed

Pricing

from $1.50 / 1,000 job posting rows

Go to Apify Store
Greenhouse Jobs Feed + Lever, Ashby & Workable: New & Closed

Greenhouse Jobs Feed + Lever, Ashby & Workable: New & Closed

Greenhouse jobs plus Lever, Ashby and Workable postings from public job boards in one flat schema with salary, location and remote fields. Change mode returns only new, changed or closed postings since your last run. No recruiter fields; emails and phone numbers removed from descriptions.

Pricing

from $1.50 / 1,000 job posting rows

Rating

0.0

(0)

Developer

Jack Valmadre

Jack Valmadre

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Categories

Share

Greenhouse, Lever, Ashby & Workable Jobs Feed — New & Closed

Get the open jobs of any company that publishes its job board on Greenhouse, Lever, Ashby or Workable, in one flat table — and, on a schedule, only the postings that are new, changed or closed since your last run.

It reads the public job-board APIs these applicant-tracking systems provide for employers' careers pages (plain JSON, no login, no browser, one request per board), so runs are quick and cheap.

SystemWhat to enterSalary fields
Greenhousegreenhouse:stripe or https://boards.greenhouse.io/stripewhen the employer publishes a pay range
Leverlever:spotify or https://jobs.lever.co/spotify (EU: https://jobs.eu.lever.co/...)when the employer publishes a pay range
Ashbyashby:linear or https://jobs.ashbyhq.com/linearwhen the employer publishes a pay range
Workableworkable:skroutz or https://apply.workable.com/skroutznever (Workable's public job list has no salary field)

What you can use it for

  • Keep a job board, newsletter or niche jobs site up to date with new postings and remove closed ones.
  • Watch hiring at a list of companies (new teams, new locations, roles closing).
  • Salary and remote-work research across employers that publish pay ranges.

Input

FieldWhat it does
boardsOne board per line: greenhouse:stripe, lever:spotify, ashby:linear, workable:skroutz, or a board URL (https://boards.greenhouse.io/figma, https://jobs.lever.co/spotify, https://jobs.ashbyhq.com/linear, https://apply.workable.com/skroutz). EU-hosted Lever boards (https://jobs.eu.lever.co/...) work too; EU-hosted Greenhouse boards (boards.eu.greenhouse.io), single Workable job links (https://apply.workable.com/j/...) and Workable careers sites on a company's own domain are not supported and are reported as invalid. Up to 500 per run. Also accepted as startUrls, urls or companies.
modefull (default): every open posting on every run, marked new / changed / unchanged, plus closed ones. changes: only new, changed and closed postings since the previous run with the same boards; the first run returns every open posting as new. Use changes for scheduled runs.
maxRowsStop after this many rows (each row is one charged job-row event). The input form starts at 10 so a first try costs about US$0.015; clear it (or set 0) to get every posting. Leave it out when calling the API and there is no limit. Also accepted as maxItems.
includeDescriptionAdds the plain-text job description (off by default; about 7 times larger output in our test). Email addresses and phone numbers are removed.
stateStoreNameName of the key-value store in your account that remembers the previous run (default ats-job-feed-state).
resetStateForget the history for these boards and start over.

The board name is the part of the careers-page URL after the domain (for https://jobs.lever.co/spotify it is spotify; for https://apply.workable.com/skroutz it is skroutz).

How the change feed works

The actor keeps the postings it saw in a named key-value store in your own Apify account (default ats-job-feed-state), one record per distinct board list (the record key is a hash of the sorted boards, so the order and URL form don't matter). Schedule the actor with the same boards and mode set to changes — for example daily — and each run returns only what changed. Changing mode or includeDescription keeps the history. Editing the board list starts a new history for the new list. The record is small (about 24 KB for 272 postings in our test) and named stores are kept until you delete them.

  • A posting is changed when its title, team, location, workplace type, employment type, salary, links or description change. Greenhouse's updated_at alone does not count (Greenhouse updates it without visible edits).
  • A closed posting appears once, on the first run after it disappeared, then never again.
  • A board that fails to load (network error, 404) keeps its history and never produces closed rows; the run summary lists it.
  • A run stopped early by your maximum cost per run or by maxRows saves history only for the postings it wrote: the rest come back on the next run, and boards it didn't reach never produce closed rows.
  • Rows are written before the history is saved, so an interrupted run can repeat rows on the next run but never lose a change.

Output

One dataset row per posting, same fields for all four systems (missing values are null):

source, board, company, job_id, posting_key (source:board:job_id, stable across runs), title, department, team, location, all_locations, country, workplace_type (remote / hybrid / onsite), remote, employment_type, salary_min, salary_max, salary_currency, salary_interval, salary_text, url, apply_url, published_at, updated_at, description, change_type (new / changed / unchanged / closed), first_seen_at, closed_at, scraped_at.

Example row (real output for Figma's Greenhouse board, 2026-09-25, description shortened):

{
"source": "greenhouse", "board": "figma", "company": "Figma", "job_id": "5426468004",
"posting_key": "greenhouse:figma:5426468004", "title": "Account Executive, Enterprise",
"department": "Sales", "location": "San Francisco, CA • New York, NY • United States",
"salary_min": 165000.0, "salary_max": 190000.0, "salary_currency": "USD",
"url": "https://boards.greenhouse.io/figma/jobs/5426468004?gh_jid=5426468004",
"published_at": "2025-01-28T18:57:29-05:00", "change_type": "new",
"first_seen_at": "2026-09-25T09:41:36Z", "closed_at": null
}

The run summary (key-value store record OUTPUT) lists each board's status (ok, not_found, error, invalid, duplicate), counts of new / changed / unchanged / closed postings, and a warning when a board is empty (companies that move to another applicant-tracking system often leave an empty board behind).

What the data covers (measured)

Field coverage depends on what each employer fills in. On 21 real boards on 2026-09-25 (4,651 postings), a salary was present on 33% of Greenhouse, 35% of Lever and 66% of Ashby postings, and a remote flag on 17%, 100% and 78%. On Greenhouse, salary_text is the employer's label for the pay range (e.g. "Annual Base Salary Range:") and salary_interval is usually empty.

Workable (3 real boards on 2026-09-27, 54 postings): the salary fields are always empty; country, remote and all_locations were filled on every posting, department on 51 and employment_type on 41; workplace_type is set only for remote jobs. Workable lists a job once per location; the actor returns it as one row with every location in all_locations, so the row count matches the job total on the company's Workable careers page (33, 19 and 2 jobs on these boards).

Limitations

  • Only Greenhouse, Lever, Ashby and Workable job boards. Companies using other systems (Workday, iCIMS, SmartRecruiters, Personio, Recruitee and others) are not covered; a company that moved away shows as not_found or empty.
  • You supply the boards; the actor doesn't discover companies or search all jobs.
  • Only postings the employer publishes on the public board (Ashby unlisted postings are skipped).
  • A board whose address redirects to another site is reported as an error and keeps its history (no false closed rows).
  • Personal data: recruiter and hiring-manager fields, Greenhouse custom fields and internal ids are never copied, and email addresses and phone numbers are removed from descriptions. Names of people that appear inside the free text of a description are not removed; switch descriptions off if you don't need them.
  • Postings are the employers' own job ads. You are responsible for how you use and republish them.

Politeness

One request per board per run (up to 2 retries on errors), at least 1 second between requests to the same host (Lever's robots.txt asks for this), and a clear user agent. Only the public read-only endpoints are used; no applications are submitted.

Use with AI agents and other actors

Input is plain JSON, e.g. {"boards": ["greenhouse:stripe", "ashby:linear", "workable:skroutz"], "mode": "changes"}; startUrls in the usual [{"url": "..."}] form also works. Each row has a stable posting_key for de-duplication.

Pricing

Pay per event: US$0.0015 per dataset row (job-row), plus a start fee of US$0.00005 per GB of run memory, charged once per run (at most US$0.00005 at the default 256 MB). Every row counts: in full mode (the default) that is every open posting plus closed ones, in changes mode only new, changed and closed postings. There is no extra charge for Apify platform usage. Apify shows the price before you run, and you can set a maximum cost per run. When that budget (or maxRows) runs out, the run writes as many rows as it covers — part of a board if need be — then stops, succeeds, and says so in its status message; the OUTPUT record marks the cut board partial and the boards after it not_read. Nothing is lost in the change feed: postings whose row wasn't written keep their saved history, so the next run with these boards still reports them as new, changed or closed, and boards that weren't read never produce closed rows.

Support

Please use the Issues tab of this actor. We aim to respond within 14 days. This actor is built and supported with AI assistance; a human owner can be reached on request through the Issues tab.

Publisher: Madrasco. Not affiliated with Greenhouse, Lever, Ashby or Workable.