Greenhouse Jobs Scraper avatar

Greenhouse Jobs Scraper

Pricing

from $2.00 / 1,000 jobs

Go to Apify Store
Greenhouse Jobs Scraper

Greenhouse Jobs Scraper

Type company names or paste Greenhouse job-board URLs and get every open job from those companies' Greenhouse career boards: full descriptions, salary where published, one clean format. Filter by keyword, place, department, salary or date; get only new, changed or closed jobs since your last run.

Pricing

from $2.00 / 1,000 jobs

Rating

0.0

(0)

Developer

Michael Costa

Michael Costa

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 hours ago

Last modified

Share

What does Greenhouse Jobs Scraper do?

Greenhouse Jobs Scraper takes a list of companies that hire on Greenhouse and returns every open job they post there, in one clean, consistent format, fetched live from each company's own Greenhouse job board through Greenhouse's public job-board API. No login.

It is not a job-board search: it doesn't search Indeed, LinkedIn, or all of Greenhouse. Greenhouse doesn't publish a directory of the companies that use it, so you list the companies, and you get every job each of them has open, the moment it's listed.

Three ways to name a company, one per line, mixed freely:

You typeExampleHow it's found
Company nameDiscordLooked up on Greenhouse only. It's used only when the board's own company name agrees with what you typed.
Greenhouse board URLhttps://boards.greenhouse.io/dropbox, https://job-boards.greenhouse.io/dropbox, or the short form greenhouse:dropboxUsed as is. Links to a single job work too.
Careers pagehttps://example.com/careersScanned for a link to the company's Greenhouse board. Works when the page links it directly; many big-company pages load jobs with JavaScript, and then the name or the Greenhouse URL works better.

Try it in one click: the input comes pre-filled with 2 example companies, one typed as a name and one as a URL: Discord and Dropbox. That's about 95 jobs, or roughly $0.19 (95 × $0.002 per job, plus $0.00005 for the run start). Then replace them with the companies you actually want.

Monitor new, changed and closed Greenhouse jobs

Greenhouse Jobs Scraper can watch a list of companies and give you only what happened since its last run: new jobs, and optionally the jobs that closed or changed. Set it up once:

  1. Save a task. Fill in Companies (and any filters), turn on Only jobs new since my last run (onlyNewJobs: true in the API), then click Save as a new task at the top right of the actor's page. The first run returns every current job that matches; later runs return only jobs posted since. For a full job-change feed, also turn on Also report closed and changed jobs (includeClosedAndChanged: true): each row then has a changeType of new, changed (title, location, department, employment type or salary changed; changedFields shows old and new) or closed (taken off the company's Greenhouse board; the row keeps its last known title, location and link). Useful for spotting ghost jobs and filled roles.
  2. Schedule it. In Apify Console, open Schedules, click Create new, pick the task and set how often it runs (for example every day at 07:00, cron 0 7 * * *).
  3. Send the new jobs where you work, from the task's Integrations tab:
    • Slack: a message in the channel you choose when a run succeeds (you pick the events and can edit the message).
    • Email: Send results email via Gmail sends the run's results, with the dataset attached.
    • Webhook: a POST to your URL on the ACTOR.RUN.SUCCEEDED event. The payload's resource.defaultDatasetId points to the new jobs: GET https://api.apify.com/v2/datasets/<defaultDatasetId>/items?format=json with your API token.
    • Make, Zapier or n8n: each has an Apify step that starts on a finished run and reads its dataset.

A run that finds nothing new (or changed or closed) returns 0 jobs and costs only the $0.00005 start fee. Slack and email are sent for every successful run, including a quiet one; to hear only about new jobs, use the webhook or Make/Zapier/n8n and skip runs whose dataset is empty. Add the run failed event too, so a failed run doesn't go unnoticed. Keep the task's filters fixed: the memory is per company and per filter combination, so changing them starts a fresh search.

What data does Greenhouse Jobs Scraper return?

FieldExampleNotes
titleAccount Executive
companyName, companyDropbox, dropboxThe board's display name and its Greenhouse address.
department, teamDirect Sales - AMER (Sub Team)null when the board doesn't group jobs.
location, locations, countryRemote - US: Select locationsAs the company lists them.
workplaceType, remoteremote, trueremote, hybrid or onsite; null when the job doesn't say.
employmentTypeFULL_TIMEOne of FULL_TIME, PART_TIME, CONTRACT, TEMPORARY, INTERNSHIP, VOLUNTEER, or null.
postedAt, updatedAt2026-09-01T13:20:17ZISO 8601 UTC.
url, applyUrlhttps://jobs.dropbox.com/listing/8159652?gh_jid=8159652The job page and where to apply.
salaryMin, salaryMax, salaryCurrency, salaryPeriod146500, 198300, USD, YEARFrom the pay range in the job text; null when there is none.
salaryText, salarySource$146,500—$198,300 USD, descriptionThe text it was read from, and where.
descriptionRole Description...Plain text; switch off Include full job description to leave it out.
idgreenhouse:dropbox:8159652Stable across runs, for deduplication.
changeTypenew, changed, closedOnly with Also report closed and changed jobs; the fields below too.
changedFields{"title": {"old": "Engineer", "new": "Senior Engineer"}}For changed jobs: each field that changed, old and new. null otherwise.
closedDetectedAt, firstSeenAt2026-10-02T07:00:00ZWhen a run found the job gone, and when a run first returned it (null for jobs returned before version 1.1).

