Greenhouse Jobs Scraper: All 5 ATS Boards avatar

Greenhouse Jobs Scraper: All 5 ATS Boards

Pricing

from $0.20 / 1,000 job postings

Go to Apify Store
Greenhouse Jobs Scraper: All 5 ATS Boards

Greenhouse Jobs Scraper: All 5 ATS Boards

Scrape job postings from Greenhouse, Lever, Ashby, Workable and Recruitee boards into one row shape for a list of companies, at $0.45 per 1,000 ($0.20 on Gold) with the full description. Title, location, department, pay when published, apply link. Get only new jobs, and the ones that closed.

Pricing

from $0.20 / 1,000 job postings

Rating

0.0

(0)

Developer

Pradio Actors

Pradio Actors

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Share

What does Greenhouse Jobs Scraper do?

Greenhouse Jobs Scraper returns one row per posting from Greenhouse jobs boards. It covers Lever, Ashby, Workable and Recruitee boards the same way. Give it company names, careers-page URLs or slugs. It finds each board itself. Or start from a preset list. Every posting comes back in the same 36-field shape. Each row carries title, location, department and team. It also carries pay where published, the apply link and the full posting text. $0.45 per 1,000 postings. A board it cannot find or read costs nothing. Its row says why.

On a schedule it returns the postings new since your last run. It adds the ones that closed or changed. No login, no API key, no browser. The boards answer their own public feeds.

The prefilled input reads three companies on three different boards:

{
"company": [
"https://jobs.ashbyhq.com/ramp",
"https://boards.greenhouse.io/stripe",
"https://jobs.lever.co/spotify"
]
}

Who uses Greenhouse Jobs Scraper

WhoWhat they run it for
Recruiters and sourcersA target list's live postings, with apply links and published pay
Talent intelligence and job boardsEvery open role across a company list, in one shape for five vendors
Sales teams on hiring signalsWhich roles a watched company opens, where and at what pay
Agents and pipelinesCompany names in, the same columns out, whichever board answered

Features

  • Five boards, one shape. Workable postings land in the same rows as Greenhouse, Lever, Ashby and Recruitee.
  • Board found from a name. A company name or careers-page URL is tried on all five boards until one answers. A guessed board is kept only when the employer name it publishes agrees with your entry.
  • Preset company lists. AI startups (21), fintech (12), developer tools (16) and top tech (14), each checked on its vendor's feed.
  • Filters you set. Keep only the postings that publish pay. Or drop the roles and places you do not want by title, department, location, remote flag, date or type.
  • New and closed postings. A scheduled run can return only what appeared since your last run. It adds the postings that left the board or changed.
  • Pay read where published. The vendor's pay fields, or a range the posting text states next to a pay word, with on-target earnings flagged.
  • Postings by address. Paste posting page URLs and get one row each. The list filters do not apply to them.
  • Clean text beside the original. The posting as published, plus the same text as clean plain text on every vendor.
  • Optional English translation. Made inside the run by a bundled model, with no outside service. The posted text is never rewritten.

What you can count on

  • An entry it cannot answer still comes back as a row naming what you gave it and the reason.
  • A row is charged only after it is written to your dataset.
  • A run that finds nothing returns one row saying so, never an empty dataset.
  • A spending limit you set on the run stops it cleanly. A last row says how many rows came back and how many did not.
  • Every run saves a summary of what it read, returned and charged. A short run is easy to tell from a broken one.
  • A board that refuses a read or answers with an error is reported in the log. Its own row says so too. It is never returned as empty rows.
  • No value is invented. A field the board does not publish stays null. The tables below say which.

Why this one

This ActorMost-used alternative
Postings returned28510
Price per 1,000 postings$0.45$1.50

The most-used alternative on this platform, run on the same three-company input on 2026-10-11. This Actor's run stopped at its default 100-per-company cap on two of the three boards.

  • Workable boards in the same rows as Greenhouse, Lever, Ashby and Recruitee. None of this shelf's leading Actors reads Workable.
  • A published-pay filter and exclusion lists keep or drop the postings you choose. The leading Actors do not offer them.
  • A $0.00005 start charge a run, the smallest on this shelf. Start fees elsewhere run to $0.005.
  • The source on every row. Each posting carries its own URL and apply link. You can check any row against the live board.

