ATS Jobs Scraper – Greenhouse, Lever, Ashby & More avatar

ATS Jobs Scraper – Greenhouse, Lever, Ashby & More

Pricing

from $1.48 / 1,000 item extracteds

Go to Apify Store
ATS Jobs Scraper – Greenhouse, Lever, Ashby & More

ATS Jobs Scraper – Greenhouse, Lever, Ashby & More

Export public jobs from six ATS platforms with titles, locations, available descriptions, application links, filters, and source metadata in one dataset.

Pricing

from $1.48 / 1,000 item extracteds

Rating

0.0

(0)

Developer

Fetch Cat

Fetch Cat

Maintained by Community

Actor stats

0

Bookmarked

11

Total users

3

Monthly active users

5 days ago

Last modified

Share

Export public jobs from Greenhouse, Lever, Ashby, Recruitee, SmartRecruiters, and Personio into one normalized dataset. Supply employer board URLs or source-specific slugs, then download job titles, locations, descriptions, application links, and source metadata where available.

The Actor reads public boards without target-site login. You provide the companies. It does not discover employers, search job aggregators, or automatically track changes between runs.

Quick start

Start with one board and a small job limit:

{
"startUrls": [{ "url": "https://jobs.ashbyhq.com/openai" }],
"maxItems": 5,
"includeDescriptions": false
}

Run the Actor, open its dataset, and export JSON, CSV, Excel, or another Apify-supported format. A valid board address does not guarantee current vacancies. Source-dependent fields may be null or absent.

Prefer a video guide? This short Apify walkthrough shows you how to set up and run an Actor. It uses a different Actor, but the setup steps are the same.

Ready-to-run examples

Choose a public example to see its settings before starting a run:

What you get

One row per saved public job, with source and board identity, a job identifier and available title, location, team, posting links and description. Six sources are supported: Greenhouse, Lever, Ashby, Recruitee, SmartRecruiters and Personio. Optional source fields can be missing. Workday and LinkedIn are separate products, not additional input modes.

Who is it for?

  • Recruiting analysts reviewing advertised roles at a known list of employers.
  • Job-aggregation teams combining supported public employer boards into a consistent import format.
  • Workforce researchers comparing job snapshots in their own analysis tools.
  • Sales research teams using cited public job descriptions to review hiring themes.

How you can use the data

  • Build a mixed-board job sheet. Supply known public boards from the supported sources and a small total job cap. Keep source, companySlug, jobId, title and jobUrl together so each row remains traceable to its employer and posting.
  • Review a focused team or location. Apply department or location substring filters and inspect the returned text. A location match is not a normalized remote-work or applicant-eligibility classification, and candidate limits can exclude later matches.
  • Analyze available descriptions separately. Request descriptions when your own text-analysis workflow needs skills or responsibilities. Keep posting URLs as citations. Optional description failures can leave useful listing data.
  • Compare your own hiring snapshots. Join exports by source, companySlug and jobId downstream. The Actor does not classify skills, identify new or removed jobs, or generate hiring reports itself. Retrieve the datasets through the API or connect a run-finished webhook to your warehouse, spreadsheet or n8n workflow. Repeated execution must be configured separately.

Input settings

Board fields are alternatives and can also be combined. At least one recognized board is required at runtime. No single board field is globally required. Duplicate source/slug pairs are combined.

SettingJSON keyWhat to provide
Mixed ATS board URLsstartUrlsSupported public board URLs as { "url": "…" } objects.
Greenhouse board tokens or URLsgreenhouseBoardsTokens such as airbnb or Greenhouse board URLs.
Lever company slugs or URLsleverCompaniesSlugs such as spotify or Lever board URLs.
Ashby board slugs or URLsashbyBoardsSlugs such as openai or Ashby board URLs.
Recruitee company subdomains or URLsrecruiteeCompaniesSubdomains such as bunq or https://bunq.recruitee.com.
SmartRecruiters company identifiers or URLssmartRecruitersCompaniesIdentifiers such as SmartRecruiters or public company board URLs.
Personio company subdomains or URLspersonioCompaniesSubdomains such as egym or https://egym.jobs.personio.de.
Maximum jobsmaxItemsTotal saved-job ceiling. Default 20, range 1–10,000. Not a completeness guarantee.
Include job descriptionsincludeDescriptionsDefault true. Turn off for listing-only runs. Descriptions can be missing even when requested.
Department or team filterdepartmentFilterCase-insensitive substring in department/team text.
Location filterlocationFilterCase-insensitive substring in primary location text, not a normalized remote-work test.
Title/description keyword filterkeywordFilterCase-insensitive substring in title and available description. With descriptions off, only titles are searched.
Safe run-time limitrunTimeSecsDefault 270 seconds. Range 30–285. Stops starting new requests and preserves saved results.