Every job has the same fields; the full record is under Output.

How much does it cost to scrape Greenhouse jobs?

You pay per job returned: $2.00 per 1,000 jobs, plus $0.00005 each time a run starts. Filters are applied before you're charged, so you only pay for jobs you keep. A company that isn't found, fails or has no matching jobs costs nothing, and a repeat run with nothing new costs only the start fee.

  • The example below: 96 jobs × $0.002 = $0.192, plus the $0.00005 start fee; the repeat run $0.00005.
  • Closed and changed jobs are rows like any job, $0.002 each, and only when you turn that option on.
  • A month, for example: 50 companies with 2,000 open jobs between them, checked daily: the first run is 2,000 × $0.002 = $4.00; if 30 new jobs a day are posted after that, 870 × $0.002 = $1.74: about $5.74, plus 30 starts ($0.0015).
  • Caps: Max jobs per run in the input, and Maximum cost per run in the run options. It stops cleanly at whichever comes first, and stops fetching as soon as the limit is covered, so a capped run is also a fast one.

How to scrape Greenhouse jobs

  1. Open the actor and type your companies into Companies, one per line: names, Greenhouse board URLs or careers pages.
  2. Optionally add Title keywords, Locations, Departments, Minimum salary or Posted within (days) to keep only the jobs you want.
  3. Click Start.
  4. Open the Output tab and export the jobs as JSON, CSV or Excel, or read them through the API.
  5. To keep watching the same companies, save it as a task and schedule it (see Monitor new, changed and closed Greenhouse jobs above).

Each run's log and the RUN_STATS record show what every name or page was matched to, and anything that couldn't be used, with the reason. A company on another hiring platform is skipped with a clear message and the rest of the run continues; for those, use Company Career Page Jobs Scraper, which covers Greenhouse and 5 other platforms with the same output format.

Example: two companies, then a daily re-check

The pre-filled input, with Only jobs new since my last run turned on:

{"companies": ["Discord", "https://boards.greenhouse.io/dropbox"], "onlyNewJobs": true, "includeDescription": true}

It returned 96 jobs. One of them (real output from a local run on 2026-09-25; description shortened):

{
"id": "greenhouse:discord:8806482002",
"platform": "greenhouse",
"company": "discord",
"companyName": "Discord",
"title": "Commercial Policy Lead",
"department": "Policy",
"location": "San Francisco Bay Area",
"remote": false,
"postedAt": "2026-09-15T16:52:11Z",
"url": "https://job-boards.greenhouse.io/discord/jobs/8806482002",
"salaryMin": 192000.0,
"salaryMax": 216000.0,
"salaryCurrency": "USD",
"salaryPeriod": "YEAR",
"salaryText": "$192,000 to $216,000",
"salarySource": "description",
"description": "Discord has a highly engaged community of millions of daily active users who use the platform for ma..."
}

Run again straight after, the same input returned 0 jobs, so only the start fee was charged.

Input

FieldWhat it does
CompaniesOne per line: a company name, a Greenhouse board URL (or greenhouse:slug), or a careers page that links to its Greenhouse board.
Title keywords / Exclude keywordsKeep or drop jobs by words in the title (case-insensitive).
LocationsKeep jobs whose location or country contains any of these. Add remote to include remote jobs.
Remote jobs onlyOnly jobs marked remote.
Posted within (days)Only recently published jobs.
DepartmentsKeep jobs whose department or team contains any of these (case-insensitive).
Employment typesOnly jobs of these types (FULL_TIME, CONTRACT, ...). Greenhouse states no employment type, so leave it empty.
Minimum salary, currency, perOnly jobs whose pay reaches this amount at the top of their range, in this currency (default USD) and period (default a year). Currencies are never converted.
Keep jobs with no comparable salaryWith a minimum salary: keep (default) or drop jobs whose pay isn't published or can't be compared.
Only jobs new since my last runFirst run returns everything that matches; later runs return only jobs posted since. Remembered in your own Apify storage, per company and per filter combination.
Also report closed and changed jobsLater runs also return jobs you were given before that have since closed or changed, each marked with changeType. Implies the option above.
Include full job descriptionPlain-text description (on by default).
Max jobs per runCap the total number of jobs across all companies.
Max jobs per companyCap results per company.
{
"companies": [
"Discord",
"https://boards.greenhouse.io/dropbox",
"greenhouse:figma"
],
"keywords": [
"engineer"
],
"locations": [
"San Francisco",
"remote"
],
"postedWithinDays": 30
}

