Greenhouse Jobs Scraper & API avatar

Greenhouse Jobs Scraper & API

Pricing

Pay per usage

Go to Apify Store
Greenhouse Jobs Scraper & API

Greenhouse Jobs Scraper & API

Free Greenhouse jobs scraper: pay only for platform usage. Extract every open job from one or many Greenhouse boards with titles, locations, departments, salary ranges, remote/hybrid type, descriptions, publish dates, and application questions. Filter by department, location, keywords, or date.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Milad Amirzadeh

Milad Amirzadeh

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Collect every open job from one or many Greenhouse job boards in a single run: titles, locations, departments, offices, salary ranges, remote/hybrid type, full descriptions, publish dates, and application questions. Use the results for job-board feeds, recruiting research, salary benchmarking, hiring-trend tracking, and scheduled employer snapshots, with no login or API key.

The Actor is free to use: you pay only for Apify platform usage, which is typically a fraction of a cent per run.

Greenhouse is the applicant tracking system behind the careers pages of companies such as Airbnb, Stripe, Figma, Anthropic, Databricks, Cloudflare, and thousands more. This Actor reads Greenhouse's public Job Board API directly over HTTP. It runs without a browser or proxy and finishes most companies in a few seconds.

What you get

  • All open jobs for one or many companies per run, from a slug (stripe) or any board URL
  • Specific job postings by ID or URL (job_details mode)
  • Salary ranges (min, max, currency) whenever the employer publishes pay transparency data
  • Workplace type (Remote, Hybrid, On-site) detected from employer fields and location text
  • Departments, offices, requisition ID, custom employer fields, and language
  • Full job description as HTML and clean plain text
  • First-published and last-updated timestamps
  • Optional application form questions
  • Filters for department, location, keywords, and publish or update date
  • US and EU Greenhouse boards (job-boards.greenhouse.io and job-boards.eu.greenhouse.io)
  • A per-company run summary showing open, matched, and saved counts, plus any slugs that were not found

Quick start

All jobs from several companies

{
"mode": "company_jobs",
"companySlugs": ["stripe", "figma", "https://job-boards.greenhouse.io/airbnb"],
"maxJobsPerCompany": 9999
}

Filtered: recent remote engineering roles mentioning AI

{
"mode": "company_jobs",
"companySlugs": ["stripe", "figma", "airbnb"],
"filterDepartment": "Engineering",
"filterLocation": "Remote",
"jobKeywords": ["AI", "machine learning", "backend"],
"firstPublishedAfter": "2026-08-01",
"maxJobsPerCompany": 200
}

Specific jobs, with application questions

{
"mode": "job_details",
"jobIds": [
"airbnb/8187190",
"https://job-boards.greenhouse.io/airbnb/jobs/8232207",
"https://job-boards.eu.greenhouse.io/parloa/jobs/4925162101"
],
"includeQuestions": true
}

How to find a company's slug

Open the company's Greenhouse board. The slug is the path segment right after greenhouse.io/:

Board URLSlug
https://job-boards.greenhouse.io/stripestripe
https://boards.greenhouse.io/airbnb/jobs/8187190airbnb
https://job-boards.eu.greenhouse.io/parloaparloa
https://boards.greenhouse.io/embed/job_board?for=figmafigma

You can paste any of these URLs directly. The Actor extracts the slug for you.

Input reference

FieldTypeDefaultBehavior
modestringcompany_jobscompany_jobs lists all open jobs for each company. job_details fetches specific jobs.
companySlugsarray["airbnb"]Board slugs or board URLs. Used in company_jobs mode. Duplicates are removed.
jobIdsarray[]slug/jobId, slug:jobId, or Greenhouse job URLs. Used in job_details mode.
includeContentbooleantrueSave the description as HTML (content) and plain text (descriptionText).
includeQuestionsbooleanfalseFetch application form questions. Adds one small request per job.
filterDepartmentstringemptyCase-insensitive partial match against department names.
filterLocationstringemptyCase-insensitive partial match. Place names (London, Germany) match the job location and office names. Workplace terms (Remote, Hybrid, On-site) match the job location and the detected workplaceType, not office names, because employers often use labels like "Remote India" for office-based teams.
jobKeywordsarray[]Up to 20 keywords or phrases. A job matches when any of them appears as a whole word in its title or description.
firstPublishedAfterstringemptyYYYY-MM-DD or relative (7 days). Inclusive, compared as UTC dates.
updatedAfterstringemptySame format as above, applied to the last-updated timestamp. Useful for daily incremental runs.
maxJobsPerCompanyinteger500Maximum jobs saved per company after filtering, newest first. Use 9999 for all.
proxyConfigurationobjectoffOptional. The API is public, so a proxy is not required.

All filters that you set must match (AND). Filters apply only in company_jobs mode.

Keyword matching uses whole words, so AI matches "AI Engineer" and "Applied AI" but not "maintain" or "email". Add every form you want to catch, such as engineer and engineering.

Output

Each saved job looks like this:

{
"jobId": 8187190,
"title": "Senior Staff Software Engineer, Tech Foundations",
"companyName": "Airbnb",
"companySlug": "airbnb",
"location": "Remote",
"workplaceType": "Remote",
"departments": [{ "id": 77, "name": "Software Engineering" }],
"departmentNames": ["Software Engineering"],
"offices": [{ "id": 63868, "name": "United States", "location": null }],
"url": "https://job-boards.greenhouse.io/airbnb/jobs/8187190",
"absoluteUrl": "https://careers.airbnb.com/positions/8187190?gh_jid=8187190",
"salaryMin": 244000,
"salaryMax": 305000,
"salaryCurrency": "USD",
"payRanges": [
{ "title": "Pay Range", "min": 244000, "max": 305000, "currency": "USD", "description": "Our job titles may span more than one career level..." }
],
"content": "<div class=\"content-intro\"><p>Airbnb was born in 2007...</p></div>",
"descriptionText": "Airbnb was born in 2007 when two hosts welcomed three guests...",
"metadata": [{ "name": "Workplace Type", "value": "Remote" }],
"firstPublished": "2026-09-18T17:33:00-04:00",
"updatedAt": "2026-09-24T18:49:00-04:00",
"applicationDeadline": null,
"language": "en",
"requisitionId": "ONE",
"internalJobId": 3542815,
"questions": null,
"scrapedAt": "2026-09-26T11:21:13+00:00"
}
FieldMeaning
jobIdGreenhouse job post ID.
titleJob title.
companyName / companySlugCompany name from Greenhouse and the board slug.
locationLocation text shown on the posting.
workplaceTypeRemote, Hybrid, On-site, or null. Detected from employer fields, then from location text.
departments / departmentNamesDepartments as objects and as a simple list of names.
officesOffices as {id, name, location}.
urlHosted Greenhouse job page.
absoluteUrlThe job on the company's own careers site when it has one.
salaryMin / salaryMax / salaryCurrencyFirst published pay range, in currency units (not cents). null when not published.
payRangesAll published pay ranges, for example separate ranges per region.
content / descriptionTextDescription as HTML and as plain text. null when includeContent is off.
metadataCustom employer fields such as cost center or employment type.
firstPublished / updatedAtISO 8601 timestamps with the employer's time zone offset.
applicationDeadlineDeadline when the employer set one.
language / requisitionId / internalJobIdPosting language, employer requisition ID, and the Greenhouse job ID shared by all postings of the same role.
questionsApplication questions as {label, required, description, fields} when includeQuestions is on.
scrapedAtWhen the job was collected (UTC).

Results appear in the default dataset. Use the Job overview view for compact metadata, salaries, and links, or the Job descriptions view for text.

Run summary

Each run also writes an OUTPUT record to the default key-value store. It shows every target's status (ok, not_found, or error) and its open, matched, and saved job counts, so you can spot mistyped slugs without reading the log. When no target succeeds, the run is marked as failed.

API and exports

Run the Actor from your application with the standard Apify API:

curl -X POST \
"https://api.apify.com/v2/acts/miladamirzadeh~greenhouse-jobs-scraper/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"companySlugs": ["stripe", "figma"],
"filterLocation": "Remote",
"maxJobsPerCompany": 50
}'

You can also use the generated Python, JavaScript, CLI, OpenAPI, and MCP examples in the Actor's API tab. Datasets export to JSON, CSV, Excel, XML, and HTML.

Recurring workflows

Save a tested input as an Apify Task and schedule it daily or weekly. For daily runs, set updatedAfter to 1 day so each run saves only postings that are new or changed since the day before.

Typical uses:

  • Job-board and aggregator ingestion
  • Salary benchmarking across companies that publish pay ranges
  • Tracking hiring volume by department or location
  • Alerts for new roles at target companies, through Apify integrations such as Slack, Google Sheets, Make, or Zapier

Each run produces an independent dataset. The Actor does not keep history between runs.

Practical limitations

  • You need each company's Greenhouse slug. Greenhouse has no public directory of all boards.
  • Only public job boards are supported. Internal or employee-only boards are not available through the public API.
  • Salary fields are filled only when the employer publishes pay transparency data in Greenhouse. Some employers put pay only in the description text, and those jobs have null salary fields.
  • workplaceType is best-effort. It uses employer metadata and location text and does not read the description.
  • Keyword and location filters are literal text matches, not semantic search.
  • Filters apply only in company_jobs mode.
  • Closed jobs return not_found in job_details mode.

Pricing

The Actor is free. There is no per-run or per-result fee; you pay only for the Apify platform usage (compute units) of your runs, which the Apify free plan's monthly credit covers for most users.

Runs are cheap because the Actor makes plain HTTP requests with no browser or proxy. It runs at 512 MB by default, and most companies finish in a few seconds. For example, the full Databricks and Anthropic boards (about 1,500 jobs) took under a minute at 512 MB, which is less than 0.01 compute units. Turning on includeQuestions adds one request per job and makes runs a little longer.

Troubleshooting and support

If a run returns no jobs:

  1. Open the OUTPUT record. A not_found status means the slug is wrong or the company does not use Greenhouse.
  2. Open the company's board in a browser and copy the slug from the URL.
  3. Remove the filters temporarily to rule out an overly narrow match.

For support, open an Actor issue with your input (without tokens), the run link, and what you expected to see.