What data does Greenhouse Jobs Scraper return?

The example run read three boards: Ramp on Ashby, Stripe on Greenhouse, Spotify on Lever. One of its postings, cut to the fields a buyer reads first:

{
"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",
"department": "Engineering",
"team": "Backend",
"description": "ABOUT RAMP\n\nRamp is building the smart infrastructure for finance teamsโ€ฆ",
"salary_minimum": 211400,
"salary_maximum": 290600,
"salary_currency": "USD",
"salary_text": "$211.4K - $290.6K",
"pay_interval": "year",
"has_equity": true,
"company_name": "Ramp",
"apply_url": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application",
"city": "New York City",
"employment_type": "full_time"
}

Fields on every posting row

Every value is the board's own. A field the board leaves out stays null. A few fields are derived instead, and they say so beside them. They are the company name from the slug, the level read from the title and the cleaned employment type. They also cover the split city, region and country, the remote flag on Greenhouse and the cleaned description text.

FieldWhat it carries
platformWhich board answered: ashby, greenhouse, lever, workable or recruitee
official_urlThe posting's public URL on the board
titleJob title as published
posted_dateWhen the posting was published
locationWorkplace text as published
is_remoteThe vendor's remote mark; Greenhouse infers it from the location wording
workplace_typeremote, hybrid or onsite as published; null on Greenhouse
descriptionThe full posting text, exactly as published
description_textThe same text as clean plain text
job_typeEmployment type in the vendor's own words
employment_typeCleaned: full_time, part_time, contract, intern or temporary
departmentIts department; on Ashby and Lever, the team when none is given
teamTeam inside the department; Ashby and Lever only
job_idThe vendor's own posting identifier
company_slugThe board slug that answered
company_nameEmployer's display name; the slug in title case on Ashby and Lever
addressThe vendor's structured location, unchanged
apply_urlWhere a person applies; falls back to the posting URL
seniorityThe level the title states, intern to c-level, else null
city, region, countryThe location split out; country as a two-letter code where it resolves
salary_minimum, salary_maximumPublished pay floor and ceiling in the posting's currency
salary_currencyISO currency code of the published pay
salary_textThe pay as the posting states it; may be on-target earnings
pay_intervalThe period the pay is stated for: year to hour
has_equityEquity in the published package; Ashby only
salary_is_oteTrue when the published pay says OTE or on-target earnings
compensationThe vendor's own pay object, unchanged
is_repostRepost mark when Flag reposted postings is on; null otherwise
sectionsParsed description sections when Split description into sections is on
translationEnglish translation when translateTo is en
translation_languageThe detected language of the posting text
translation_noteWhy translation is null, or its machine-translation label
row_typeROW on a posting; the status kinds are in the Output table
status, reason, subjectok on a posting row; on a status row, which note, why, and what it is about
rowsFetched, rowsReturned, rowsRemainingThe counts behind a status row

Which board fills which field

Counts from the example run (100 Ashby rows, 100 Greenhouse, 85 Lever):

Field groupAshbyGreenhouseLever
Core posting fields: title, URL, date, location, description, apply link, idsevery rowevery rowevery row
department, teamalldepartment onlyall
workplace_typeallnullall
job_type, employment_typeallnull79 / 78 of 85
is_remoteall9 of 100all
addressallnullnull
Pay columns (min, max, currency, text, interval, equity, OTE, raw object)97 of 100none on this boardnone on this board
city / region / country93 / 88 / 10058 / 10 / 1882 / 30 / 85
seniority32 of 100none on this board54 of 85

A lower number means that board published the value less often or not at all. Every row keeps the same shape either way. Workable and Recruitee were not on that input.

How much does it cost?

$0.45 per 1,000 postings ($0.00045 each), plus $0.00005 once a run to start it. The two charges:

ChargePriceWhen
listing-returned$0.00045One posting written to your dataset
apify-actor-start$0.00005Once per run
Postings writtenYou pay
100$0.045
1,000$0.45
10,000$4.50

On Apify's paid Store plans the posting price steps down. Bronze is $0.00035 per posting ($0.35 per 1,000). Silver is $0.0003 ($0.30). Gold, Platinum and Diamond are $0.0002 ($0.20). Status rows and dropped duplicates are free. A posting your filters drop is dropped before it is written. Platform compute is billed separately by Apify, the same as for any Actor.

