ATS Jobs Scraper – Greenhouse, Lever, Ashby & More
Pricing
from $1.48 / 1,000 item extracteds
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
Maintained by CommunityActor stats
0
Bookmarked
11
Total users
3
Monthly active users
5 days ago
Last modified
Categories
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:
- Remote Engineering Jobs Across ATS Boards
- Startup Hiring Monitor Across ATS Boards
- Mixed ATS Job Boards Sample
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,titleandjobUrltogether 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,companySlugandjobIddownstream. 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.
| Setting | JSON key | What to provide |
|---|---|---|
| Mixed ATS board URLs | startUrls | Supported public board URLs as { "url": "…" } objects. |
| Greenhouse board tokens or URLs | greenhouseBoards | Tokens such as airbnb or Greenhouse board URLs. |
| Lever company slugs or URLs | leverCompanies | Slugs such as spotify or Lever board URLs. |
| Ashby board slugs or URLs | ashbyBoards | Slugs such as openai or Ashby board URLs. |
| Recruitee company subdomains or URLs | recruiteeCompanies | Subdomains such as bunq or https://bunq.recruitee.com. |
| SmartRecruiters company identifiers or URLs | smartRecruitersCompanies | Identifiers such as SmartRecruiters or public company board URLs. |
| Personio company subdomains or URLs | personioCompanies | Subdomains such as egym or https://egym.jobs.personio.de. |
| Maximum jobs | maxItems | Total saved-job ceiling. Default 20, range 1–10,000. Not a completeness guarantee. |
| Include job descriptions | includeDescriptions | Default true. Turn off for listing-only runs. Descriptions can be missing even when requested. |
| Department or team filter | departmentFilter | Case-insensitive substring in department/team text. |
| Location filter | locationFilter | Case-insensitive substring in primary location text, not a normalized remote-work test. |
| Title/description keyword filter | keywordFilter | Case-insensitive substring in title and available description. With descriptions off, only titles are searched. |
| Safe run-time limit | runTimeSecs | Default 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"}
| Fields | Meaning |
|---|---|
source, companySlug, jobId | Source and board/job identifiers. Combine these when comparing snapshots. |
title, companyName | Job title and company name when exposed. Company name is not populated for every source. |
location, department, team | Published primary location and organizational labels. |
workplaceType, employmentType | Source-dependent workplace and employment labels, not universal classifications. |
compensation | Public compensation text when exposed. No guaranteed normalized salary range. |
jobUrl, applyUrl | Public posting and application destinations when available. |
description, descriptionHtml | Requested description text/HTML. HTML is omitted when descriptions are disabled. Optional detail failures preserve listing data. |
publishedAt, updatedAt, scrapedAt | Available source dates and the run's collection timestamp. |
sourceRawMetadata | Source 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 osfrom apify_client import ApifyClientclient = 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
- Claude and Claude Code (Anthropic): Apify setup guide.
- ChatGPT and Codex (OpenAI): Apify setup guides.
- Grok Bot (xAI): Apify plugin guide.
- Gemini CLI (Google): MCP server setup guide. Use the server URL below with the HTTP configuration supported by Gemini CLI.
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.
Related Actors
- 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. ♥