Greenhouse Jobs Monitor & Scraper avatar

Greenhouse Jobs Monitor & Scraper

Pricing

$2.00 / 1,000 results

Go to Apify Store
Greenhouse Jobs Monitor & Scraper

Greenhouse Jobs Monitor & Scraper

Monitor Greenhouse jobs from any company careers board (Airbnb, Stripe, Discord and thousands more). Get flat rows with title, location, posting date, apply link, and published salary ranges as numbers: min, max, currency, period. Schedule monitor runs to get only new, changed, and removed jobs.

Pricing

$2.00 / 1,000 results

Rating

0.0

(0)

Developer

Redomic

Redomic

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 hours ago

Last modified

Security

Limited permissions

Share

Greenhouse Jobs Monitor & Scraper

Monitor Greenhouse jobs from any company careers board (for example airbnb, stripe, or discord) and get every open job as flat rows: title, location, posting date, apply link and, when the company publishes one, the salary range as numbers: salaryMin, salaryMax, salaryCurrency (ISO 4217) and salaryPeriod (year, month, hour). Schedule runs in monitor mode to get only new, changed, and removed jobs since the last run.

Real rows from airbnb, 31 Oct 2026 (default input, no extra options):

titlelocationworkplaceTypesalaryMinsalaryMaxsalaryCurrencysalaryPeriod
AirCover Specialist, Claims ExperienceCanadaRemote58,00068,000CADyear
Associate Principal, Procurement Innovation Supplier ProgramsUnited StatesRemote102,000120,000USDyear
Business Development ManagerBerlin, GermanyHybrid71,00084,000EURyear
Business Operations and Growth LeadUnited StatesRemote168,000203,000USDyear
Business Process Improvement ManagerUnited StatesRemote156,000195,000USDyear

What it does

Salary comes from Greenhouse itself. Companies that use Greenhouse's pay-transparency feature attach a pay range to each job; the Actor requests it (?pay_transparency=true on the public board API) and splits it into salaryMin, salaryMax, salaryCurrency and salaryPeriod. How often it is filled depends on the company. Counts from runs on 31 Oct 2026 with the input {"boards": ["<board>"], "maxItems": 1000}:

boardjobswith salary
discord4138
airbnb202165
databricks901491
figma14093
stripe7460 (Stripe writes pay only in the description: use includeDescription, 24 found)

When a job has several pay zones (Robinhood lists 3), all of them are in salaryRanges, and salaryMin/salaryMax span them. With includeDescription, a range written only in the text ("Salary: $156,800 - $235,200/yr") is read as well. A job without a published range has null salary fields.

In monitor mode the Actor stores each board's jobs in a named key-value store and returns only jobs that are new, changed (title, location, update time, requisition id or pay range) or removed since the previous run, with changeType. You pay for new and changed jobs only.

Every board you enter gets a status row, so a typo ("_status": "failed", reason board not found (404)) or an empty board is visible in the dataset. The empty case, from a battery run on 31 Oct 2026:

{"_status": "empty", "board": "prisma", "mode": "jobs", "rows": 0, "reason": "board has no open jobs", "total": 0}

A board that exists but has no open jobs (like prisma above) is a successful run with an empty status row, not a failure; a board that cannot be fetched (_status: "failed", for example a 404 typo) gets a failed status row, and the run fails only when no board could be fetched; with some boards fetched it succeeds as partial and you keep their jobs. Rows are capped per board by maxItems, and the run stops at the maximum cost you set. Placeholder requisition ids (ONE, MULTI, See Opening ID) are returned as null.

The data comes from the public boards-api.greenhouse.io JSON API: one request per board, no proxy, no browser. A run over a few boards takes seconds.

Input

FieldTypeDefaultMeaning
boardsarray of strings["airbnb"]Greenhouse board slugs — the part after boards.greenhouse.io/, for example airbnb, stripe. Full board or job URLs are accepted; only the slug is kept
modeenumjobsjobs lists every open job; detail fetches full descriptions for specific jobIds; monitor reports only new, changed and removed jobs since the last run
jobIdsarray of integers[]For mode: detail: the Greenhouse job ids to fetch in full
searchstring""Keep only jobs whose title, location or department (or description, when included) contains this text. Case-insensitive
postedSinceDaysintegernullKeep only jobs first published within the last N days (postedAt at or after the run time minus N days). For "new this week" set 7, for "new this month" set 30 — no monitor state needed. Empty for every open job. Works in jobs, detail and monitor modes
locationsarray of strings[]Keep only jobs whose location contains one of these values (case-insensitive, OR within the list). Empty for every location. AND-combined with the other filters
workplaceTypesarray of strings[]Keep only jobs with one of these workplace types (Remote, Hybrid, Onsite; OR within the list). Remote also matches when the location says remote. Empty for every workplace type; jobs with no workplace type are excluded only when this filter is set
employmentTypesarray of strings[]Keep only jobs with one of these employment types (Full-time, Part-time, Contract, Internship, Apprenticeship, Temporary; OR within the list). Empty for every type; jobs with no employment type are excluded only when this filter is set
minSalarynumbernullMinimum yearly salary: keep only jobs whose salaryMax, converted to yearly (year x1, month x12, hour x2080), is at least this value. Jobs with no published salary are excluded
salaryCurrencystring""ISO 4217 code (for example CAD) that salary must be in when minSalary is set. Empty for any currency
hasSalaryOnlybooleanfalseKeep only jobs with a published salary range. Off for every job, including those with null salary
includeDescriptionbooleanfalseAdd the full description (plain text and HTML), department and offices, and read pay ranges written only in the description. Same single request per board, just a bigger response
maxItemsinteger100Upper limit on job rows per board, 1 to 1000 (3 boards x 100 = at most 300 rows)