Requests use direct public access. There is no connection selector or supported proxy input.

Limits, filtering, and continuation

Inputs accept up to 1,000 unique boards. Each run processes up to 100 boards within its time and request limits, distributing the remaining job allowance across requested boards. Results follow processing/source order, not a guaranteed newest-first or salary sort.

Filters apply to the listings fetched for each source. Some sources limit the fetched candidates before filtering, so a filtered run can miss matching roles later in a board. A low maxItems is not a complete board search.

When work remains, inspect RUN_SUMMARY.continuationInput and copy that complete object into a new run. It preserves filters, description and runtime settings, replaces the board list with pending boards, and reduces the job limit by the saved count. Reaching maxItems ends the requested workload. Continuation is not automatic and is not a cross-run new-jobs tracker.

Example inputs

Use the Quick start input as a small first run. Adjust the fields described above for your own data.

Output data

Each dataset row is a job posting. This illustrative shape is not an observed job:

{
"source": "lever",
"companySlug": "example-company",
"companyName": null,
"jobId": "example-id",
"title": "Example role",
"location": "Example location",
"department": null,
"team": null,
"workplaceType": null,
"employmentType": null,
"compensation": null,
"jobUrl": null,
"applyUrl": null,
"description": null,
"publishedAt": null,
"updatedAt": null,
"sourceRawMetadata": {},
"scrapedAt": "2026-10-24T00:00:00.000Z"
}
FieldsMeaning
source, companySlug, jobIdSource and board/job identifiers. Combine these when comparing snapshots.
title, companyNameJob title and company name when exposed. Company name is not populated for every source.
location, department, teamPublished primary location and organizational labels.
workplaceType, employmentTypeSource-dependent workplace and employment labels, not universal classifications.
compensationPublic compensation text when exposed. No guaranteed normalized salary range.
jobUrl, applyUrlPublic posting and application destinations when available.
description, descriptionHtmlRequested description text/HTML. HTML is omitted when descriptions are disabled. Optional detail failures preserve listing data.
publishedAt, updatedAt, scrapedAtAvailable source dates and the run's collection timestamp.
sourceRawMetadataSource extras such as offices, secondary locations, seniority, or Recruitee's original remote flag when supplied.

The dataset schema also retains optional remote, secondaryLocations, experienceLevel, compensationMin, compensationMax, compensationCurrency, and compensationInterval fields. Current extraction does not populate those top-level fields. Do not rely on them. Available source-specific values may instead appear in sourceRawMetadata or workplaceType.

Download your results

Open your run's dataset, choose Export and select JSON, CSV or Excel. JSON keeps nested fields together. CSV and Excel are useful when you want to review the records in a spreadsheet.

See Apify's download and export guide for the available formats and field options.

Pricing

This Actor uses pay-per-event pricing: start is charged after valid board input is confirmed, plus item for each saved job. Filtered-out jobs and failed requests do not create job-item events. Each continuation is a separate run.

Use a small maxItems, a focused company list and includeDescriptions: false when descriptions are unnecessary. Consult the live Pricing tab for current rates and account-specific terms, including applicable platform usage.

Tips for best results

  • Start with known employer boards. The Actor accepts supported public boards and does not discover companies for you.
  • Keep source and job identifiers in your export. Use them together when comparing snapshots in your own workflow.
  • Check filters against available source text. A filtered result is not a guarantee that every matching job on a board was examined.
  • Read the run summary before continuing. Copy its complete continuation input into a new run only when work remains, preserving filters and the remaining job allowance.
  • Request descriptions only when needed. Optional details can be missing even when requested.

Limits and caveats

Only the six listed public ATS sources are supported. There is no company discovery, applicant-data access, login-only recruiting data, Workday or LinkedIn input mode. Requests use direct public access, without a supported proxy selector.