Output

Every job has the same fields. Fields Greenhouse doesn't publish for a job are null.

{
"id": "greenhouse:dropbox:8159652",
"platform": "greenhouse",
"company": "dropbox",
"companyName": "Dropbox",
"title": "Account Executive",
"department": "Direct Sales - AMER (Sub Team)",
"team": null,
"location": "Remote - US: Select locations",
"locations": [
"Remote - US: Select locations"
],
"country": null,
"remote": true,
"workplaceType": "remote",
"employmentType": null,
"postedAt": "2026-09-01T13:20:17Z",
"updatedAt": "2026-09-08T15:46:44Z",
"url": "https://jobs.dropbox.com/listing/8159652?gh_jid=8159652",
"applyUrl": "https://jobs.dropbox.com/listing/8159652?gh_jid=8159652",
"salaryMin": 146500.0,
"salaryMax": 198300.0,
"salaryCurrency": "USD",
"salaryPeriod": "YEAR",
"salaryText": "$146,500—$198,300 USD",
"salarySource": "description",
"description": "Role Description\n\nAs an Account Executive on the Growth team, you will help Dropbox…",
"scrapedAt": "2026-09-24T15:58:25.413475Z"
}

id is stable across runs (platform:company:jobId), so you can use it to deduplicate.

Run it on a schedule, or from your own code

  • Schedule: save the input as a task and add it to a schedule, as in Monitor new, changed and closed Greenhouse jobs above.
  • API: fetch a task's latest results with GET https://api.apify.com/v2/actor-tasks/<task id>/runs/last/dataset/items?status=SUCCEEDED&format=csv and your API token (format can also be json or xlsx).
  • Webhooks and automation: a webhook when a run succeeds, or Make, Zapier or n8n through Apify's integrations.

Can I use Greenhouse Jobs Scraper from an AI agent (MCP)?

Yes. Connect the agent to Apify's MCP server (https://mcp.apify.com) and add humble-echidna/greenhouse-jobs as a tool; the agent passes the same input JSON as above. To keep answers small, have it set includeDescription: false and a Max jobs per run (maxJobs).

Who it's for

Niche job boards and aggregators that list jobs from a known set of employers, recruiters and sales teams watching target companies' hiring (hiring signals), job seekers with a shortlist of companies, and salary and market research (pay ranges as numbers, with currency and period). The recurring job: keep a list of companies that hire on Greenhouse, run it daily with Only jobs new since my last run, and get each new posting once.

