Greenhouse Jobs API - Career Page Scraper & Apply Links avatar

Greenhouse Jobs API - Career Page Scraper & Apply Links

Pricing

from $2.00 / 1,000 job results

Go to Apify Store
Greenhouse Jobs API - Career Page Scraper & Apply Links

Greenhouse Jobs API - Career Page Scraper & Apply Links

Greenhouse jobs API and career page scraper. Read live postings from any Greenhouse job board or careers page, or search thousands of known Greenhouse ATS boards in one run. Full descriptions, departments, locations and direct apply links as JSON.

Pricing

from $2.00 / 1,000 job results

Rating

0.0

(0)

Developer

Sulle H

Sulle H

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

9 days ago

Last modified

Categories

Share

Greenhouse Jobs Scraper — Every Open Role, With Descriptions & Apply Links

Give it a company and get back every job currently open on that company's Greenhouse board — full descriptions, departments, offices, locations, requisition ids and direct apply links, as structured JSON.

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

No login, no cookies, no proxies, no API key. Greenhouse publishes this data openly; this Actor reads it, normalizes it and hands it to you in one call.

What you get

Every row has the same shape:

FieldDescription
company / companySlugCompany name and its Greenhouse board slug
jobIdGreenhouse job id — stable, so it works as a dedupe key across runs
titleJob title
locationLocation string as shown on the board
officesStructured office list, when the company defines offices
departmentsDepartment or team
firstPublishedAtWhen the role first went live
updatedAtLast modification timestamp
applyUrlDirect application link on the company's own board
requisitionIdInternal requisition id, when the company exposes one
descriptionTextFull job description as plain text
scrapedAtWhen this row was read

Input

{
"boards": ["databricks", "https://job-boards.greenhouse.io/figma"],
"titleFilter": "engineer",
"locationFilter": "remote",
"includeDescription": true,
"maxJobsPerBoard": 200
}
OptionWhat it does
boards (required)One entry per company. Bare slugs and full board URLs both work.
titleFilterCase-insensitive substring match on the job title.
locationFilterCase-insensitive substring match on the location.
includeDescriptionSet false for a faster, lighter run when you only need titles and links.
maxJobsPerBoardCap the rows per company. Defaults to 100 — a board like Databricks has 800+ open roles and this Actor bills per row.

Finding a board slug

Open the company's careers page and look at the URL:

URL you seeSlug
job-boards.greenhouse.io/databricksdatabricks
boards.greenhouse.io/stripestripe
careers page with ?for=acme in the sourceacme

Embedded boards work too — many companies frame Greenhouse into their own site, and the slug is still in the page source. You can also paste the full URL straight into boards and let the Actor pull the slug out.

What people use it for

Tracking one employer. Watch a company you want to work for, or a competitor you want to understand. Run it on a schedule and diff the jobId set.

Sourcing and recruiting. Pull open roles across a list of target companies, filter by title, and work from a clean spreadsheet instead of twenty browser tabs.

Market research. Departments and office locations tell you where a company is investing before any announcement does.

Feeding a job board. Every row carries applyUrl pointing at the employer, so your users apply directly rather than through a middleman.

Scale beyond one ATS

This Actor is deliberately narrow: you name the Greenhouse boards, it reads them. If you need breadth instead — search across companies without knowing who uses what — two companion Actors share the same output schema:

  • Career Site Job Feed — searches a bundled registry of 40,000+ company boards across Workday, Greenhouse, SmartRecruiters, Workable, Lever, Ashby and Breezy in one run.
  • New Job Alerts — the same coverage, but each run returns only postings that appeared since the previous run.

Or stay narrow and switch platform. These work the same way this Actor does, one applicant tracking system each, and emit the same rows:

What Greenhouse publishes, and what it does not

Greenhouse's board endpoint is generous compared with most applicant tracking systems, which is why this Actor can return full descriptions where others cannot:

AvailableNot available
Job title, location, officesSalary as a structured field
Departments and sub-departmentsApplicant counts or hiring stage
Full description as HTMLRecruiter or hiring-manager contacts
First published and last updated timestampsAnything behind the employer's login
Requisition id, where the company sets oneCandidate data of any kind

Descriptions arrive as entity-escaped HTML. This Actor decodes them twice — Greenhouse double-encodes some fields — strips tags, and returns readable plain text, so you are not writing a parser.

Reading the data

jobId is stable. It does not change while a posting is open, so companySlug:jobId is a safe key for detecting what opened and closed between runs.

offices and departments are arrays. A role can sit in several offices; a role can belong to one department with a parent above it. Both come through as published rather than flattened to a single string.