Inputs accept up to 1,000 unique boards, while a run processes up to 100 within its time and request limits. Results follow processing and source order. Some sources limit fetched candidates before filtering, so low caps or filters can miss later matching jobs.

Continuation is manual. Copy the complete RUN_SUMMARY.continuationInput rather than assembling a new board list and forgetting its filters or remaining job allowance. It is not a cross-run new-job tracker.

Greenhouse listing responses of 404 or 410 are reported as unavailable, without claiming privacy or deletion. Those boards can complete successfully with no rows. Other upstream failures differ: if no jobs are saved, errors remain and there is no continuation, the run fails. Mixed batches can preserve useful records while reporting errors.

Public fields vary by source. An unavailable optional description leaves its listing intact. Reserved top-level remote and normalized-salary fields are not populated by current extraction. Use the actual returned source fields rather than assuming universal classifications.

Automation and integrations

Save your settings for next time

Once you have an input that works for you, save it as an Apify task. This keeps your settings together so you can use them again without filling in the form from scratch.

Run on a schedule

Need fresh results regularly? You can schedule the Actor or a saved task to run at a time that suits you.

Each scheduled run collects the data again. If you want to compare results or highlight changes, add that step in your own workflow.

Send results to your other tools

Use n8n, Make or Zapier to connect this scraper to the rest of your workflow. For example, you could pass its results to an AI assistant or add records to a spreadsheet. Follow the Apify integration guides for your chosen tool.

For a custom connection, an Apify webhook can notify your app when a run finishes or fails. Your app can then fetch the results or handle the failure.

API usage

Want to collect this data from your own app or automation? The examples below send input to the scraper and show how to collect its results.

The Node.js and Python examples wait for the run to finish before reading its results. The cURL example starts the run and returns its details. Wait for that run to finish, then use its defaultDatasetId to fetch the results.

For setup instructions, see Apify's JavaScript client guide, Python client guide and Actor runs API reference.

cURL

curl -X POST 'https://api.apify.com/v2/acts/fetch_cat~ats-jobs-scraper/runs' \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H 'Content-Type: application/json' \
--data @- <<'JSON'
{
"startUrls": [
{
"url": "https://jobs.ashbyhq.com/openai"
}
],
"maxItems": 5,
"includeDescriptions": false
}
JSON

Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/ats-jobs-scraper').call({
"startUrls": [
{
"url": "https://jobs.ashbyhq.com/openai"
}
],
"maxItems": 5,
"includeDescriptions": false
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('fetch_cat/ats-jobs-scraper').call(run_input={'startUrls': [{'url': 'https://jobs.ashbyhq.com/openai'}], 'maxItems': 5, 'includeDescriptions': False})
print(client.dataset(run['defaultDatasetId']).list_items().items)

API usage notes

The asynchronous API response identifies the run. Wait for completion, then retrieve its default dataset. Inspect the key-value store's RUN_SUMMARY for partial or empty results.

MCP and AI agents

You can ask your AI assistant to collect data with ATS Jobs Scraper – Greenhouse, Lever, Ashby & More and help you work with the results. The scraper returns the data, and your assistant can then summarize it, compare records or prepare notes.

Connect your assistant through the Apify MCP server. MCP gives your assistant a way to find this scraper, run it and read the results. Follow the official setup and sign-in guide for your app.

Easier setup with an Apify plugin

If you use a supported coding assistant, the official Apify plugin can set up the connection for you. It connects your assistant to Apify and includes instructions for common tasks. Follow the guide for your particular app.

Use Apify AI in Console

Prefer to keep everything in Apify? Open Apify AI in Console and ask it to find Fetch Cat's ATS Jobs Scraper – Greenhouse, Lever, Ashby & More. You can describe the data you want and ask questions about the results.

Apify AI is currently in beta. It asks for confirmation before starting an Actor, and normal run charges apply.

Choose your assistant

Connect just this scraper

To keep your setup focused on this scraper, add this server configuration to a compatible MCP client:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=fetch_cat/ats-jobs-scraper"
}
}
}

Sign in to Apify when your client asks. If your client uses a Bearer token instead, follow its setup guide and keep the token in its secure configuration. Configuration formats vary by app, so use the linked guide if your client needs a different format.