How do I use Greenhouse Jobs Scraper?

  1. Open the Actor in the Apify Console and press Start. The prefilled input reads Ramp, Stripe and Spotify on three vendors.
  2. Replace the company list with yours: names, careers-page URLs, slugs or board URLs, one per line. Or pick a preset list, or paste posting page addresses.
  3. Set any filters you want. For a schedule, turn on Only new since my last run and Report closed postings.
  4. Press Start. Rows land in your dataset as they are read. The run's summary in the key-value store holds the totals.

Worked examples

Use it to get every open job at companies you know by name:

{
"company": ["Hugging Face", "Scale AI", "https://careers.bunq.com"],
"maxItemsPerCompany": 50
}

Use it to find engineering jobs at AI startups posted this week:

{
"preset": "ai-startups",
"keywords": ["engineer", "researcher", "scientist"],
"departments": ["engineering", "research"],
"postedWithinDays": 7,
"maxItemsPerCompany": 30
}

Use it to collect remote jobs from company boards:

{
"company": ["ramp", "greenhouse:stripe", "lever:zoox"],
"remoteOnly": true,
"maxItemsPerCompany": 100
}

Use it to track new fintech jobs every day:

{
"preset": "fintech",
"onlyNew": true,
"postedWithinDays": 2,
"maxItemsPerCompany": 100
}

Through the API, post the same JSON to https://api.apify.com/v2/acts/Pradio~greenhouse-lever-ashby-job/runs. Read the dataset back from the run.

Input

InputTypeDefaultWhat it does
companylist of stringsthree board URLsOne entry per company: name, careers-page URL, slug, vendor:slug or board URL
presetchoice(none)A bundled list: ai-startups, fintech, devtools or top-tech
postingUrlslist of stringsone Ramp postingPosting page addresses, one row each; the list filters do not apply
titleKeywordstring(none)Keep postings whose title contains this text
keywordslist of strings(none)Keep postings whose title contains any of these
excludeTitleKeywordslist of strings(none)Drop postings whose title contains any of these
searchDescriptionbooleanfalseAlso match those words in the posting text
departmentslist of strings(none)Keep postings whose department contains any of these
locationKeywordstring(none)Keep postings whose location contains this text
excludeLocationKeywordslist of strings(none)Drop postings whose location contains any of these
remoteOnlybooleanfalseKeep only postings the vendor marks remote
postedWithinDaysinteger(none)Keep postings published in the last N days
employmentTypeslist of choices(none)Keep these types: full_time, part_time, contract, intern, temporary
onlyWithPaybooleanfalseKeep only postings that publish pay
maxItemsPerCompanyinteger100Most posting rows per company; each board capped on its own
maxItemsinteger(none)An overall cap across the whole run
onlyNewbooleanfalseSkip postings an earlier run already returned
reportClosedbooleanfalseAdd rows for postings that closed or changed since the last run
memoryNamestring(empty)A schedule's own memory name; up to 20 letters, digits or hyphens
includeDescriptionbooleantrueOff is a cheaper title-and-link pass on Workable
detectRepostsbooleanfalseMark reposted postings from a board's second run on
structuredDescriptionbooleanfalseAdd sections parsed from the posting text
omitEmptyFieldsbooleanfalseDrop the fields a row carries null
translateTochoice(none)en adds an English translation made inside the run

company

One entry per company, in any of these forms:

  • A company name (Hugging Face, Scale AI): the likely slugs are tried on all five boards. A guessed board is kept only when the employer name it publishes agrees with your entry.
  • A careers-page URL or domain (careers.bunq.com, stripe.com): the domain's name is tried as a slug on every board. The page itself is not fetched.
  • A slug, bare or tagged (ramp, greenhouse:stripe): a bare slug tries each board in turn. vendor:slug pins the vendor when two boards share one. Find a slug in a job's address: jobs.ashbyhq.com/ramp gives ramp.
  • A board URL (jobs.ashbyhq.com/ramp, boards.greenhouse.io/stripe, jobs.lever.co/zoox, apply.workable.com/nuvei, bunq.recruitee.com): read directly.

An entry naming a vendor outside the five (a Personio or SmartRecruiters board) gets a status row. So does one pointing at a private hiring API. Neither is fetched.

