Greenhouse Jobs Scraper: Locations, Departments & Apply Links avatar

Greenhouse Jobs Scraper: Locations, Departments & Apply Links

Pricing

from $2.00 / 1,000 job scrapeds

Go to Apify Store
Greenhouse Jobs Scraper: Locations, Departments & Apply Links

Greenhouse Jobs Scraper: Locations, Departments & Apply Links

Scrape public job listings from any Greenhouse-hosted job board. Returns title, location, department, the full description and an apply URL. No login, no proxy, no browser.

Pricing

from $2.00 / 1,000 job scrapeds

Rating

0.0

(0)

Developer

Arman Hossain

Arman Hossain

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

Categories

Share

Greenhouse Jobs: Every open role on any Greenhouse board, with departments, offices and apply links

Pulls every open role from any Greenhouse-hosted job board. You get the title, location, offices, departments, the full description as plain text, and a direct apply link.

Thousands of companies post through Greenhouse, and every board exposes a public JSON feed. This Actor reads that feed directly, so there's no browser, no proxy, no login and no rate-limit games. A board with 500 roles comes back in a couple of seconds.

Agent skill: SKILL.md

https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/greenhouse-jobs-scraper.md

What you get

FieldWhat it holds
board, companyThe board token used, and the company name Greenhouse reports
jobId, requisitionIdGreenhouse's job ID and the company's internal requisition ID
titleJob title
location, officesThe location string, plus the structured office list
departmentsEvery department the role is filed under
urlDirect apply link
firstPublished, updatedAt, applicationDeadlinePosting timestamps
descriptionFull description as clean plain text, with HTML stripped and entities decoded
scrapedAtWhen the run happened

RUN_SUMMARY in the key-value store holds per-run counts, the filters you used, and any board that failed.

What people use it for

  • Job aggregators. Ingest hundreds of company boards on a schedule.
  • Recruiting intelligence. See which teams a competitor is hiring into, and where.
  • Lead generation. A company hiring for a role is usually a company buying for it.
  • Market research. Track hiring volume by department or location over time.
  • Job hunting. Watch a shortlist of companies and filter down to what you actually want.

Quick start

Two boards, everything on them:

{
"boards": ["stripe", "figma"]
}

Remote engineering roles only, capped:

{
"boards": ["stripe", "https://boards.greenhouse.io/airbnb"],
"searchTerms": ["engineer", "developer"],
"locationFilter": ["remote"],
"departmentFilter": ["engineering"],
"maxJobsPerBoard": 50,
"includeDescription": true
}

A light sweep for change detection:

{
"boards": ["stripe"],
"includeDescription": false
}

Input

FieldTypeDefaultNotes
boardsarrayrequiredBoard tokens like stripe, or full board URLs. You can mix both. URLs get normalised to tokens for you.
searchTermsarray[]Keep only titles containing one of these terms, case-insensitive. Empty means keep everything.
locationFilterarray[]Keep only locations containing one of these terms. Empty means all locations.
departmentFilterarray[]Keep only departments matching one of these terms. Empty means all departments.
maxJobsPerBoardinteger0Cap jobs saved per board, applied after filtering. 0 means no limit.
includeDescriptionbooleantrueInclude the full plain-text description. Turn it off for a much smaller, faster dataset.

The three filters are independent and combine with AND. A job has to match at least one term in each filter you actually filled in.

Output example

{
"board": "stripe",
"company": "Stripe",
"jobId": 8023928,
"requisitionId": "REQ-1234",
"title": "Account Executive, Bridge",
"location": "London",
"offices": ["London"],
"departments": ["Sales"],
"url": "https://stripe.com/jobs/search?gh_jid=8023928",
"firstPublished": "2026-07-14T09:12:00Z",
"updatedAt": "2026-08-01T11:03:22Z",
"applicationDeadline": null,
"description": "About the team\n\nBridge is .",
"scrapedAt": "2026-08-06T12:00:00.000Z"
}

Finding a board token

Open a company's careers page and look at the URL.

URL you seeToken
boards.greenhouse.io/acmeacme
job-boards.greenhouse.io/acmeacme
./embed/job_board?for=acmeacme

You can paste the whole URL and let the Actor pull the token out. If the careers page sits on the company's own domain, view source and search for greenhouse.io. The token is nearly always in an iframe or a fetch URL.

API example

curl -X POST "https://api.apify.com/v2/acts/arman-bd~greenhouse-jobs-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"boards": ["stripe"],
"searchTerms": ["engineer"],
"maxJobsPerBoard": 25
}'

JavaScript example

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('arman-bd/greenhouse-jobs-scraper').call({
boards: ['stripe', 'figma'],
searchTerms: ['engineer'],
locationFilter: ['remote'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const job of items) console.log(`${job.company} - ${job.title} (${job.location})`);

Notes

  • A bad board won't kill the run. Unknown boards return HTTP 404 and land in RUN_SUMMARY.failures. The Actor only errors out if every board fails.
  • Transient errors get retried. 429s and 5xx responses get three attempts with linear backoff.
  • Descriptions are decoded twice. Greenhouse returns entity-encoded HTML and some boards double-encode it, so entities are decoded before tags are stripped and again afterwards. You get real text, not <p>.
  • Public data only. No authentication, no personal data, nothing that gets around access controls.

FAQ

Do I need a Greenhouse API key? No. You supply no credentials.

Does it include salary? Only if the company wrote it into the description. Greenhouse's public feed has no structured salary field, and this Actor won't invent one.

How many boards can I pass at once? There's no hard cap. Each board is one request and they run in sequence, so hundreds per run is normal.

Why did a board return nothing? Either the token is wrong or your filters excluded everything. RUN_SUMMARY reports listed, matched and saved counts per board, which tells the two apart straight away.

Can I get only new or changed jobs? Run it on a schedule and diff on jobId and updatedAt. Setting includeDescription to false makes those sweeps a lot cheaper.

Can I plug it into something else? Yes. Apify API, the client libraries, webhooks, scheduled runs, dataset exports to JSON, CSV or Excel, or MCP. The output is structured JSON.