Greenhouse, Lever & Ashby Jobs Scraper (Only New)
Pricing
$1.50 / 1,000 job postings
Greenhouse, Lever & Ashby Jobs Scraper (Only New)
Job scraper for public ATS career boards (Greenhouse, Lever, Ashby): one clean schema, optional feed mode returning only postings new since the last run.
Pricing
$1.50 / 1,000 job postings
Rating
0.0
(0)
Developer
Francesco Antonio Russo
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Company Jobs Feed — Greenhouse, Lever, Ashby, Workable & Teamtailor jobs scraper, new postings only
A job scraper and jobs API for public ATS career boards: get the open positions of any list of companies from Greenhouse, Lever, Ashby, Workable and Teamtailor in one clean schema — and, if you want, only the postings that appeared since your last run. It reads the vendors' documented public endpoints, not the HTML, so it does not break when a careers page is redesigned.
You give a list of companies. You get one record per job posting: title, department, locations, workplace type, pay range when the company publishes it, publication date, links, and the full description as clean text.
Supported boards: Greenhouse, Lever, Ashby, Workable, Teamtailor. Give a company's website or careers page and the Actor finds which of them it uses.
Why use it
- A feed, not a dump. Turn on Only new postings, schedule the Actor, and every run returns just what is new. No diffing on your side, and you pay only for what is delivered.
- Give a website, not a board. Paste
careers.stripe.comorhttps://www.airbnb.com/careers: the Actor looks for the company's board on the five supported systems and tells you which one it found. - One schema for every board. The same fields in the same order whatever the source, so the output goes directly into a sheet, a database, a CRM or an LLM prompt.
- Filter before you pay. Title, location, remote and recency filters are applied before delivery. Postings that do not match are never charged.
- Built on documented public endpoints. No browser, no proxy, no login, no anti-bot workarounds. Runs are fast and cheap, and they do not break when a careers page is redesigned.
- Job postings only. The Actor adds no personal data: no recruiter names, no candidate data. Descriptions are delivered as the company published them.
Typical uses
- Hiring signals for sales: watch target accounts and get notified when they open roles that mean budget ("Head of Data", "Salesforce Admin", "Security Engineer").
- Job boards and newsletters: keep a niche board fresh from a curated list of companies.
- Recruiting and talent intelligence: track where competitors are hiring, in which teams and locations.
- AI agents: give a job-search or research agent a reliable, structured source of open roles.
Input
| Field | What it does |
|---|---|
companies (required) | One entry per company: its website or careers page, the URL of its public job board, or source:company. |
onlyNew | Return only postings that appeared since the previous run with the same feed name. |
baselineOnFirstRun | With onlyNew: the first run records every posting that is listed and delivers nothing. |
stateKey | Feed name. Use different names for independent feeds. Default default. |
titleKeywords / excludeTitleKeywords | Keep / drop postings by words in the title (case-insensitive). A keyword is a word or a phrase, not a piece of text: it matches from the start of a word to the end of it, and also the usual endings of that word (s, es, ing, er, ers, ed, ship, ships). So engineer finds "Engineer", "Engineers" and "Engineering Manager"; intern finds "Intern" and "Internship" but not "Internal", "Internet" or "International"; design finds "Designer". A word of up to 3 letters (AI, ML, PM) must be the whole word, so AI does not find "AirCover" or "Spain". To match any ending, finish the keyword with * (data* finds "Database"). Accents are not folded: ingénieur does not find "Ingenieur". |
locationKeywords | Keep postings whose locations contain any of these words. The country the board gives counts too (Lever, Ashby, Workable, Teamtailor): "United States", "Japan" find jobs labelled "San Francisco, California" or "London". A country is found under every way it is written: "US", "USA", "U.S." and "United States" are the same search (also in a label like "Remote - USA"), and so are "UK", "Great Britain" and "United Kingdom". A short word of up to 3 letters ("US", "NY") must be a whole word, so "US" does not find Sydney, Brussels or Columbus. Greenhouse gives no country: there only the location text is searched. |
remoteOnly | Keep only postings the company marks as remote (its workplace-type field, or a location label saying Remote). |
postedWithinDays | Keep only postings published in the last N days. |
includeDescription | Add the description as plain text. Default on. |
includeDescriptionHtml | Also add the original description HTML. Default off. |
maxJobsPerCompany / maxJobsTotal | Caps on the number of postings delivered. Postings are ordered newest first, so a cap keeps the most recently published ones. |
Quick start: press Start with the prefilled companies and you get the 10 newest postings of each (30 in total, a few cents) in seconds; then replace them with your own list and remove the cap.
How to write a company
Use the board URL you see in the browser, or the short form:
| Board | URL form | Short form |
|---|---|---|
| Greenhouse | https://boards.greenhouse.io/airbnb or https://job-boards.greenhouse.io/airbnb | greenhouse:airbnb |
| Lever | https://jobs.lever.co/spotify | lever:spotify |
| Ashby | https://jobs.ashbyhq.com/notion | ashby:notion |
| Workable | https://apply.workable.com/huggingface/ | workable:huggingface |
| Teamtailor | https://career.teamtailor.com/jobs (any <name>.teamtailor.com career site) | teamtailor:career |
Giving a company's website instead
Not sure which system a company uses? Enter its website or careers page (stripe.com, careers.stripe.com, https://www.airbnb.com/careers). The Actor takes the company name from the domain and asks each of the five supported systems' public endpoints whether a board with that name exists and has open postings (one polite request per system). It never requests the company's own website.
- If exactly one system has such a board, the Actor uses it. The
SUMMARYrecord shows which one (source,company,detectedFrom). - If the name exists on more than one system, or on none, the entry is reported as
not_foundwith an explanation, and nothing is guessed. Usesource:companyor the board URL for those. - A name can belong to an unrelated company. Every record says how its board was found in
boardMatch:given(you named the board),confirmed(found from the website, and the postings link back to that website's domain — Greenhouse boards usually do),name(found from the website only because a board has that name — for exampleatlas.commatches an unrelated Ashby board called "atlas"). Filter onboardMatchor use the explicit form when you need to be certain; anamematch also shows a warning in the log. - Websites of systems this Actor does not read (for example SmartRecruiters, Recruitee, Workday, BambooHR, Personio) are reported as ignored entries.
Example: daily feed of new engineering roles
{"companies": ["greenhouse:airbnb", "lever:spotify", "notion.com"],"onlyNew": true,"baselineOnFirstRun": true,"titleKeywords": ["engineer", "developer"],"excludeTitleKeywords": ["intern"]}
Schedule it daily. The first run records what is already open; from the second run on, you receive only the roles that appeared since the previous run, however you change the filters in between.
Output
One record per posting. Example (description shortened):
{"id": "ashby:ramp:34413f8d-26bf-4bbc-8ade-eb309a0e2245","source": "ashby","company": "ramp","companyName": "ramp","jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245","title": "Security Engineer, Cloud","department": "Engineering","team": "Backend","location": "New York, NY (HQ)","locations": ["New York, NY (HQ)","Remote (Canada)","Remote (US)","Miami, FL"],"countries": ["United States","Canada"],"workplaceType": "hybrid","employmentType": "Full-time","compensation": {"text": "$211.4K – $290.6K • Offers Equity","min": 211400,"max": 290600,"currency": "USD","interval": "year"},"publishedAt": "2026-04-07T17:12:35.753Z","updatedAt": null,"url": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245","applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application","language": null,"descriptionText": "About Ramp\n\nRamp is building the smart infrastructure for finance teams, embedded in the t…","boardMatch": "given","scrapedAt": "2026-10-06T09:27:43.435Z"}
| Field | Notes |
|---|---|
id | Unique key: source:company:jobId. company is written as you entered it (or as detected), so keep the spelling consistent; Lever and Workable identifiers are always lower case. |
companyName | Display name when the board provides one (Greenhouse, Workable, Teamtailor); otherwise the company identifier. |
boardMatch | given, confirmed or name: how the board was found (see Input) |
locations | Every location listed for the posting; location is the first. |
countries | Countries as the board gives them, in English, one name per country ("USA", "US" and "United States" all become "United States"; 2-letter codes become names). Empty on Greenhouse, which has no country field |
workplaceType | remote, hybrid, onsite, or null when the company does not state it. Greenhouse: the company's own Workplace Type / Location Type field when its board has one (many do), otherwise remote or hybrid only when the location label says so. Lever and Ashby: their workplace-type field. Workable: remote when the posting is flagged as telecommuting. Teamtailor: its remote status (none is onsite). |
compensation | Present only when the company publishes a pay range. min/max are in currency units; interval is year, month, week, day, hour, or null when the board does not state the pay period. |
publishedAt, updatedAt | ISO 8601, UTC. updatedAt is available on Greenhouse only. On Lever, publishedAt is the date the posting was created. |
employmentType | As the board publishes it; always null on Greenhouse and Teamtailor. |
descriptionText | Full description as plain text, with paragraphs and bullet lists preserved. |
A SUMMARY record in the run's key-value store lists, per company: status (ok, baseline, partial, not_found, error, skipped), postings listed, postings delivered, any input entries that were ignored (invalidEntries), and entries left out because they name a company already in your list (duplicateEntries: careers.stripe.com next to stripe.com, or Lever:Spotify next to lever:spotify).
How "Only new postings" works
A posting is new if it was not on the company's board when your feed started (its first run for that company) and has not been delivered to you since. In practice:
- At the first run for a company, every posting open at that moment is recorded. With Skip existing postings on the first run it is only recorded; without it, the postings matching your filters are delivered (and charged) once.
- Your filters never turn an old posting into a new one. A posting that was open at the first run but did not match your filters then is recorded too: widening the filters later does not deliver it. To get the backlog under new filters, use a new feed name (a new feed has its own first run).
- A posting stays remembered for as long as the company keeps it open, however long that is. It is never re-delivered as "new".
- If a posting is closed and re-opened more than 30 days later, it counts as new.
- Postings that match your filters but were held back by a limit (
maxJobsPerCompany,maxJobsTotal, your spending limit) are not marked as delivered: the next run returns them. - If a company's board cannot be read during a run, its memory is left untouched.
- Delivery is at-least-once: if a run is interrupted between delivering postings and saving the memory, the next run delivers those postings again. A posting is never lost.
- Do not run two runs with the same feed name at the same time: both would deliver the same new postings. Give overlapping schedules different feed names.
The memory lives in a named key-value store, company-jobs-feed-state, in your account. Delete a record there to reset a feed.
Pricing
Pay per event: you are charged for each job posting delivered to the dataset, at the price shown on the Pricing tab. There is no start fee. Companies that are not found, postings removed by your filters, and baseline runs cost nothing. Example: a run that delivers 250 postings costs $0.45 at $1.80 per 1,000; a scheduled feed that finds 12 new postings costs about $0.02. The Actor respects the maximum charge you set for a run and stops cleanly when it is reached.
API & integrations
Everything the Console does is available through the Apify API and the official clients, so the feed drops into any pipeline.
Run it and read the results with the API (replace <token> with your Apify API token):
curl -X POST "https://api.apify.com/v2/actors/far003~company-jobs-feed/run-sync-get-dataset-items?token=<token>" \-H "Content-Type: application/json" \-d '{"companies": ["greenhouse:cloudflare", "lever:palantir"], "onlyNew": true, "stateKey": "my-feed"}'
From Node.js with apify-client:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<token>' });const run = await client.actor('far003/company-jobs-feed').call({companies: ['greenhouse:cloudflare', 'lever:palantir'],onlyNew: true,stateKey: 'my-feed',});const { items } = await client.dataset(run.defaultDatasetId).listItems();
From Python with apify-client:
from apify_client import ApifyClientclient = ApifyClient("<token>")run = client.actor("far003/company-jobs-feed").call(run_input={"companies": ["greenhouse:cloudflare", "lever:palantir"],"onlyNew": True,"stateKey": "my-feed",})items = client.dataset(run.default_dataset_id).list_items().items
Schedules and integrations. Create a Schedule in the Console (for example daily) with onlyNew on, then attach an integration to the Actor: a webhook on ACTOR.RUN.SUCCEEDED, or one of the built-in connectors (Slack, Google Drive, Airtable, Make, Zapier, n8n…). Each run's dataset then contains only the postings that appeared since the previous run, so the integration receives nothing when there is nothing new. The dataset can be exported as JSON, JSONL, CSV, Excel, XML, HTML table or RSS from the run page or through the API.
Limits
- Five systems are supported today. Companies using other systems are reported as ignored entries, not silently skipped.
- EU-hosted boards (
jobs.eu.lever.co,job-boards.eu.greenhouse.io) are not supported yet and are reported as ignored entries. - The Actor reads what the company publishes: if a field is empty at the source, it is
nullhere. - Teamtailor career sites on a custom domain are not recognised (only
<name>.teamtailor.com); neither are Workable boards other thanapply.workable.com/<name>. - A website entry costs up to five lightweight requests (one per supported system) before its postings are read.
- To stay polite to the boards, requests to the same host are spaced one second apart. A list of 500 companies on the same board takes roughly 10 minutes.
companyNameon Lever and Ashby is the board identifier, because those boards do not expose a display name.
FAQ
A company returns not_found. The identifier is wrong or the company moved to another system. Open its careers page and copy the board URL from the address bar.
Can I track thousands of companies? Yes. Memory use is low and cost scales with postings delivered, not with companies checked.
Is this allowed? The Actor uses only endpoints and feeds these vendors document as public for reading published job postings (Greenhouse Job Board API, Lever Postings API, Ashby job posting API, Workable's public account endpoint, Teamtailor's career site RSS feed), without authentication, and returns only information the companies have made public to attract applicants. It adds no personal data to what the company published. You remain responsible for how you use the data, including each board's terms and the laws that apply to you.
Why are my capped results not random? Within each company, postings are ordered newest first (undated last), so maxJobsPerCompany and maxJobsTotal keep the most recent ones. With several companies, maxJobsTotal fills in the order of your list.
Which systems are supported, and why not others? Greenhouse, Lever, Ashby, Workable and Teamtailor, because each vendor documents a public way to read published postings without a key. A system is added only when its vendor documents public, keyless access.
Something is wrong or a board is missing. Open an issue on the Issues tab.
Greenhouse, Lever, Ashby, Workable and Teamtailor are trademarks of their respective owners. This Actor is not affiliated with or endorsed by them.