Use Apify's general server

Already connected to the general Apify MCP server at https://mcp.apify.com? You can use it to find this scraper without adding another server. Ask your assistant to use ATS Jobs Scraper – Greenhouse, Lever, Ashby & More by Fetch Cat, or give it the identifier fetch_cat/ats-jobs-scraper.

Your assistant can check the available settings and retrieve the results from the returned run. If the run is still working, it should follow that run rather than start it again. Both connection options use Apify's hosted service.

Example requests

  • “Use Fetch Cat’s ATS Jobs Scraper to collect up to 5 jobs across the public Greenhouse and Lever employer-board URLs I provide. Show source, employer slug, job ID, title, location and posting link.”
  • “Collect at most 5 jobs from this public Ashby employer board, filtering team text for engineering. Include available descriptions for a separate skills review, preserving posting links as citations.”
  • “Retrieve up to 5 jobs from these supported public employer boards with location text matching London. Keep source and job identifiers for comparison with my earlier export, and report incomplete boards without treating the sample as a complete hiring inventory.”

Normal Apify charges apply. Check the live Pricing tab before asking your assistant to run a larger batch.

Pay with x402

If your AI agent has a funded wallet, it can pay for Apify usage through x402. This experimental option lets an agent use Apify without a conventional account.

Apify AGI provides a prepaid API token with a spending cap after payment. Your agent can use that token to run this scraper through the Apify API or an authenticated MCP connection.

Some MCP setups also support paying for each request directly. That is a different payment option, so check the official guide for its availability.

Follow the official guide for wallet setup, supported payment options and current terms. Apify handles the payments. Keep wallet keys and payment tokens in your agent's secure configuration.

Other ways for agents to pay

Apify also supports MPP for prepaid access through AGI and Skyfire for eligible Actors. If your agent already uses one of these, see the agentic payment guide to choose the right setup.

FAQ

Why is a result empty or partial?

A board may have no matching jobs, may have moved, or may be temporarily inaccessible. RUN_SUMMARY records saved counts, errors, emptyBoards, pending boards, and budget stops. Its legacy alias RUN-SUMMARY remains available. Summary PARTIAL is a data-completeness indication, not necessarily a failed platform run.

Greenhouse listing responses of 404 or 410 are reported as unavailable, without claiming privacy or deletion. Those boards can complete successfully with no rows. Other upstream failures are not all treated the same: if no jobs are saved, errors remain, and there is no continuation, the run fails. Mixed batches can preserve useful records while reporting errors.

Why are descriptions or fields missing?

Public fields vary by source and employer. Ashby and SmartRecruiters may require additional public job-detail requests for descriptions. An unavailable optional detail leaves the listing intact. It does not guarantee a complete description. No applicant records or login-only recruiting data are supported.

Why did a filter miss a job?

Only fetched candidates are searched, and not every source applies filtering before its candidate limit. Description keywords cannot match text that was disabled or unavailable. Location matching uses text rather than inferred remote status. Increase the relevant allowance or narrow the boards, without assuming every current posting will be returned.

  • Greenhouse Jobs Scraper — Export openings from supplied public Greenhouse company boards, with available titles, locations, departments and application links.
  • Lever Jobs Scraper — Export public postings from supplied global Lever company boards, with available titles, locations, teams and descriptions.
  • Ashby Jobs Scraper — Export public Ashby company-board postings, with available job titles, teams, locations and compensation summaries.
  • SmartRecruiters Jobs Scraper — Export openings from supplied SmartRecruiters company boards, with titles, locations and published job URLs.
  • Workday Jobs Scraper — Workday boards, which this Actor does not support.

Support and feedback

For custom additions or integrations, email hello@fetchcat.dev.

Found an error or have a feature request? Open an issue with the run URL, a non-sensitive input example and what you expected.

Need help sharing it? See Apify’s guide to sharing a run when reporting an issue. Sharing a run can give the developer access to its input, logs and results, so use a run that contains no sensitive data. Please leave out API tokens, passwords, cookies, private documents and personal data. Use a public sample URL or a redacted example instead.

Tried this scraper? We'd love to hear how it worked for you. Leave a review to help others choose the right tool and help us improve it. Your feedback means a lot to us.

Made with care for curious people, AI agents and the possibilities in data. ♥