Why this one?

  • Just type the company name. "Discord" finds Discord's Greenhouse board, checked against the board's own company name, so a different company that happens to use that name as its board address is rejected. Embedded boards (…?for=company) and single-job links work too.
  • Reliable. A broken or unreachable company never affects the others in your run. A malformed job record is skipped instead of failing its company. Rate limits are handled automatically. The run log and the RUN_STATS record say exactly which company had a problem and why.
  • Clean, consistent fields. Employment type is one of FULL_TIME, PART_TIME, CONTRACT, TEMPORARY, INTERNSHIP, VOLUNTEER and workplace type one of remote, hybrid or onsite (null when the job doesn't say); dates are ISO 8601 UTC. The format is identical to our other job scrapers, so results from several platforms can go in one table.
  • Salary where it's published. Greenhouse has no salary field, but many companies put the pay range in the job text, and it's extracted from there as numbers with currency and period ("$150,000 - $200,000 USD", "$28.50/hr"), and salarySource says which. Extraction is conservative: bonuses, stipends and funding amounts are ignored.
  • Fast and live. It reads Greenhouse's public job-board API, the same data the company's own careers page shows, during your run: no login, no browser, no proxies.

Limits

  • It reads only the companies you list; it can't search all of Greenhouse (see the FAQ).
  • Greenhouse only: a company on another platform is reported, not fetched.
  • A careers page that loads its jobs with JavaScript can't be scanned; type the company name or the Greenhouse URL instead.

FAQ

Can I get every job on Greenhouse, from every company?

No. This actor fetches the companies you list. Greenhouse doesn't publish a directory of its customers, so no scraper can list "all Greenhouse jobs" from Greenhouse itself. Use this one when you know which companies you want to track and need their complete, fresh listings.

Why wasn't a company found?

The run log and RUN_STATS (unresolved) say why, and the rest of the run continues. Common reasons: it hires on another platform, its careers page loads jobs with JavaScript (type the name instead), or it has no open jobs right now.

What if it matched the wrong company?

Names are only matched when the Greenhouse board's own company name agrees with what you typed, but two companies can share a name. Paste the exact Greenhouse URL to pin it down; company and companyName on every job show which board it came from.

How does "Only jobs new since my last run" know about my last run?

It stores the IDs of the jobs it returned in a named key-value store (greenhouse-jobs-seen) in your Apify account, which persists between runs. Each company and filter combination has its own memory, so a daily "engineer" alert and a weekly "sales" alert on the same company don't interfere. Changing the filters starts a fresh search, and so does deleting that store. Jobs held back by Max jobs per company are not marked as seen, so they come through on a later run.

How are closed jobs detected?

With Also report closed and changed jobs on, the same memory also keeps each returned job's title, locations, department, employment type, salary text and link. On the next run, a job that's no longer on the company's Greenhouse board comes back once as changeType: "closed", with those last known fields and closedDetectedAt; a job whose tracked fields differ comes back once as changeType: "changed", with changedFields (old and new). Only jobs you were already given are tracked, so a search with filters sees closures and changes of its own jobs. A job only counts as closed when its board was read cleanly: if it fails, is blocked, times out or has records that don't parse, or suddenly lists nothing or far fewer jobs, its closed-job check is skipped for that run and the log and RUN_STATS (closureChecksHeld) say why. A sudden drop that the next run sees again is reported then; one that recovers never is.

How do the department, employment type and salary filters work?

Departments keeps jobs whose department or team contains any of your words, ignoring case ("engineering" matches "Product Engineering"). Employment types keeps jobs of the types you pick. Minimum salary keeps jobs whose pay range reaches your amount at its top, in the currency and period you choose: pay per hour, day, week or month is compared as a full-time year (2,080 hours, 260 days, 52 weeks, 12 months), and amounts are never converted between currencies. All three run before you're charged, so a job they leave out costs nothing, and each is part of the search that Only jobs new since my last run remembers.

A filter can only use what the board publishes. A job with no department or team, or no stated employment type, is left out while that filter is set. A job with no comparable pay (none published, another currency, or no period) is kept unless you turn off Keep jobs with no comparable salary. The log and RUN_STATS (boards → notes) say per company how many jobs that affected. Greenhouse has no salary field, so pay comes only from the job text: on 4 boards checked on 2026-09-25 (Greenhouse, Discord, Dropbox, Figma; 275 jobs) it was found for 196 (71%), almost all US roles in dollars a year. Greenhouse states no employment type, so the employment type filter leaves out every Greenhouse job: leave it empty.

Why does a company that used to work now fail or return fewer jobs?

Greenhouse can change its public feed without notice, so a site change is the most likely cause. The run log names the company and what didn't parse, and every other company in the run is unaffected. Please open an issue with the company so it can be looked at.

What if some of my companies use another platform?

A job-board URL from another platform is skipped with a message saying which platform it is, and a name that isn't found on this platform is reported as not found; the rest of the run continues. Company Career Page Jobs Scraper reads Greenhouse, Lever, Ashby, Recruitee, Personio and Teamtailor in one run, with this exact output format.

It reads the public job-board data each company publishes on Greenhouse for its own careers page. It collects job postings only: no recruiter names, emails, or other personal data. It identifies itself honestly (User-Agent HumbleEchidnaApify) and follows Greenhouse's robots.txt: anything the site disallows is never requested, and the company is reported with the reason instead of being skipped silently; crawl delays are respected.

Which addresses does it request?

Only public web addresses on the standard web ports (80 and 443). A careers page on another port, or on a domain that points at a private network, is refused with the reason, and a careers domain that doesn't exist is reported as such. Each site's robots.txt is read once per run; a site that asks for more than 30 seconds between requests is reported rather than fetched slowly.

ActorUse it when
Company Career Page Jobs ScraperYour list mixes platforms: one run for Greenhouse, Lever, Ashby, Recruitee, Personio and Teamtailor, with this same output format.
Lever Jobs ScraperThe same, for companies hiring on Lever.
Ashby Jobs ScraperThe same, for companies hiring on Ashby.
Remote Jobs ScraperYou want remote jobs from We Work Remotely and Remote OK, in the same format.
Dataset Transformer: Filter, Dedupe, ConvertYou want to filter the jobs and export CSV for your board.

Feedback and support

Found a bug, or need a field that isn't here? Open an issue on the Issues tab with the input you used.

Versions

Current version: 1.1. See the Changelog tab for what changed in each version.