postingUrls

One posting page address per entry, on the five hosts (jobs.ashbyhq.com, boards.greenhouse.io, jobs.lever.co, apply.workable.com, company.recruitee.com). Each returns the one posting it names, as listed. The list filters do not apply to it. Any other answer comes back as a status row. It says the board does not list that posting now. Or the address is no posting page it reads, or the vendor is not one of the five. Leave Companies and the preset empty to read only the postings you name.

The memory switches

Only new since my last run skips postings an earlier run already returned. Report closed postings watches each board's open postings. It adds a row when one leaves. It also adds a row when a posting's title, department, team, location, remote flag or apply link changes. Both keep their lists in a store under your account. The stores hold posting URLs and those watched fields, never pay or descriptions. Memory name gives each schedule its own pair. Delete the store to start over.

Output

A posting row carries every field above. A value the board leaves out stays null. A duplicate posting URL is dropped before it is written. A company no board answers still gets a row naming it and saying why. An empty dataset never stands in for the answer:

Every word in the status column says what happened to one entry, in one row that names it; row_type says whether the row is a posting (ROW) or a verdict (ITEM_STATUS), and reason says it in words. These are all the words the Actor can write โ€” no fourth value ships undocumented:

row_typestatusWhen it appears
ROWokA posting
ITEM_STATUSvendor_not_readA vendor it does not read, a removed board, a robots-disallowed feed
ITEM_STATUSread_refusedThe board refused the read; not retried that run
ITEM_STATUSno_board_foundNo vendor has a public board for the entry
ITEM_STATUSposting_closedA posting on the board's last run is no longer listed
ITEM_STATUSposting_changedA watched field on a listed posting moved
ITEM_STATUSno_postingsThe board was read and had nothing to return
ITEM_STATUSposting_not_foundA posting address whose board does not list it now
ITEM_STATUSbad_inputAn entry that is unusable; the row says why, and it costs nothing
ITEM_STATUSduplicateThe same board or posting as an entry above it; that entry's rows are the answer. This row names the repeat, costs nothing and spends no maxItems slot (the cap counts postings); on a run-ending row it counts among the rows pushed before that row, which is what rowsReturned means here
ITEM_STATUSnot_foundNo postings came back for this input; the reason names which (a board that refused, a vendor this Actor does not read, a board with nothing to return, a posting its board does not list) โ€” a refused read is named, never filed as a no
ITEM_STATUSnot_reachedAn entry the run stopped before reading; nothing was billed for it
NO_MATCHING_LISTINGSThe same run-ending row as not_found; the two words differ only in row_type
STOPPED_EARLYabortedYour spending limit ended the run; the counts and the entries it never returned ride on the row
STOPPED_EARLYerrorThe run stopped on a fault; the rows it already returned are kept, and this row names what failed
run entryRUN_SUMMARYEnd of every run, in your key-value store, with the totals

Zero postings is an answer, not silence. The row's reason says the board was empty, the filters dropped everything, or no board answered the entry. A refused read keeps the postings already collected. The run goes on to the next board.

What can you do with the data?

Watch hiring across a list. A recruiting lead schedules a weekly run over its target companies with Only new on. Monday's dataset holds the roles that appeared. Report closed postings shows which ones filled.

Feed a board or a market map. An aggregator sweeps a preset list and keeps the postings that publish pay. Title, pay, level and place are already columns whatever board answered. The rows go straight into a table.

Screen a niche. A sourcing lead mixes the filters. Remote only, posted in the last week, engineering departments, no intern titles. What is left is a short list with apply links and the full posting text.

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.

Personal data

  • Each row describes a job posting, not a person. No field pulls a name, email or phone out of the posting text. A name an employer wrote stays inside it.
  • Every posting row carries platform, official_url and apply_url where the vendor gives one. Each row links back to its source posting.
  • The posting text is the employer's own advert, unchanged. The optional translation is made inside the run by a bundled model. The text is never sent to an outside service, trained on or republished as a corpus.
  • The only-new and closed-postings memories hold posting URLs and watched posting fields. They live in a store under your own account. No applicant or person data is stored.
  • You are the controller for the rows you keep. Use them for reading and job-market research, with a lawful basis for keeping them.
  • To have a row corrected or removed, open an issue on the Actor's Issues tab. A board owner or a person named in a posting uses the same route. A listed board goes on a removal list every run reads first.