firstPublishedAt is when the role went live, and updatedAt moves when the employer edits it. For "what is new" logic, use firstPublishedAt — an edit should not make an old role look fresh.

descriptionText is capped at 20,000 characters. Long postings are truncated rather than returned in full, which keeps rows a predictable size.

Recipes

Watch one employer. Run daily with a single slug, keep the jobId set, and diff it. New ids are openings; missing ids are roles that closed.

Build a target list. Pass twenty company slugs, set titleFilter to the role you sell into, and you have a list of employers hiring for it right now, each with an apply link you can verify.

Feed a niche job board. Pick the companies your audience cares about, run hourly, and publish straight from the dataset. Because every row carries the employer's own applyUrl, your users apply at the source.

Research a company's direction. Departments and office locations across a board show where headcount is going before any announcement does.

Finding slugs at scale

This Actor needs you to name the boards. If you do not know who uses Greenhouse, the companion Career Site Job Feed ships a registry of 5,751 known Greenhouse boards — run it with providers: ["greenhouse"] and the companySlug column is your list.

Limits worth knowing

  • Boards are read in sequence. A dozen companies is seconds; several hundred is minutes. For breadth across thousands of employers, use the feed Actor instead.
  • A wrong slug is not fatal. It lands in FAILED_BOARDS and the rest of the run continues.
  • Embedded boards work, but you need the slug from the page source (?for=acme), not the URL of the page you are looking at.
  • No login, no proxies. If a company's board is private, no scraper can see it, including this one.

Performance

A large board (800+ roles) completes in well under a minute with descriptions on. Boards are read in sequence, so a run over a dozen companies is still a matter of seconds.

Use it as an API

Most people who rely on this Actor never open the Apify console after the first run — they call it from their own code and read the rows straight back. One request in, job rows out, no polling and no dataset id to chase:

curl -X POST "https://api.apify.com/v2/acts/starbright_overlap~greenhouse-jobs-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"boards": ["databricks", "stripe"], "maxJobsPerBoard": 100}'
import requests
rows = requests.post(
"https://api.apify.com/v2/acts/starbright_overlap~greenhouse-jobs-scraper/run-sync-get-dataset-items",
params={"token": "YOUR_TOKEN"},
json={"boards": ["databricks", "stripe"], "maxJobsPerBoard": 100},
timeout=300,
).json()
for r in rows:
print(r["company"], "—", r["title"], "—", r["applyUrl"])
const rows = await (await fetch(
'https://api.apify.com/v2/acts/starbright_overlap~greenhouse-jobs-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN',
{ method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({"boards": ["databricks", "stripe"], "maxJobsPerBoard": 100}) },
)).json();

Your token is at Settings → Integrations in the Apify console. Keep maxJobs set to what you actually need — it is the cap that decides what the call costs.

Running it on a schedule instead

If you want the rows to arrive without asking, add a Schedule from the Actor page (Actions → Schedule) and point a webhook at your endpoint. A daily schedule plus the postedWithinDays filter is the usual setup for a job board or an alerting pipeline.

Pricing

Pay per result — you are charged per job row delivered. A board that fails or returns nothing costs you nothing. Platform usage is included rather than billed on top, so the per-result price is the whole price.

Notes

  • Bad or dead slugs never abort the run. They are collected into a FAILED_BOARDS record in the key-value store, so you can see exactly which ones failed and why.
  • jobId is stable per posting, which makes companySlug:jobId a reliable key for detecting new and removed roles between runs.
  • Set includeDescription: false when you only need titles and links — it is several times faster and cheaper.

Frequently asked

Is there a free Greenhouse API? Greenhouse's board endpoint is public and unauthenticated, so yes, technically. This Actor exists because reading it well is fiddly: descriptions arrive as escaped HTML, offices and departments are nested, and slug discovery from a careers page is not obvious. You get clean plain text and a flat schema instead.

Can I scrape several companies at once? Yes — put as many slugs in boards as you like. Each is read independently, and one failing does not stop the others.

How do I get only engineering roles? Set titleFilter to engineer. It is a case-insensitive substring match, so it catches "Software Engineer", "Engineering Manager" and "Site Reliability Engineer".

Do I get salary data? Only when the employer writes it into the job description, and only with includeDescription: true. Greenhouse's board endpoint has no structured salary field, so this Actor does not invent one.

How do I find new postings since yesterday? Either diff jobId between runs yourself, or use New Job Alerts, which keeps that memory for you across 40,000+ boards.

What if the company is not on Greenhouse? Then this Actor cannot see it. Career Site Job Feed covers seven applicant tracking systems and can tell you which one a company uses.

Does it work with embedded boards? Yes. If a company frames Greenhouse into its own careers page, find the slug in the page source (?for=acme) and pass that.