Greenhouse Jobs Scraper: Lever & Ashby Job Feed avatar

Greenhouse Jobs Scraper: Lever & Ashby Job Feed

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Greenhouse Jobs Scraper: Lever & Ashby Job Feed

Greenhouse Jobs Scraper: Lever & Ashby Job Feed

Greenhouse jobs scraper for Lever and Ashby too: get jobs by company name, domain or careers URL with title, location, remote flag, salary and apply link as JSON, CSV or Excel. Watch mode returns new, changed and closed jobs. From $1/1,000 results.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

Alexandre Manguis

Alexandre Manguis

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

16 days ago

Last modified

Share

Greenhouse Jobs Scraper: Lever & Ashby Job Feed with New/Closed Alerts

What does ATS Jobs Watch Feed do?

This Greenhouse jobs scraper also reads Lever and Ashby career boards. Give it company names, domains, career-page URLs or board tokens. It finds each company's job board and returns every open posting in one normalized format: title, department, locations, remote flag, salary (when published), description and direct apply URL.

In watch mode it remembers the previous run and returns only the new, changed and closed postings, so a daily schedule stays small and cheap.

It reads the public job-board APIs that Greenhouse, Lever and Ashby publish for third parties. No login, no browser and no proxy is involved.

Use cases

  • Sales and RevOps teams: use hiring as a buying signal. Which target accounts are hiring a "data engineer" right now?
  • Recruiting agencies: track competitors' and clients' open roles.
  • Job-board and newsletter builders: aggregate postings with apply links and normalized salary and remote fields.
  • Competitive intelligence: spot roles that were closed (filled or frozen).
  • Automations and AI agents: structured job data per company, ready for Slack, Google Sheets, Make, Zapier or a CRM.

Features

  • Three ATSs in one schema: Greenhouse, Lever, Ashby.
  • Input by company name, domain, careers URL, board URL or board token. The ATS and token are detected automatically (best effort, see Limitations).
  • Watch mode: NEW / CHANGED / CLOSED rows since the last run, one snapshot per watch list name. Only the rows returned are billed.
  • Filters: title keywords, location keywords, remote only, cap per company, overall result limit.
  • Normalized salary (min, max, currency, period) when the ATS publishes it, remote flag, workplace type, country and seniority inferred from the title.
  • Optional plain-text and HTML descriptions (turn off for lighter rows).
  • Export to JSON, CSV, Excel, XML or HTML from the Apify dataset, or call it through the API.

Input and configuration

Input fields

FieldTypeDefaultDescription
companies (required)array of strings–Board URLs (jobs.lever.co/palantir), board tokens (stripe), domains (stripe.com), careers page URLs or company names.
atsauto / greenhouse / lever / ashbyautoForce one ATS for bare tokens and names.
modeall / watchallall returns every open posting. watch returns only NEW, CHANGED and CLOSED postings since the previous run with the same watch list name. The first watch run returns everything as NEW.
watchStateNamestringdefaultName of the watch list (a-z, 0-9, -). Each name keeps its own snapshot, so several schedules run independently.
titleKeywordsarray of strings[]Keep jobs whose title contains any of these words (case-insensitive).
locationKeywordsarray of strings[]Keep jobs whose location text contains any of these words.
remoteOnlybooleanfalseKeep only jobs flagged as remote.
includeDescriptionbooleantrueInclude descriptionText and descriptionHtml.
maxJobsPerCompanyinteger0Cap per company (0 = no cap).
maxResultsinteger100Maximum rows for the whole run (also caps your spending).

Example input

{
"companies": ["stripe", "jobs.lever.co/palantir", "jobs.ashbyhq.com/linear"],
"mode": "all",
"titleKeywords": ["engineer"],
"maxResults": 100
}

Output

Example output

One dataset row per job. Short example (description shortened, values illustrative):

{
"jobId": "greenhouse:stripe:8172508",
"ats": "greenhouse",
"boardToken": "stripe",
"companyInput": "stripe.com",
"companyName": "Stripe",
"title": "Abuse Investigator",
"department": "8611 Security Analytics",
"locations": ["Dublin"],
"country": null,
"isRemote": false,
"workplaceType": null,
"employmentType": null,
"seniority": null,
"salaryMin": null,
"salaryMax": null,
"salaryCurrency": null,
"salaryPeriod": null,
"salaryText": null,
"descriptionText": "About the team and the role …",
"descriptionHtml": "<h2>About the team</h2> …",
"jobUrl": "https://stripe.com/jobs/search?gh_jid=8172508",
"applyUrl": "https://stripe.com/jobs/search?gh_jid=8172508#app",
"publishedAt": "2026-09-03T17:32:53.000Z",
"updatedAt": "2026-09-25T20:45:00.000Z",
"changeType": null,
"changedFields": null,
"firstSeenAt": null,
"closedAt": null,
"scrapedAt": "2026-10-04T10:21:10.285Z"
}