Example:

{ "boards": ["airbnb"], "mode": "jobs", "maxItems": 20 }

Output

One row per job, then one status row per board, then a summary row as the last row. In Apify Console the "Jobs" table shows the columns most buyers use (title, location, salary, dates, links); the "Full details" view adds ids, language, descriptions and the per-zone salaryRanges. Example values come from the Greenhouse board API captured on 2026-10-31 (the default input's board, airbnb).

FieldExampleMeaning
id8306554Greenhouse's job id, stable across runs
boardairbnbThe board (company) you searched
titleAirCover Specialist, Claims ExperienceJob title
companyAirbnbEmployer
locationCanadaThe job's location as the board lists it
workplaceTypeRemoteRemote / Hybrid / Onsite, from the company's own field, or Remote when the location says so; null otherwise
urlhttps://careers.airbnb.com/positions/8306554?gh_jid=8306554The job posting URL
applyUrlsame as urlThe apply link (on Greenhouse boards the posting is the application)
postedAt2026-10-28T14:52:05ZFirst-published date, UTC ISO-8601
updatedAt2026-10-28T14:52:05ZLast-updated date, UTC ISO-8601
applicationDeadlinenullApplication deadline, when the board sets one
internalJobId3591434The company's internal job id
requisitionIdnullThe company's requisition reference; null when absent or a placeholder like ONE
languageenPosting language
departmentCommunity SupportPrimary department (detail / includeDescription only)
departments["Community Support"]All departments (detail / includeDescription only)
offices["Canada"]Offices (detail / includeDescription only)
employmentTypenullFull-time, Part-time, Contract, Internship, Apprenticeship or Temporary, only when the title (or the description, when included) states it; null otherwise
salaryMin58000Lowest published pay (across all pay zones of the same currency and period)
salaryMax68000Highest published pay
salaryCurrencyCADISO 4217 currency code
salaryPeriodyearyear, month or hour
salaryTextCAD 58,000 - 68,000 per yearThe range as one readable string
salarySourcepayTransparencypayTransparency (the company's structured Greenhouse pay range) or description (read from the description text); null when no pay is published
salaryRanges[{"min": 58000, "max": 68000, "currency": "CAD", "period": "year", "label": "Canada Annual Pay Range"}]Every published range, e.g. one per pay zone
descriptionTextAirbnb was born in 2007 when two hosts welcomed...Full description as plain text (detail / includeDescription only)
descriptionHtml<div class="content-intro"><p>...Full description as HTML (detail / includeDescription only)
changeTypenewMonitor mode only: new, changed or removed
scrapedAt2026-10-31T00:00:00ZWhen the row was fetched (UTC)

The status row carries _status (ok, partial, empty, failed), board, mode, rows, reason and total (the board's own job count). The last row is a summary with _status: "summary" and totals: rows, boardsOk, boardsEmpty, boardsFailed, and — in monitor mode — checked, unchanged, new, changed, removed, firstRun, runStatus, charged plus the evidence ids newIds, changedIds, removedIds (the job ids of the event rows delivered in that run, so the summary can be reconciled against the dataset). Every monitor run pushes exactly one summary row; a quiet run that finds nothing new ends successfully with checked jobs examined, unchanged jobs untouched, new 0 and charged 0, and runStatus ok.

Pricing

result: $0.002 per job row delivered, no start fee. 1,000 jobs ≈ $2.00. In monitor mode you pay only for new and changed jobs; unchanged and removed jobs are free.

Monitor recipe

Track hiring signals for one company, and get a webhook whenever something changes:

  1. Create a task with { "boards": ["airbnb"], "mode": "monitor" }.
  2. Schedule it hourly (or daily) in Apify Console.
  3. Add a webhook for "run succeeded" to push new / changed / removed rows to Slack, Make or n8n — or export the dataset straight to Google Sheets.
  4. Filter the dataset on changeType to see what actually moved since the previous run. A changed pay range counts as changed, so you can also watch salary bands move.

FAQ

  • How do I find a board slug? Open a company's careers page; if it is a Greenhouse page the slug is the part right after boards.greenhouse.io/ (or job-boards.greenhouse.io/), e.g. boards.greenhouse.io/airbnb → airbnb. You can paste the whole URL.
  • Can I search across every company at once? No — Greenhouse's public API is per-board, and there is no global endpoint. Run several boards in one boards list instead.
  • Does it include salary? Yes, whenever the company publishes it. Structured pay-transparency ranges come with every run at no extra cost; with includeDescription a range written in the description text is read as well. Companies that publish no pay get null salary fields: nothing is estimated or invented.
  • Why is salaryPeriod null on some rows? The company gave a range but no period, and the amount alone cannot tell (e.g. PLN). The range is still returned.
  • What if a job closes? The job drops off the board. In jobs mode it just disappears; in monitor mode it is reported as removed.

What this does not do

It does not log in, break captchas or access anything behind Greenhouse's Harvest API; it reads only the public board endpoints. It does not guess missing fields (salary when no range is published, department when not published), and it does not search a keyword across all Greenhouse companies.

Other languages

Español

Dale un tablero de Greenhouse — el identificador de la página de empleo de una empresa, por ejemplo airbnb — y obtén cada vacante abierta como filas: puesto, empresa, ubicación, departamento, fecha de publicación, el enlace para postularse y, cuando la empresa lo publica, el rango salarial en números (mínimo, máximo, moneda ISO y periodo). Para usarlo, rellena boards (por ejemplo ["airbnb"]) y pulsa Start; pagas solo por cada empleo entregado.

Deutsch

Gib ein Greenhouse-Board an — den Slug der Karriereseite eines Unternehmens, zum Beispiel airbnb — und erhalte jede offene Stelle als Zeilen: Titel, Firma, Ort, Abteilung, Veröffentlichungsdatum, Bewerbungslink und, wenn das Unternehmen es veröffentlicht, die Gehaltsspanne als Zahlen (Minimum, Maximum, ISO-Währung, Zeitraum). Fülle dafür boards (zum Beispiel ["airbnb"]) aus und klicke auf Start; du zahlst nur pro gelieferter Stelle.

Français

Donnez-lui un board Greenhouse — le slug de la page carrière d'une entreprise, par exemple airbnb — et obtenez chaque offre ouverte sous forme de lignes : intitulé, entreprise, lieu, département, date de publication, lien de candidature et, quand l'entreprise la publie, la fourchette de salaire en chiffres (minimum, maximum, devise ISO, période). Remplissez boards (par exemple ["airbnb"]) puis cliquez sur Start ; vous ne payez que pour chaque offre livrée.

Português

Informe um board do Greenhouse — o slug da página de vagas de uma empresa, por exemplo airbnb — e receba cada vaga aberta como linhas: título, empresa, local, departamento, data de publicação, link de candidatura e, quando a empresa publica, a faixa salarial em números (mínimo, máximo, moeda ISO e período). Preencha boards (por exemplo ["airbnb"]) e clique em Start; você paga apenas por vaga entregue.

Sibling Actors: Ashby Jobs Scraper with Salaries and Lever Jobs Scraper with Salaries (same row shape for the other two big startup ATSs) and Google Jobs API Scraper.

Use it from AI agents (MCP) and Python

AI agents. Add this Actor as a tool in Claude, Cursor, VS Code or any MCP client through the Apify MCP server. The agent reads the input schema, so a plain request is enough.

{
"mcpServers": {
"greenhouse-jobs-monitor": {
"url": "https://mcp.apify.com?tools=redomic/greenhouse-jobs-monitor",
"headers": {
"Authorization": "Bearer <YOUR_APIFY_TOKEN>"
}
}
}
}

Python. pip install apify-client, then:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("redomic/greenhouse-jobs-monitor").call(run_input={"boards": ["airbnb"], "mode": "jobs"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

More from us

  • Ashby Jobs Scraper with Salaries: Ashby jobs scraper for any startup careers board (OpenAI, Ramp, Notion and thousands more), with salary ranges as numbers: min, max, currency, period, plus equity and bonus flags
  • ATS Jobs Search: Greenhouse, Lever & Ashby Jobs API: Search 328,000+ open jobs from 11,000+ companies on Greenhouse, Lever and Ashby in one run
  • Google Jobs Scraper - Job Postings API: Google Jobs and job postings scraper: get job title, company, location, posted date, salary, full description and every apply link for any search
  • Google Trends API: Trending Now & Interest Over Time: Trending-now searches and new-trends alerts/monitoring per country with the news behind them, plus interest over time, interest by region, and related and rising queries for any keyword
  • Lever Jobs Scraper with Salaries: Lever jobs scraper for any company's careers page (Palantir, Spotify, Zoox, Shield AI and thousands more): flat rows with title, team, location, workplace, commitment, apply link, salary as numbers and the full description merged