Greenhouse Jobs Scraper: Lever, Ashby, Workable
Pricing
from $0.65 / 1,000 job postings
Greenhouse Jobs Scraper: Lever, Ashby, Workable
Scrape job postings from Greenhouse, Lever, Ashby, Workable and Recruitee boards for a list of companies. One row per job: title, location, department, apply URL, full description and pay when published. Filter by title, location or remote; get only new jobs.
Pricing
from $0.65 / 1,000 job postings
Rating
0.0
(0)
Developer
Pradio Actors
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 hours ago
Last modified
Categories
Share
What does Greenhouse Jobs Scraper do?
Greenhouse Jobs Scraper reads the public job-board feeds of Greenhouse, Lever, Ashby, Workable and Recruitee for a list of companies in one run. Each posting is one row: title, company name, seniority, city, region and country, department, apply URL, the full description, and pay when the posting publishes it. You do not need to know a company's slug: give its name or its careers-page URL and the Actor finds the board. Or start from a preset list of AI or fintech companies. Filter by title, keywords, department, location, remote or posting age before anything is read; ask for only the postings you have not seen since your last run. No login, no browser, no applicant or Harvest APIs. The default company is ramp (Ramp's Ashby board).
Who uses Greenhouse Jobs Scraper
| Who | What they run it for |
|---|---|
| Talent intelligence and aggregators | Pull every open role across a list of companies, whichever of the five vendors each one uses, into one table with one shape. |
| Recruiters and sourcers | Refresh a target list's live postings, keep apply URLs and published pay, and see only what is new since last week. |
| Sales and hiring-signal work | Watch which roles a company opens, in which department and where, and whether pay is posted. |
| Agents and pipelines | Pass a list of company names and get rectangular rows instead of five vendor dialects. |
Features
- Finds the board from a company name or careers-page URL. Give
Hugging Faceorhttps://careers.bunq.comand the Actor tries the likely slugs on all five vendors until one answers. - Five vendors, one row shape. Greenhouse, Lever, Ashby, Workable and Recruitee postings come back with the same columns, in the same types.
- Preset company lists.
ai-startups(21 companies) andfintech(12 companies), each board checked on its vendor's public feed. - Filters before anything is read. Title, keywords, department, location, remote and posting age; a posting a filter removes costs nothing.
- Only the new jobs. Turn on
onlyNewand each run returns only the postings you have not had before, ready for a daily schedule. - Pay read where it is published. Structured pay fields from Ashby, Lever and Recruitee, and a range the posting text states next to a pay word on Greenhouse and Workable.
- Seniority and location split out. Seniority read from the title, and the location split into city, region and a two-letter country code.
What you can count on
- every row is charged only after it is written to your dataset; a row you cannot see is never billed
- a run that finds nothing returns one NO_MATCHING_LISTINGS row that says so, never an empty dataset
- a spending limit stops the run cleanly with a STOPPED_EARLY row saying how many rows were returned and how many were not
- every run writes a RUN_SUMMARY entry with rowsFetched, rowsPushed, rowsCharged and duplicatesDropped, so a short run and a broken one are told apart
- if a board changes its response, the run fails with the error in the log; it never returns rows full of nulls and calls it success
Why this one
The most-used alternative was run on 2026-09-25 on the same board as this Actor's sample, Ramp's Ashby board. Both filled the title, the pay range, the employment type and the remote status on every posting they returned, so on a board that publishes those fields the two agree. The differences are the price, the memory and the reach: it charges $0.0015 a posting and this Actor charges $0.0012; it runs at 1024 MB and this Actor at 256 MB; and this Actor also reads Recruitee boards, answers a misspelt company with a row that names it, and keeps a removal list that every run checks before it reads anything.
What data does Greenhouse Jobs Scraper return?
One real posting from the default Ramp board (description shortened):
{"platform": "ashby","official_url": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245","title": "Security Engineer, Cloud","posted_date": "2026-04-07T17:12:35.753+00:00","location": "New York, NY (HQ)","is_remote": false,"workplace_type": "Hybrid","description": "ABOUT RAMP\n\nRamp is building the smart infrastructure for finance teams, embedded in the transaction flow of every dollar a business spends.","job_type": "FullTime","department": "Engineering","job_id": "34413f8d-26bf-4bbc-8ade-eb309a0e2245","salary_minimum": 211400,"salary_maximum": 290600,"salary_currency": "USD","compensation": {"compensationTierSummary": "$211.4K – $290.6K • Offers Equity","scrapeableCompensationSalarySummary": "$211.4K - $290.6K","compensationTiers": [{"id": "5f7a903e-36e4-492c-ac09-f2745d717daa","tierSummary": "$211.4K – $290.6K • Offers Equity","title": null,"additionalInformation": null,"components": [{"id": "feaef96f-559f-4df8-a38c-3eee072a8d74","summary": "Offers Equity","compensationType": "EquityPercentage","interval": "NONE","currencyCode": null,"minValue": null,"maxValue": null},{"id": "3481c194-45fd-4b89-8592-e8f4d4b51f20","summary": "$211.4K – $290.6K","compensationType": "Salary","interval": "1 YEAR","currencyCode": "USD","minValue": 211400,"maxValue": 290600}]}],"summaryComponents": [{"compensationType": "EquityPercentage","interval": "NONE","currencyCode": null,"minValue": null,"maxValue": null},{"compensationType": "Salary","interval": "1 YEAR","currencyCode": "USD","minValue": 211400,"maxValue": 290600}]},"company_slug": "ramp","address": {"postalAddress": {"addressRegion": "NY","addressCountry": "USA","addressLocality": "New York City"}},"apply_url": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application","company_name": "Ramp","seniority": null,"salary_text": "$211.4K - $290.6K","pay_interval": "year","has_equity": true,"city": "New York City","region": "NY","country": "US","row_type": "ROW"}
The run that produced this example returned 100 postings on the default input (company = ["ramp"], maxItemsPerCompany = 100); the board listed 146.
Fields on every posting row
No column is always empty: every field in the table below is filled by at least one vendor, and the table says which.
| Field | Meaning | Ashby | Greenhouse | Lever | Workable | Recruitee |
|---|---|---|---|---|---|---|
platform | Which vendor answered | ashby | greenhouse | lever | workable | recruitee |
official_url | Public posting URL (link) | jobUrl | absolute_url | hostedUrl | url | careers_url |
title | Job title | title | title | text | title | title |
company_name | Employer's display name | slug in title case | company_name | slug in title case | board name | company_name |
seniority | Level the title states | title | title | title | title | title |
posted_date | Published time | publishedAt | first_published | createdAt | published_on | published_at |
location | Workplace text as published | location | location.name | categories.location | city, state, country | location |
city | City | addressLocality | read from location | read from location | city | city |
region | State, province or region | addressRegion | read from location | read from location | state | state_name |
country | Two-letter country code | addressCountry | read from location | country | countryCode | country_code |
is_remote | Remote postings only: hybrid and on-site read false; null when the vendor says nothing | workplaceType is Remote (isRemote when there is no workplace type) | word Remote in location, else null | workplaceType | telecommuting | remote |
workplace_type | remote, hybrid or onsite, as the vendor writes it (Ashby capitalises: Hybrid) | workplaceType | null | workplaceType | workplace | remote / hybrid / on_site |
description | Full posting text, plain or HTML as the vendor gives it | descriptionPlain | content | descriptionPlain | description + requirements + benefits | description + requirements |
job_type | Employment type in the vendor's words | employmentType | null | categories.commitment | employment_type | employment_type_code |
department | Department or team | department | departments[0].name | categories.department | department | department |
job_id | The vendor's own posting id | id | id | id | shortcode | id |
salary_minimum | Published pay floor | compensation minValue | the posting's pay ranges, else pay stated in the posting text | salaryRange.min | pay stated in the posting text | salary.min |
salary_maximum | Published pay ceiling | compensation maxValue | as above | salaryRange.max | as above | salary.max |
salary_currency | ISO code of the published pay | currencyCode | as above | salaryRange.currency | as above | salary.currency |
pay_interval | year, month, week, day or hour | interval | as above | salaryRange.interval | as above | salary.period |
salary_text | The pay as published, as text | pay summary | the range as written | built from salaryRange | the range as written | built from salary |
has_equity | The pay package includes equity | equity component | null | null | null | null |
compensation | The vendor's whole pay object, unchanged | compensation | pay_input_ranges | salaryRange | null | salary |
company_slug | The slug that answered | slug | slug | slug | account | company |
address | The vendor's structured location, unchanged | address | null | null | city, state, country | city, region, country |
apply_url | Where a person applies (link) | applyUrl | posting URL | applyUrl | application_url | careers_apply_url |
row_type | ROW on a posting, ITEM_STATUS on an entry this Actor does not read or cannot find, NO_MATCHING_LISTINGS when no posting matched, STOPPED_EARLY when a spend cap ended the run | |||||
reason | Status rows only: why there were no postings, why the run stopped early, or why an entry was not read (a vendor this Actor does not read, a board on the removal list, a board whose robots.txt disallows the feed, or no public board found, naming the vendors tried) | |||||
status | Entry-note rows only, and these two values are the only ones: vendor_not_read when the board is not read (a vendor this Actor does not read, a board on the removal list, or a Recruitee board whose robots.txt disallows the offers feed; reason says which), no_board_found when no vendor has a public board for the entry | |||||
entry | Entry-note rows only: the company entry exactly as you gave it | |||||
rowsFetched | Status rows only: postings received before de-duplication and the cap | |||||
rowsReturned | Status rows only: rows written to the dataset before this status row, uncharged entry notes included | |||||
rowsRemaining | Status rows only: fetched postings not returned |
A null in a cell above means that vendor does not publish the value on its public feed. The row still carries the column, as null, so every vendor's rows have the same shape.
Pay. Ashby, Lever and Recruitee publish pay as fields on many postings. Greenhouse and Workable publish it only inside the posting text, if at all. There the Actor reads a range only when it sits next to a pay word and carries a currency. It copies that range to salary_text exactly as written. The pay is always the posting's own figure: on sales roles an employer often publishes on-target earnings (base plus commission), and the row carries that range as published, not a base salary. A figure that is not a pay range (a funding round, a customer count) is not read. How often pay is stated depends on the employer: boards hiring in US states with pay-transparency laws state it on most postings, others rarely.
Location. city, region and country come from the vendor's structured location where it has one. Greenhouse and Lever give a text such as San Francisco, CA. The Actor splits it only when its shape is plain, and reads a US state or Canadian province code as that country. A text naming several places, or only Remote, leaves city null.
Seniority is read from the title alone: Intern, Junior, Senior, Staff, Principal, Lead, Manager, Director, Head of, VP and Chief titles, in English, German and French. A title that states no level (Software Engineer, Product Manager) is null, not assumed to be mid.
Pricing
Pay-per-event: $0.0012 per listing-returned, one posting written to the dataset. The platform also charges apify-actor-start at $0.00005 per GB of run memory, at least one per run. At this Actor's 256 MB default that is one per run.
Status rows (ITEM_STATUS, NO_MATCHING_LISTINGS, STOPPED_EARLY) and dropped duplicates are not charged. Postings removed by a filter are never read in full and never charged.
| Postings written | listing-returned | Start (default) | Total (those two) |
|---|---|---|---|
| 100 | $0.12 | $0.00005 | $0.12005 |
| 1,000 | $1.20 | $0.00005 | $1.20005 |
| 10,000 | $12.00 | $0.00005 | $12.00005 |
Platform compute is billed separately by Apify according to memory and duration. A run of 100 Ramp postings finished in about 11 seconds on the platform, measured at 1024 MB. A buyer's run uses the 256 MB default unless you raise it, and the time at 256 MB has not been measured, so a run there may take longer. Workable descriptions cost one request per kept posting; a run of 100 such postings takes about half a minute more.
How do I use Greenhouse Jobs Scraper?
- Open the Actor on Apify and press Start. The default input reads Ramp's board.
- In
company, add one entry per company: a company name (Hugging Face), its careers-page URL (https://careers.bunq.com), a slug (ramp), a tagged slug (greenhouse:stripe), or a public board URL. Or pick apresetlist. - Optionally set
titleKeyword,keywords,departments,locationKeyword,remoteOnlyorpostedWithinDaysto keep only the postings you want,maxItemsPerCompany(default 100), andonlyNewto skip what an earlier run already returned. - Download the dataset.
RUN_SUMMARYin the default key-value store has the counts.
Example input, the one this page's sample row came from:
{"company": ["ramp"],"maxItemsPerCompany": 100}
Worked examples
Use it to pull every open job at companies you know only by name. The Actor turns each name into its likely board slugs and tries them on every vendor.
{"company": ["Hugging Face", "Scale AI", "https://careers.bunq.com"],"maxItemsPerCompany": 50}
Use it to find engineering jobs at AI startups posted this week, from a preset list with several title words and one department filter.
{"preset": "ai-startups","keywords": ["engineer", "researcher", "scientist"],"departments": ["engineering", "research"],"postedWithinDays": 7,"maxItemsPerCompany": 30}
Use it to build a list of senior remote jobs with published pay. Filter on the board, then keep rows where salary_text is filled and seniority is senior or staff/principal in your spreadsheet.
{"company": ["ramp", "greenhouse:stripe", "lever:zoox"],"remoteOnly": true,"maxItemsPerCompany": 100}
Daily new jobs only. See the next section.
Daily new jobs only
Turn on onlyNew and run the Actor on a daily schedule (Apify Console, Schedules, cron 0 7 * * *). The first run returns every current posting and remembers each one it returned; every later run returns only postings that appeared since. Add postedWithinDays to keep the first run small.
Use it to get a daily feed of only the new jobs at fintech companies.
{"preset": "fintech","onlyNew": true,"postedWithinDays": 2,"maxItemsPerCompany": 100}
The memory is a named key-value store in your account, greenhouse-lever-ashby-job-seen, keyed by posting URL. A posting is remembered only after it was written to your dataset, so a run cut short by a spend limit leaves the rest for the next day. Delete that store to start over. Only the postings returned are charged, so a day with nothing new costs one start event and no posting events.
How to find a company's slug
Usually you do not need to. Put the company's name or its careers-page URL in company and the Actor tries the likely slugs (Scale AI gives scaleai and scale-ai) on all five vendors. The order is Ashby, Greenhouse, Lever, Workable, Recruitee. The company's own website is never fetched; only the vendors' public feeds are asked. The log says which board answered, and every row carries platform, company_slug and company_name so you can check it is the right employer.
When a name finds nothing, or finds a different company with the same slug, find the slug by hand:
- Open the company's careers page and click any job.
- Read the job's address. The slug is the part right after the vendor's host:
jobs.ashbyhq.com/ramp/...isashby:rampboards.greenhouse.io/stripe/jobs/...orjob-boards.greenhouse.io/stripe/...isgreenhouse:stripejobs.lever.co/zoox/...islever:zooxapply.workable.com/nuvei/...isworkable:nuveibunq.recruitee.com/o/...isrecruitee:bunq
- If the careers page shows jobs inside the company's own site, the vendor's address is often in the apply button's link.
- Paste the job address itself into
company: any vendor board URL is read directly.
Tag the slug with its vendor (greenhouse:stripe) to skip the other vendors and to stop a same-named board on another vendor from answering first.
API (replace the token):
https://api.apify.com/v2/acts/Pradio~greenhouse-lever-ashby-job/runs?token=YOUR_TOKEN
with body {"company":["ramp"],"maxItemsPerCompany":20}.
Input
| Input | Type | Default | Required | What it does |
|---|---|---|---|---|
company | list of strings | ["ramp"] | no | One entry per company: name, careers-page URL, slug, vendor:slug, or public board URL |
preset | choice | (none) | no | Add a bundled list: ai-startups (21 companies) or fintech (12 companies) |
maxItemsPerCompany | integer | 100 | no | Most posting rows per company; each board is capped on its own |
maxItems | integer | (none) | no | Overall cap across the run, on top of the per-company cap |
titleKeyword | string | (empty) | no | Keep postings whose title contains this text, case-insensitive |
keywords | list of strings | (empty) | no | Keep postings whose title contains any of these, case-insensitive |
departments | list of strings | (empty) | no | Keep postings whose department contains any of these, case-insensitive |
locationKeyword | string | (empty) | no | Keep postings whose location text, city, region, country or structured address contains this text |
remoteOnly | boolean | false | no | Keep only postings the vendor marks remote; an unclassified posting is dropped, not guessed |
postedWithinDays | integer | (none) | no | Keep postings published in the last N days; a posting with no date is dropped |
onlyNew | boolean | false | no | Skip postings an earlier run under your account already returned |
includeDescription | boolean | true | no | Read the per-posting description on Workable (one request per kept posting) |
With neither company nor preset, the run reads Ramp's board.
company
Accepted forms, one per entry:
- Company name:
Hugging Face,Scale AI. Turned into likely slugs and tried on every vendor. - Careers-page URL or domain:
https://careers.bunq.com,stripe.com. The domain's name is tried as a slug on every vendor; the page itself is not fetched. - Bare slug:
ramp, tried on Ashby, Greenhouse, Lever, Workable and Recruitee in that order until one answers. - Tagged:
ashby:ramp,greenhouse:stripe,lever:spotify,workable:nuvei,recruitee:bunq. Pin the vendor when two of them know the same slug. - Board URLs:
https://jobs.ashbyhq.com/ramp,https://boards.greenhouse.io/stripe,https://jobs.lever.co/spotify,https://apply.workable.com/nuvei/,https://bunq.recruitee.com/, and the vendors' API URLs for the same boards.
It does not accept applicant Data API URLs, Harvest tokens, or login cookies.
preset
A bundled list of companies, each board checked on its vendor's public feed on 2026-09-24 and confirmed to be the named company's. It adds to company; a board in both is read once.
ai-startups: OpenAI, Anthropic, Cohere, Perplexity, ElevenLabs, Harvey, Replit, Cursor, LangChain, Deepgram, Synthesia, Sierra, Modal, Character.AI, Writer, Pinecone, Scale AI, Together AI, AssemblyAI, Glean, Hugging Face.fintech: Stripe, Ramp, Plaid, Brex, Chime, Robinhood, Coinbase, Affirm, SoFi, Monzo, Gusto, bunq.
{"preset": "fintech","titleKeyword": "engineer"}
maxItemsPerCompany and maxItems
Each company keeps at most maxItemsPerCompany postings after the filters, so a board of 300 never starves the next one on the list. maxItems is an extra ceiling on the whole run; leave it empty unless you want one.
titleKeyword, keywords, departments, locationKeyword, remoteOnly, postedWithinDays
Substring matches, case-insensitive. titleKeyword is one text the title must contain. keywords is a list, and the title must contain at least one of them. When both are set a posting must pass both. departments keeps postings whose department contains any of its entries. locationKeyword reads the location text, the city, region and country, and the structured address. remoteOnly keeps only postings whose vendor marks them remote. postedWithinDays keeps postings whose stated posting date is within the last N days. A posting the board gives no department or no date for is dropped by that filter, not guessed. All of them run before any per-posting description is read, so filtered-out postings cost nothing.
{"company": ["greenhouse:anthropic"],"keywords": ["engineer", "research"],"departments": ["AI Research"],"postedWithinDays": 30}
onlyNew
Postings this Actor has returned under your account are remembered in a named key-value store, greenhouse-lever-ashby-job-seen, by posting URL. A posting is added only after it was actually returned, so a run cut short by a spend cap leaves the rest for next time. Delete that store to forget everything.
includeDescription
Ashby, Greenhouse, Lever and Recruitee include the description in the board response. Workable publishes it on a per-posting endpoint, one request per kept posting. Set this to false for a cheaper title-and-link run on Workable; its description is then null.
Output
- Posting rows carry
row_type: "ROW"and every field in the table above (a value the vendor does not publish isnull, never omitted). Duplicateofficial_urlvalues are dropped before charge. - An entry this Actor does not read (SmartRecruiters or Personio): one uncharged row with
row_type: "ITEM_STATUS",status: "vendor_not_read", theentryas you gave it and areason. The other entries in the run are read as usual. - An entry with no public board (a misspelt slug, or a company none of the five vendors hosts): one uncharged row with
row_type: "ITEM_STATUS",status: "no_board_found", theentryas you gave it and areasonnaming the vendors tried. The other entries in the run are read as usual. - Zero postings: one uncharged row with
row_type: "NO_MATCHING_LISTINGS"and areason. The dataset is never empty. ItsrowsReturnedcounts the entry notes written before it, 0 when there are none. - Spend cap: one uncharged
STOPPED_EARLYrow withrowsReturnedandrowsRemaining. - On both status rows
rowsReturnedis the number of rows written before that row, entry notes included: the same count RUN_SUMMARY callsrowsPushed. - RUN_SUMMARY in the default key-value store:
rowsFetched,rowsPushed,rowsCharged,duplicatesDropped,stoppedEarly, andskippedSeenwhenonlyNewis on.
An HTTP error, a JSON parse failure, or a 429 that still fails after retries fails the run. That is deliberate: a refused read is not an empty board.
What can you do with the data?
A researcher compiling every open engineering role across a list of portfolio companies passes their slugs in company with titleKeyword set to engineer. The export carries title, department, location, apply_url and pay where published.
A sourcer watching Stripe's Greenhouse board and Spotify's Lever board sets locationKeyword to London and onlyNew to true. Each week they get only the postings that appeared since the last run.
A pipeline that already stores company slugs maps each one to this Actor, writes rows into a warehouse, and joins on official_url or job_id as the stable posting key.
An agent asks for one company by name and reads rectangular fields instead of learning five vendor dialects.
Use Greenhouse Jobs Scraper with AI agents
claude mcp add --transport http apify "https://mcp.apify.com?tools=Pradio/greenhouse-lever-ashby-job"
Paste that line to give an MCP client this Actor as a tool (the tool name is the Store identity Pradio/greenhouse-lever-ashby-job).
Personal data
Each row describes a job posting, not a person. There are no name, email or phone columns. The one place a person can appear is description, which is the employer's own posting text, unchanged: some employers name a recruiter or the hiring manager there. The Actor never pulls those names out into columns of their own: no field extracts a person's name, email or phone from the description. Names that appear inside a description stay inside it, and there is no hiring_manager or recruiter_email column.
You decide what to do with the rows, so you are the controller of any personal data in them, and you need a lawful basis for keeping and using it (for example legitimate interest under the GDPR or the UK GDPR).
The rows are meant for job market research and for finding jobs: who is hiring, for what, where, and at what pay. Do not use them to build profiles of the people a posting names.
Every row carries platform, official_url and company_slug, so you can always say which public job board a posting came from.
If you run a job board, or you are named in a posting, and want it left out of future runs, open an issue on the Actor's Issues tab with the board or the posting URL. The board or posting goes on a removal list that every run reads before anything is fetched. A removed board returns one uncharged ITEM_STATUS row with status vendor_not_read and a reason saying it was removed on request.
The descriptions are the employers' own job adverts, reproduced for reference and linked to the original posting. Do not republish them as your own content, and do not use these rows to train AI models. Lever's site asks that its postings be used for reference only and not for AI training, and Workable's asks that they not be used for AI training.
Limits
- Public job-board feeds only. Ashby posting-api, Greenhouse boards-api, Lever postings, Workable's widget and v2 job endpoints, and Recruitee's public offers feed. No Harvest, no authenticated Data APIs, no apply POST, no shared ATS accounts, no HTML scrape of careers sites.
- Polite by each vendor's own rules. Lever rows are read at most one request per second, following the Crawl-delay line in Lever's robots.txt. A Recruitee board whose robots.txt disallows the offers feed is not read.
- Five vendors, named. SmartRecruiters and Personio are not read, and an entry naming either returns one uncharged row saying so. Workday, iCIMS and Taleo are not read: they have no logged-out job-board feed. A company whose board lives on one of those is tried on the five and found on none. That entry returns one uncharged
no_board_foundrow naming it rather than a guess, and when no other entry returned postings the run ends with the uncharged NO_MATCHING_LISTINGS row as well. - Finding a board by name is a best guess on the slug. A company whose board uses a slug unlike its name is not found that way. A different company with the same slug can answer first. Check
company_name, and tag the slug when it matters (see How to find a company's slug). - A list of company boards per run, not a search engine across every company on a vendor.
- No browser, no proxy. If a host refuses the GET, the run fails (with backoff on HTTP 429).
- Pay only when the posting publishes it. Greenhouse publishes a pay range only on boards that turn it on, and Workable publishes no pay fields. Otherwise their pay is read only from a range the posting text states next to a pay word and a currency. A posting without one carries null pay fields.
remoteOnlydrops the unclassified. Greenhouse has no remote flag, so a Greenhouse posting passesremoteOnlyonly when its location text says Remote.- Not affiliated with Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee, or any employer whose board you read. Re-read each vendor's public API docs and site terms before you rely on a high-volume schedule; stop if they object.
Adjacent Actors from the same publisher: Authentic Jobs Listings Scraper for that board's public listings feed, and Voice Over Jobs Monitor for voice-over castings. This Actor is only the five vendors' public job-board feeds.
Report problems on the Actor's Issues tab on Apify.
Troubleshooting
I got fewer rows than maxItemsPerCompany. The board had fewer postings after the filters, or Ashby skipped isListed: false items. That is the board running out, not a silent error. Check RUN_SUMMARY.rowsFetched.
I got one row and no jobs. Read row_type. NO_MATCHING_LISTINGS means every vendor tried for that slug answered and there were no postings, or none passed the filters, or onlyNew had already returned them all. That one row is the answer; it is not billed.
The run failed instead of returning empty titles. A 401/403/5xx or truncated JSON on any board fails the whole run, and nothing is written or billed: postings are written only once every board is read. Take the refusing board off your list and run again, or wait out a 429. Empty-looking success rows are not produced on a refused read.
A bare slug or a name found the wrong company. Two vendors can know the same slug. Check company_name, then pin it: greenhouse:your-slug, workable:your-account.
A company name found nothing. Its board uses a slug unlike its name. Follow How to find a company's slug and pass the tagged slug or a job's URL.
A SmartRecruiters entry returned one row and no jobs. SmartRecruiters is not read: its robots.txt allows only one named crawler. A smartrecruiters: entry or a SmartRecruiters URL returns one uncharged ITEM_STATUS row with status vendor_not_read, and the rest of the run goes on.
FAQ
Can I use integrations with Greenhouse Jobs Scraper?
Yes. Apify integrations can start this Actor and pass any of the inputs above. Chain it by storing the dataset and pointing the next Actor at that dataset URL.
Can I use Greenhouse Jobs Scraper with the Apify API?
Yes. Start runs against Pradio/greenhouse-lever-ashby-job (Pradio~greenhouse-lever-ashby-job in the path). The input JSON is the same as the Console. Dataset items and RUN_SUMMARY are the same records as a Console run.
Can I use Greenhouse Jobs Scraper through an MCP server?
Yes. Use the snippet in Use Greenhouse Jobs Scraper with AI agents so the client exposes this Actor as a tool.
Can I run it on a schedule?
Yes. In the Apify Console open Schedules, add one with a cron such as 0 7 * * * and pick this Actor with your input. Turn on onlyNew and each scheduled run returns only the postings it has not returned before; see Daily new jobs only above.
Is it legal to scrape the boards?
This Actor only GETs the vendors' public job-board / posting feeds (logged-out JSON), the same endpoints their own careers-page embeds read. It does not use Harvest or applicant APIs and it does not collect recruiter emails. You are responsible for each vendor's current public API rules and terms, for your jurisdiction, and for stopping if a host objects. This page is not legal advice. The Actor is not an official product of any vendor named here. See Personal data for how the rows may be used.
Release notes
0.1.24, 2026-09-25: on the zero-postings rowrowsReturnednow counts the uncharged entry notes written before it, asSTOPPED_EARLYalready did; it no longer reads 0 beside notes.0.1.16, 2026-09-25: SmartRecruiters boards are no longer read: its robots.txt allows only one named crawler. Asmartrecruiters:entry or a SmartRecruiters URL now returns one unchargedITEM_STATUSrow that names the entry and says why. Wise leaves thefintechpreset, which now lists 12 companies. Lever boards are read at most once a second, as Lever's robots.txt asks. Each Recruitee company's robots.txt is read first, and a board it disallows returns one uncharged row. Boards and postings can be removed from every run on request.0.1.15, 2026-09-24: Personio boards are removed pending a review of Personio's terms. Apersonio:entry or a Personio board URL now returns one unchargedITEM_STATUSrow that names the entry and says why; every other vendor is unchanged.0.1.14, 2026-09-24: Recruitee boards are read. Give a company name or careers-page URL instead of a slug, or apresetlist of AI or fintech companies. New columnscompany_name,seniority,salary_text,pay_interval,has_equity,city,regionandcountry; pay stated in the posting text is now read on Greenhouse, Workable and SmartRecruiters (SmartRecruiters stopped being read in 0.1.16). New filterskeywords,departmentsandpostedWithinDays.compensationandaddressare unchanged, and every earlier input still works;companyis no longer required.0.1.13, 2026-09-24:remoteOnlynow keeps remote postings only. Ashby marks hybrid roles as remote-allowed, and those came back before;is_remotenow follows the posting's workplace type.company_nameis renamedcompany_slug, which is what it holds.0.1.10, 2026-09-10: Ashby, Greenhouse, Lever, Workable and SmartRecruiters, a list of companies per run, title, location and remote filters, only-new, and a per-company cap.
Not affiliated
Greenhouse Jobs Scraper is an independent tool. It is not affiliated with, endorsed by, or maintained by Greenhouse Software, Lever (Employ Inc.), Ashby, Workable, SmartRecruiters, Recruitee, or any employer whose public job board you request. Job content belongs to the posting company.