Watch mode rows

In watch mode changeType is NEW, CHANGED or CLOSED, firstSeenAt is set, and CHANGED rows list the changed fields in changedFields.

Output fields and fill rates

Fill rates measured on a 60-row test run across several boards (all three ATSs, mode: all). They depend on what each company publishes, so your own results will vary.

FieldFill rateNotes
jobId, ats, boardToken, companyInput, title, jobUrl, applyUrl, scrapedAt100%Always present.
department, locations, isRemote, publishedAt100%
descriptionText, descriptionHtml100%null when includeDescription is off.
workplaceType62%When the ATS publishes it.
country68%Only when it can be inferred reliably.
employmentType60%
companyName40%Only when the board publishes it.
updatedAt40%Not exposed by every ATS.
salaryMin, salaryMax, salaryCurrency, salaryPeriod, salaryText47%Only when the posting publishes pay. In a Greenhouse-only discovery run (15 rows) none did. No guessing.
seniority15%Inferred from the title; null when unclear.
changeType, firstSeenAtwatch mode only100% in a watch test run, null in all mode.
changedFields, closedAtwatch mode onlyOnly on CHANGED / CLOSED rows.

How to use via the API

Replace YOUR_APIFY_TOKEN with your own token.

curl

curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~ats-jobs-watch-feed/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"companies": ["stripe", "jobs.lever.co/palantir"], "maxResults": 50}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('YOUR_USERNAME/ats-jobs-watch-feed').call({
companies: ['stripe', 'jobs.lever.co/palantir'],
mode: 'watch',
watchStateName: 'sales-targets',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'new, changed or closed jobs');

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("YOUR_USERNAME/ats-jobs-watch-feed").call(run_input={
"companies": ["stripe", "jobs.lever.co/palantir"],
"mode": "watch",
"watchStateName": "sales-targets",
"remoteOnly": False,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(len(items), "new, changed or closed jobs")

Scheduling a "new jobs" feed in watch mode

  1. Create a Task with mode: watch and a fixed watchStateName.
  2. Add an Apify Schedule (for example daily).
  3. Add a webhook or an integration (Slack, Google Sheets, Make, Zapier) on run success. Each run's dataset holds only what changed since the last run.

Use a different watchStateName for each list of companies you want to track separately.

Pricing

Pay per result: you are billed one job event per dataset row returned. Unresolved companies and runs that return nothing cost no result events. Apify platform usage (a few hundredths of a cent per test run) is shown separately in your run.

Apify planPrice per 1,000 results
Free$1.50
Bronze$1.30
Silver$1.15
Gold, Platinum, Diamond$1.00

In watch mode only NEW, CHANGED and CLOSED rows are returned and billed, so unchanged jobs cost nothing. Use maxResults to cap spending.

Limitations and troubleshooting

  • Only Greenhouse, Lever and Ashby are supported. Other systems (Workday, SmartRecruiters, …) are not.
  • A company is not found. Name and domain discovery is best effort: it needs a recognisable board token or a careers page that links to the ATS board. Try the board URL or token directly. Unresolved entries are listed with a reason in the RUN_SUMMARY key-value record, and the run still succeeds without billing them. In a test with an unknown board and example.com, the run succeeded with 0 results.
  • Missing salary or null fields. Fields are filled only when the posting publishes them. The Actor does not guess.
  • "Field input.companies is required". Provide at least one company.
  • Watch mode returned everything. The first run of a watch list returns all jobs as NEW. If the snapshot is missing or corrupted, the run is treated as a first run.
  • Rate limits. Requests are paced and retried with backoff.

FAQ

Does it need a board token? No. You can pass a name, domain or careers URL, though a board URL or token is the most reliable.

Is the data public? Yes. It comes from the public job-board APIs these ATS vendors offer, with no login. Descriptions are kept as the employer published them. Check your own legal basis if you process recruiter contact details found in a description.

Can it apply to jobs or read candidate data? No. It only reads public postings.

Does watch mode work across different Tasks? Snapshots are stored per watchStateName, in your account. Reuse the same name to continue a list.

Keywords

greenhouse jobs scraper, lever jobs api, ashby jobs scraper, ats job feed, career page scraper, greenhouse job board api, lever jobs scraper, new job alerts, hiring signals, company job postings, job change monitor, career site jobs api

Hashtags

#greenhouse #lever #ashby #jobs #jobscraper #ats #careerpages #hiringsignals #recruiting #leadgeneration #jobalerts