Release notes

  • 2026-10-11: postings by address (one row each). A repost flag, description sections, drop-empty-fields and an optional English translation made inside the run.
  • 2026-09-28: Report closed postings and changed-posting rows, the memory name switch, devtools and top-tech presets, the team column.
  • 2026-09-25: SmartRecruiters and Personio left unread (their rules do not allow the read). The five vendors above stay.

See also

Limits

  • Five vendors only. SmartRecruiters, Personio and Workday have no logged-out feed this Actor may read. An entry naming one gets a status row saying so.
  • A refused board is not retried. Not in the same run, and not under another identity or proxy. Its entry gets a status row naming it.
  • Pay is the employer's choice. On the example's Ashby board nearly every row carried it. The other two boards published none. Null is what the board answered.
  • Greenhouse publishes less. No employment type, no team, no workplace word. Its remote flag is inferred from the word Remote in the location.
  • Seniority only when the title says it. Most titles state no level. Those rows stay null rather than guess one.
  • A company name is a guess. Check company_name on the rows. Pin the vendor as vendor:slug when it matters.
  • Memory starts on the second run. The only-new and closed-postings switches need a first run to learn the board.
  • Filters need their field. Posted-within, department, location, remote and type filters drop a posting that has no value to test.
  • Workable is read per posting. Its description lives on a separate endpoint, one request per kept posting. With Include the full description off, you get a title-and-link pass.

Troubleshooting

Fewer rows than the board lists? The per-company cap (default 100) stopped it. Raise Max postings per company, or set Max postings in total for the run.

Zero rows? The one status row says which. The board was read and had nothing, your filters dropped everything, or no board answered your entry. An empty board is an answer, not a broken run.

The wrong company answered? Two vendors can share a slug. Check company_name on your rows. Pin the vendor: greenhouse:stripe instead of stripe.

A board refused the read? Its status row names it. The other boards still ran. A refusal is not retried in that run. Take the entry off the list or run again later.

FAQ

Can I run it on a schedule?

Yes. Add a schedule in the Apify Console. A cron such as 0 7 * * * works. With Only new since my last run on, each run returns what appeared since the last.

Do I need a proxy or an API key?

Neither. The boards answer a plain logged-out request over a direct connection. A board that refuses gets a status row naming it.

Can I use integrations with Greenhouse Jobs Scraper?

Yes. Apify's integrations (Slack, email, webhooks, Make and Zapier) fire on a finished run. They read the dataset, so a digest or a sheet update is wiring, not code.

Can I use it with the Apify API?

Yes. The API runs it. It returns the dataset as JSON, CSV, Excel or XML, the same as the Console.

Can I use it through an MCP server?

Yes. The one-line setup in the AI agents section adds it to a Claude or another MCP client as a tool.

How much does it cost to scrape job boards?

It is $0.00045 per posting written. On Gold plans and up it is $0.0002. Add $0.00005 once a run. Status rows and dropped duplicates are free.

What if a company has no open postings?

You get one row saying so. The board was read and had nothing, or nothing passed your filters. An empty dataset never stands in for the answer.

It reads the five boards' public logged-out feeds. It honours each host's robots rules. A block stops that board's read. Nothing goes around it. Having the right to read the boards you give it, and how you use the rows, is your responsibility. This page is not legal advice.

Can I export the results to Excel or CSV?

Yes. The dataset exports as JSON, CSV, Excel or XML from the run's Export button, or through the API. The same row schema applies in every format.

How many jobs can I scrape in one run?

Each company keeps up to 100 postings by default. Raise Max postings per company for bigger boards, or cap the whole run with Max postings in total. A company list can hold as many entries as you need.

How accurate is the data?

A row is what the board published when it was read, so the data is as fresh as the last run. When a vendor names its employer, the board must prove it is your company before its rows are kept. Check company_name on the rows to see who answered.

Feedback

Something broken, or a field you need? Open an issue on the Actor's Issues tab. We answer within two days. If this Actor saved you time, a review on its Store page helps other buyers find it.

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 or Recruitee. Nor by any employer whose public job board you read through it. Job postings belong to the companies that posted them.