At a glance
What the Greenhouse Jobs Scraper does
- Search by
- Company domain or name (stripe.com), careers page, board link or ats:slug, or a bundled starter list of 49 verified employers (25 Canadian)
- Sources
- Greenhouse, Lever, Ashby and SmartRecruiters official job-board APIs
- Filters
- Canada only, countries, remote only, title keywords, max jobs per company, new jobs only
- Output
- 27 fields per job; JSON, CSV, Excel, API
- Automate
- Schedules, webhooks, Zapier, Make, n8n, Google Sheets, MCP for AI agents
Who it is for
- Job boards and aggregators adding direct-from-employer postings every day with the new-jobs-only mode
- Recruiters watching target companies for new openings
- Canadian job sites using the Canada-only filter and province codes
- HR and market analysts tracking hiring by company, team and salary band
Output
What you get
- Title, company, department, team
- Locations, ISO country codes, Canadian province codes, is_canada, remote flag, workplace type (remote/hybrid/onsite)
- Employment type (normalised + as published)
- Salary min/max, currency and interval when published (pay-transparency boards)
- Posted and updated dates in ISO 8601 UTC
- Apply link, posting link, full description as text and HTML
- Stable job_id for joins and dedupe
Example
Input and output
Input
{
"companies": [
"geotab.com",
"https://jobs.ashbyhq.com/wealthsimple",
"lever:pointclickcare"
],
"canadaOnly": true,
"titleKeywords": [
"engineer"
],
"incremental": true
}One output record
{
"job_id": "lever:pointclickcare:76cdab93-644a-47d6-a89d-9c4add288692",
"ats": "lever",
"company_token": "pointclickcare",
"company": "PointClickCare",
"title": "(Canada) Sales Development Representative (6 month contract)",
"department": "Acute & Payer",
"team": "Sales",
"locations": [
"Remote or Mississauga"
],
"countries": [
"CA"
],
"provinces": [
"ON"
],
"is_canada": true,
"remote": true,
"workplace_type": "remote",
"employment_type": "CONTRACT",
"employment_type_raw": "Contract",
"salary_min": 29,
"salary_max": 31,
"salary_currency": "CAD",
"salary_interval": "hour",
"salary_text": "This is contract role paid in an hourly rate, based on a 40 hour work week. The offer is $29 - 31CAD per hour, and is not eligible for benefits or paid time…",
"posted_at": "2026-10-13T20:52:35Z",
"updated_at": "2026-10-13T20:52:35Z",
"apply_url": "https://jobs.lever.co/pointclickcare/76cdab93-644a-47d6-a89d-9c4add288692/apply",
"description_text": "The Role: As an entry-level sales position, the Sales Development Representative (SDR) will support a Senior Sales Executive and be responsible for…",
"source_url": "https://jobs.lever.co/pointclickcare/76cdab93-644a-47d6-a89d-9c4add288692",
"scraped_at": "2026-11-04T11:17:28Z"
}From a real run of this tool; long text and lists shortened here.
How to use it
Three steps
- Type company domains into Companies (e.g. stripe.com, notion.so), or paste careers pages, board links or ats:slug (greenhouse:stripe), or pick a bundled starter list.
- Optionally narrow it: Canada only, countries, remote only, title keywords, max jobs per company; turn on 'Only new jobs since last run' for a daily feed.
- Click Start, then download JSON, CSV or Excel, or schedule the run and send results to Google Sheets, Zapier, Make or n8n.
API
Call it from Python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("aurelix/greenhouse-jobs-scraper").call(run_input={'companies': ['geotab.com',
'https://jobs.ashbyhq.com/wealthsimple',
'lever:pointclickcare'],
'canadaOnly': True,
'titleKeywords': ['engineer'],
'incremental': True})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)pip install apify-client. The same input works from the Apify console, a schedule, Make, n8n, Zapier or an AI agent through the Apify MCP server.
Pricing
Pay per result
| Per 1,000 jobs, free plan | $1.50 |
| Per 1,000 jobs, paid plans | $1.05 |
| Start fee per run | $0.00005 |
Live prices from the Apify Store; no subscription and no platform usage billed on top. A price change is scheduled; the Store page shows it before it applies. See the Store page.
Honest limits
What it does not do
- Domains are matched to a board automatically, but when the careers page does not link its ATS board and the board name differs from the domain (e.g. Ubisoft's SmartRecruiters board is 'Ubisoft2'), paste the board link. There is no search across all companies.
- Only Greenhouse, Lever, Ashby and SmartRecruiters boards. Workday, iCIMS, Taleo and custom career sites are not covered.
- Country and province are detected from text when the ATS gives none; unusual location strings can be missed.
- Lever and Ashby do not publish an 'updated' time, so updated_at equals posted_at there. Lever and Ashby have no company display name; the board token is used unless the company is in the starter list.
- SmartRecruiters needs one extra request per job for the description; turn descriptions off for very large boards.
- 'Max jobs per company' is applied before the 'new since last run' filter.
FAQ
Questions buyers ask
Can I scrape Lever, Ashby and SmartRecruiters jobs too?
Yes. The same run reads Greenhouse, Lever, Ashby and SmartRecruiters boards and returns them in one 27-field schema.
Is there a cheaper alternative to Fantastic Jobs' career-site job API?
Yes, for Greenhouse, Lever, Ashby and SmartRecruiters boards. This Actor costs $1.50 per 1,000 jobs on the free plan and $1.05 on paid plans; fantastic-jobs/career-site-job-listing-api costs $12.00, and its feed version $2.50 and $2.00. It reads each employer's board live through the official ATS APIs. Fantastic Jobs covers 58 applicant tracking systems against 4 here, so it wins if you need Workday, iCIMS and the rest.
How do I get jobs from a company's Greenhouse or Lever board into Google Sheets or an AI agent?
Two ways. For a fixed workflow, add Apify's n8n or Make node, choose **Run Actor**, enter aurelix/greenhouse-jobs-scraper and map the dataset to the next step. For an AI agent (Claude, ChatGPT, Cursor or an n8n AI Agent node), add https://mcp.apify.com/?tools=aurelix/greenhouse-jobs-scraper as an MCP server and ask for a company's open jobs in plain words; setup for each client is in the section above. Runs bill your own Apify account at the same per-result price.
How much does the Greenhouse Jobs Scraper cost?
$1.50 per 1,000 jobs ($1.05 on paid Apify plans), billed through your Apify account; you pay only for results. Apify's free plan includes $5 of credit a month, enough for about 3,333 jobs. A price change is scheduled; the Store page shows it before it applies.
Do I need the company's board token?
No. Type the company's domain (stripe.com): the Actor reads its public careers page (obeying robots.txt) and uses the Greenhouse, Lever, Ashby or SmartRecruiters board it links to; failing that it tries the domain's name on each ATS and keeps the board only when it points back to the domain. A bare name like 'Stripe' takes the first ATS with a board of that name, so prefer the domain. The run log shows which board was used. If nothing is found, paste a job link from the careers page (e.g. jobs.lever.co/spotify) or ats:slug (greenhouse:stripe).
Is this legal?
It reads only public data any logged-out visitor can see: the public job-board APIs of Greenhouse, Lever, Ashby and SmartRecruiters that employers use to show jobs on their own sites. To find a board from a domain it reads the company's public careers page and obeys robots.txt. It goes at a polite pace, never logs in and never solves CAPTCHAs. It returns job posting fields (title, location, pay, dates, description, apply link); personal emails in descriptions are removed and no candidate or recruiter profiles are collected. To have a record removed, open an issue on this Actor's Issues tab; if an employer or job-board provider formally asks us to stop, this Actor will stop. You are responsible for using the data lawfully, incl. anti-spam and privacy laws; this is not legal advice.
How does 'new since last run' work?
The Actor remembers job IDs it has returned for the same companies and filters (or for the state name you set) and returns only unseen ones. Jobs are forgotten 60 days after they were last seen.
How is Canada detected?
From the ATS country field where present, otherwise from the location text: 'Canada', province names and codes (ON, QC, BC...) and major Canadian cities. 'San Francisco, CA' is California, not Canada.
Why is salary empty for some jobs?
Salary is returned only where the employer publishes a pay range (common for Canadian and US pay-transparency jurisdictions). We never guess.
Can I use it from an AI assistant?
Yes. The input fields are described for agents: give 'companies' and optional filters. It works through Apify's MCP server and API.
Does it cover Workday, iCIMS or LinkedIn?
No. Those have no official public job-board API; this Actor uses only official endpoints. More sources may be added as separate sister Actors.
What am I charged when a board returns nothing or a run fails?
Each job written to the dataset is one job charge; nothing else is charged per job. A board with no jobs that pass your filters costs nothing beyond the small per-run start fee. If no entry in Companies resolves to a board, the run fails at once with 'no supported job board found'. If one board errors (for example a token that no longer exists), it is skipped with a warning in the log and the others carry on; only when every board fails is the run marked failed.
How are duplicates handled?
Every job has a job_id made of the ATS, the board token and the posting id, lower-cased. Inputs that point at the same board (a domain and its board link, or a board that is also in the starter list) are merged before scraping, and each job_id is returned once per run. To skip jobs returned by earlier runs, turn on 'Only new jobs since last run'.
How many jobs can one run return, and how long does it take?
There is no run-wide cap: every open job on each board is returned unless you set 'Max jobs per company'. Boards are read four at a time. In our test runs, 4 boards took about 4 s and 25 boards returned 691 jobs in 27 s. SmartRecruiters needs one extra request per job for its description, so large SmartRecruiters boards are slower; switch descriptions off for those. To cap spend, set the run's maximum charge in Apify and output stops there.
Does changing the filters reset 'Only new jobs since last run'?
Yes, unless you name the feed. The memory is keyed on the boards plus Canada only, Remote only, Title keywords and Countries, so changing any of those starts a fresh memory and the next run returns everything again. 'Max jobs per company' and 'Include full description' are not part of the key. Set 'Incremental state name' to keep one feed while you change the companies or filters.
What do remote, workplace_type and employment_type mean?
workplace_type is remote, hybrid or onsite, taken from the ATS's own field where it has one (Lever, Ashby and SmartRecruiters) and otherwise from the location or metadata text; it is empty when nothing says. remote is the ATS's own remote flag where it has one (Ashby and SmartRecruiters), otherwise true when the workplace type is remote. employment_type is normalised to FULL_TIME, PART_TIME, CONTRACT, TEMPORARY, INTERN or OTHER, and employment_type_raw keeps the employer's own wording.
Which countries and languages does it cover?
Any country an employer posts in. countries holds ISO codes from the ATS country field or the location text, and stays empty when no country can be detected; province tags are only for Canada. Titles and descriptions come in the language the employer wrote them, and Title keywords is a plain text match, so use the words of the posting's language (for example 'ingénieur' for French postings).
Does it use proxies, and does it respect robots.txt?
It uses no proxy: it calls the public job-board APIs of Greenhouse, Lever, Ashby and SmartRecruiters directly, at most four boards at a time, and backs off on HTTP 429 and server errors. When you give a company domain, it reads up to five pages of that company's public site to find the board, and only pages robots.txt allows.
Can I get a Slack or webhook message when new jobs appear?
Yes. Put a Slack incoming-webhook URL in 'Slack webhook URL', or any URL in 'Webhook URL' for Zapier, Make or n8n. After each run it posts the number of jobs saved (new ones only, when new-only mode is on) and the top 10 with links. Nothing is sent when the run saved nothing.
Guides
Tutorials using this tool
Related
Related tools
Try the Greenhouse Jobs Scraper
Open it on the Apify Store, paste the example input above and click Start. Results download as CSV, Excel or JSON.