Greenhouse + Lever Job Boards Feed (Unofficial)
Pricing
from $2.00 / 1,000 job saveds
Greenhouse + Lever Job Boards Feed (Unofficial)
Jobs from public Greenhouse and Lever job boards in one schema, with change tracking: each run flags new, changed and closed jobs. A failing board never fails the run. Company and job fields only; optional descriptions have emails, phones and names removed. Not affiliated with Greenhouse or Lever.
Pricing
from $2.00 / 1,000 job saveds
Rating
0.0
(0)
Developer
Gray Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
What does Greenhouse + Lever Job Boards Feed (Unofficial) do?
This Actor turns public company job boards hosted on Greenhouse and Lever into one clean, flat job feed, and tells you what changed since your last run: every row is marked new, changed or unchanged, and jobs that were taken down are reported once as closed.
Give it a list of companies (a board token or just the job board URL) and schedule it. Each run reads every board, normalises the jobs into one schema, checks each row against that schema, and saves it with a link to the original job page.
- Change tracking built in. No diffing on your side: use
onlyChangesto get just the new, changed and closed jobs each day. - A bad board never fails the run. A company that moved off Greenhouse, a typo, a 500 error or a slow API only affects that one board. It is listed with a plain-language reason in the run summary, and every other board is still saved.
- Retries and polite pacing. Temporary errors are retried with backoff, rate-limit responses are respected, and requests are spaced out per source.
- No account or API key needed. Both sources are public, read-only job APIs.
This Actor is unofficial. It is not affiliated with, endorsed by, or sponsored by Greenhouse Software, Inc., Lever, or Employ Inc. It reads the job postings that companies publish on their public job boards.
What data can you extract?
Company and job fields only. There are no recruiter, hiring-manager or other person fields.
| Field | What it is |
|---|---|
jobKey | Stable unique key: greenhouse:<board>:<id> or lever:<company>:<id> |
source, sourceName, board | greenhouse or lever, the source's name, and the board token or company name |
companyName | Company name as shown on the Greenhouse board (Lever's API does not provide one) |
jobId, requisitionId | The posting's id and, where published, the company's requisition id |
title, departments, team | Job title, department(s) and team |
location, allLocations, country | Location text, all listed locations, country code (Lever) |
workplaceType, isRemote | remote, hybrid or on-site (Lever); isRemote also from Greenhouse locations |
employmentType | e.g. Full-time (Lever) |
salaryMin, salaryMax, salaryCurrency, salaryInterval | Pay range when the company publishes one in the structured field (Lever) |
postedAt, updatedAt, applicationDeadline | Dates as published by the source |
jobUrl, applyUrl | Link to the original job page and the application page |
description, descriptionRedactions | Full description, only when Include full job descriptions is on (otherwise null), with personal details removed (see Privacy), and how many were removed |
changeStatus, firstSeenAt, lastSeenAt, closedAt | Change tracking (see below) |
retrievedAt | When this run read the job |
Change tracking
With trackChanges on (default), the Actor remembers each board's jobs in a named key-value store in your account (job-boards-feed-state). History is kept per feed, so separate feeds never interfere:
- Run from a saved task: the task is the feed. Two tasks that watch the same board each get every job as
newthe first time, and each keeps its own history. - Run directly (API or Console, no task): the feed is the combination of boards and filters (keywords, locations, departments, workplace types; order and letter case don't matter). Changing the boards or filters starts a new feed, whose first run reports every job as
new. ChangingonlyChanges,includeClosed,includeDescriptions,maxJobsormaxRequestskeeps the history. Two direct runs with exactly the same boards and filters share one history; use separate tasks if you need them apart.
RUN_SUMMARY.stateFeedId shows which feed a run used. On the next run of the same feed:
new: the job was not on the board last time.changed: title, location, department, pay, description or another job field changed.unchanged: same as last time (skip these withonlyChanges; skipped rows are not charged).closed: the job was on the board last time and is gone now. It is reported once with its last known details andclosedAt, then forgotten.
Safety rules:
- A board that fails in a run never marks its jobs as closed.
- A board whose rows were not all saved (for example because
maxJobswas reached) keeps its previous state, so nothing is missed next time. - A posting that is still listed but can't be read this run (for example a missing title) is not reported as closed; it keeps its history and is reported normally once it's readable again. If a posting has no readable id at all, no job on that board is marked closed in that run.
- A posting that fails the output check is kept in the history, so it is not re-reported as
newlater. If it was never delivered, it is reported asnewonce, when it first passes; it is never reported asclosed. firstSeenAtis the first run of the feed that saw the job.
Reliability
- Each board is fetched and processed in isolation. Errors are recorded per board in
RUN_SUMMARYwith a reason such as "says this board does not exist (HTTP 404)". - The run only fails if every board fails. If some fail, the run succeeds with status
partial. - Temporary errors (timeouts, 5xx) are retried with exponential backoff. HTTP 429 waits for the time the API asks for.
- Requests are paced per source (Lever: at least 1 second apart, as its robots.txt asks).
maxRequestscaps HTTP calls per run, retries included;maxJobscaps saved rows.- Every row is validated against the output schema; postings without a title or link are skipped and counted.
Use cases
- Daily feed of new openings at a list of companies, for a job board, newsletter or community.
- Labour-market and hiring-trend research: how many roles a set of companies opens and closes per week, by department or location.
- Monitoring remote or hybrid roles in a field across many company boards.
- Keeping your own careers aggregator in sync, including removing closed roles.
How to use it
- Add companies under Greenhouse boards (e.g.
acmeorjob-boards.greenhouse.io/acme) and/or Lever companies (e.g.acmeorjobs.lever.co/acme). - Optionally filter by title keywords, locations, departments or workplace type.
- Run it. Schedule it daily and turn on Only output changes for a change feed.
- Read the jobs from the dataset and the per-board results from
RUN_SUMMARY.
Finding the board name: open the company's careers page. If job links go to boards.greenhouse.io/<name>, job-boards.greenhouse.io/<name> or jobs.lever.co/<name>, that <name> is what you enter. You can also paste the URL.
Input examples
These are also in the examples/ folder.
Daily change feed for a few companies (schedule it daily; only new, changed and closed jobs are saved) (examples/daily-change-feed.json):
{"greenhouseBoards": ["gitlab", "figma", "job-boards.greenhouse.io/airbnb"],"leverCompanies": ["spotify", "jobs.lever.co/palantir"],"onlyChanges": true,"maxJobs": 2000}
Remote engineering roles at a few companies (examples/remote-engineering.json):
{"greenhouseBoards": ["gitlab", "figma"],"leverCompanies": ["spotify"],"keywords": ["engineer", "developer", "sre"],"workplaceTypes": ["remote"],"maxJobs": 500}
One company's remote engineering roles, with full descriptions, without change tracking (examples/one-company-with-descriptions.json):
{"greenhouseBoards": ["gitlab"],"departments": ["Engineering"],"locations": ["Remote"],"includeDescriptions": true,"trackChanges": false,"maxJobs": 100}
Output example
Real sample: 3 rows from a test run on October 17, 2026, with the default input (links shown without ``; the dataset has full links). With Include full job descriptions on, description holds the cleaned text, for example "This posting was created by [name removed] for the demo. Call [phone removed]. ...", and descriptionRedactions counts the removals (here 3).
[{"jobKey": "greenhouse:greenhouse:8126988","source": "greenhouse","sourceName": "Greenhouse public job board","board": "greenhouse","companyName": "Greenhouse","jobId": "8126988","title": "Commercial Counsel","departments": ["Legal Team"],"team": null,"location": "Eastern Timezone","allLocations": ["Eastern Timezone", "United States of America"],"country": null,"workplaceType": null,"isRemote": null,"employmentType": null,"salaryMin": null,"salaryMax": null,"salaryCurrency": null,"salaryInterval": null,"requisitionId": "2026 - P3178","language": "en","postedAt": "2026-08-24T13:52:04-04:00","updatedAt": "2026-10-09T18:28:27-04:00","applicationDeadline": "2026-10-26T19:00:00-04:00","jobUrl": "job-boards.greenhouse.io/greenhouse/jobs/8126988?gh_jid=8126988","applyUrl": null,"description": null,"descriptionRedactions": null,"changeStatus": "unchanged","firstSeenAt": "2026-10-17T23:56:54.029Z","lastSeenAt": "2026-10-18T00:04:40.285Z","closedAt": null,"retrievedAt": "2026-10-18T00:04:40.285Z"},{"jobKey": "lever:leverdemo:ad208490-4052-4f91-a57e-433f2d1e484b","source": "lever","sourceName": "Lever public job postings","board": "leverdemo","companyName": null,"jobId": "ad208490-4052-4f91-a57e-433f2d1e484b","title": "Customer Success Manager","departments": ["Customer Success"],"team": "Customer Success Team","location": "Atlanta, Georgia","allLocations": ["Atlanta, Georgia"],"country": "US","workplaceType": "hybrid","isRemote": false,"employmentType": "Regular Full Time (Salary)","salaryMin": 85000,"salaryMax": 175000,"salaryCurrency": "USD","salaryInterval": "per-year-salary","requisitionId": null,"language": null,"postedAt": "2026-08-31T18:12:19.703Z","updatedAt": null,"applicationDeadline": null,"jobUrl": "jobs.lever.co/leverdemo/ad208490-4052-4f91-a57e-433f2d1e484b","applyUrl": "jobs.lever.co/leverdemo/ad208490-4052-4f91-a57e-433f2d1e484b/apply","description": null,"descriptionRedactions": null,"changeStatus": "new","firstSeenAt": "2026-10-18T00:04:40.787Z","lastSeenAt": "2026-10-18T00:04:40.787Z","closedAt": null,"retrievedAt": "2026-10-18T00:04:40.787Z"},{"jobKey": "greenhouse:greenhouse:8279752","source": "greenhouse","sourceName": "Greenhouse public job board","board": "greenhouse","companyName": "Greenhouse","jobId": "8279752","title": "Enterprise Account Executive","departments": ["Account Executive"],"team": null,"location": "London, United Kingdom","allLocations": ["London, United Kingdom", "United Kingdom"],"country": null,"workplaceType": null,"isRemote": null,"employmentType": null,"salaryMin": null,"salaryMax": null,"salaryCurrency": null,"salaryInterval": null,"requisitionId": "2026 - Generating6","language": "en","postedAt": "2026-10-14T11:52:46-04:00","updatedAt": "2026-10-14T11:52:46-04:00","applicationDeadline": null,"jobUrl": "job-boards.greenhouse.io/greenhouse/jobs/8279752?gh_jid=8279752","applyUrl": null,"description": null,"descriptionRedactions": null,"changeStatus": "unchanged","firstSeenAt": "2026-10-17T23:56:54.029Z","lastSeenAt": "2026-10-18T00:04:40.285Z","closedAt": null,"retrievedAt": "2026-10-18T00:04:40.285Z"}]
How much does it cost?
Pay per event, with no subscription:
- $0.01 per run start,
- $0.002 per board checked successfully (failed boards are not charged),
- $2.00 per 1,000 jobs saved ($0.002 per row,
closedrows included; unchanged rows skipped byonlyChangesare free).
Example: 20 companies with about 1,000 jobs in total cost about $0.01 + $0.04 + $2.00 = $2.05 per full run. A daily onlyChanges run usually costs much less than a full run, because only changes are saved. Set a maximum cost per run in the run options and the Actor stops cleanly when it is reached.
Privacy: company and job data only
- The output has no person fields. Greenhouse custom fields (which companies sometimes use for recruiter or hiring-manager names) are dropped entirely.
- Full job descriptions are off by default. Rows still have the title, company, location, department, links and dates. Descriptions are each employer's own text; turn them on only if you need them.
- With Include full job descriptions on, descriptions are plain text with email addresses, phone numbers, profile links (LinkedIn, Calendly, X/Twitter) and names after cues such as "contact", "recruiter", "hiring manager", "reports to", "created by" or "my name is" replaced with placeholders like
[name removed]. - Limits: a name written with no such cue (for example a bare "Alex will onboard you") can't be told apart from other capitalised words and may remain. Leave Include full job descriptions off (the default) if you need zero free text.
- Use the data for job-related purposes. Don't use it to contact people.
Limits
- Greenhouse boards hosted in the EU region (
job-boards.eu.greenhouse.io) are not supported yet and are rejected with a clear message. - Lever's postings API does not include the company name, so
companyNameis empty for Lever rows (boardholds the company's Lever name). - Neither API supports server-side filtering, so filters are applied after download: each board is still read in full.
- Workplace type comes from Lever's structured field. Greenhouse boards only reveal "remote" when the location says so.
- Description text is the employer's own, and only lightly cleaned. Change detection still notices description edits when descriptions are off (rows are marked
changed, without the text). - The sources do not publish rate limits. The Actor paces itself and stops a board after repeated rate-limit responses.
- Change tracking remembers up to 100,000 jobs per board per feed (stored in chunks of 5,000). A board larger than that would have its oldest-listed jobs reported as
newagain; no public board we know of comes close. Very large boards also need more memory than the 256 MB default. - The October 2026 update (changelog 0.1.2) changed how history is stored (per feed instead of per board). The first run after the update reports every job as
newonce; old records namedBOARD-…injob-boards-feed-stateare no longer used and can be deleted.
Integrations and API
Use the Apify API, webhooks, or integrations (Zapier, Make, Google Sheets, Slack and others) to send each run's new and changed jobs wherever you need them. The per-board results are in the RUN_SUMMARY record of the run's default key-value store.
FAQ
Does it need a Greenhouse or Lever account? No. It reads public job board data that needs no login or key.
Why did a board fail? See RUN_SUMMARY.boards. The most common reason is a wrong board name or a company that no longer uses that job board (HTTP 404).
Will I be charged for failed boards? No. The board event is only charged for boards that were read successfully.
How do I reset change tracking? Delete the job-boards-feed-state key-value store in your account (this resets every feed), or start a new task.
Is it official? No. It is an independent tool, not affiliated with Greenhouse, Lever or Employ Inc.