Multi-ATS Job Scraper & API avatar

Multi-ATS Job Scraper & API

Pricing

from $1.50 / 1,000 results

Go to Apify Store
Multi-ATS Job Scraper & API

Multi-ATS Job Scraper & API

Scrape Greenhouse, Ashby, and Lever job boards from one input, with a unified 22-field output schema. Filter by department, team, work model, employment type, and recency before storing. Built for job boards and AI agents.

Pricing

from $1.50 / 1,000 results

Rating

0.0

(0)

Developer

Damien Alleyne

Damien Alleyne

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

Apify Actor

Scrape Greenhouse, Ashby, and Lever job boards from a single input and get one normalized output. The ATS is auto-detected per URL, and department/team and recency filters are applied before anything is stored, so you only pay for the jobs you keep. No browser, no HTML parsing. Built for job boards, AI agents, and hiring research.

What can it do?

  • ✅ One actor for three ATS platforms (Greenhouse, Ashby, Lever), auto-detected per URL
  • One normalized record shape across all sources, tagged with an ats field
  • Filter by department/team before storing, so you only pay for relevant jobs
  • Recency filter (daysBack) for scheduled, incremental scraping
  • Limit results per board with maxJobs
  • ✅ Enhanced fields: salary, location arrays, remote/hybrid detection, applicant eligibility (Ashby)

Why one endpoint for all your ATS boards

Job boards and AI agents usually need coverage across several ATS platforms. Wiring up a separate scraper per platform means three input formats and three output shapes to reconcile. This actor takes mixed Greenhouse, Ashby, and Lever URLs in one run and returns a single normalized schema, with the same filter-before-store cost model on every source.

Supported ATS and filter conventions

Filter values are ATS-specific, because each platform identifies departments/teams differently:

ATSURL exampledepartmentsteams
Greenhousehttps://job-boards.greenhouse.io/{company}integer department IDs(not applicable)
Ashbyhttps://jobs.ashbyhq.com/{company}team/department UUIDsteam/department UUIDs
Leverhttps://jobs.lever.co/{company}plain names (case-insensitive)plain names (case-insensitive)

Leave a filter out to keep everything on that dimension. See the standalone actors below for how to find IDs/UUIDs per platform.

Pricing

Pay per event: $3.00 per 1,000 results, discounting down to $1.50 per 1,000 at higher Apify subscription tiers. You are only charged for jobs that survive your filters, not for everything the boards list.

Input

{
"urls": [
{ "url": "https://job-boards.greenhouse.io/automatticcareers", "departments": [307170], "maxJobs": 25 },
{ "url": "https://jobs.ashbyhq.com/zapier", "teams": ["cbb2c602-5494-4a7b-914c-8ad0a77fdc11"], "maxJobs": 25 },
{ "url": "https://jobs.lever.co/anchorage", "departments": ["Engineering"], "daysBack": 30 }
]
}

Parameters (per board)

  • url (required): a Greenhouse, Ashby, or Lever board URL (ATS auto-detected)
  • departments (optional): department filter (see conventions table for the value format)
  • teams (optional): team filter (Ashby UUIDs or Lever names)
  • maxJobs (optional): maximum jobs to store from this board
  • daysBack (optional): only store jobs published/updated/created in the last N days

Scheduled runs

Create a Schedule in Apify Console and set daysBack to match your cadence (7 for weekly, 4 for twice-weekly). Each run then only stores and charges for jobs new since your last window. Duplicates across overlapping windows can occur; dedupe on ats + id downstream.

Output

Every record has the same shape regardless of source:

{
"ats": "lever",
"company": "anchorage",
"id": "abc12345-...",
"title": "Senior Backend Engineer",
"type": "Full-time",
"department": "Engineering",
"team": "Blockchain",
"description": "<p>...</p>",
"descriptionPlain": "...",
"location": "Remote",
"locations": ["Remote", "Singapore"],
"workplaceType": "remote",
"isRemote": true,
"isHybrid": false,
"salary": { "min": 120000, "max": 160000, "currency": "USD", "interval": "per-year-salary" },
"compensationSummary": null,
"locationRequirements": null,
"country": "US",
"metadata": {},
"postingUrl": "https://jobs.lever.co/anchorage/abc12345-...",
"applyUrl": "https://jobs.lever.co/anchorage/abc12345-.../apply",
"publishedAt": "2026-05-07T01:08:03.000Z"
}

Field notes by source

  • salary is structured for Lever (when published) and regex-parsed from descriptions for Greenhouse/Lever. Ashby compensation appears in compensationSummary.
  • locationRequirements (country-level applicant eligibility) is populated for Ashby only.
  • workplaceType is native for Lever; isRemote/isHybrid are derived from location text for Greenhouse/Ashby.
  • team is null for Greenhouse (no team concept).
  • publishedAt maps to each platform's native date (Greenhouse updated_at, Ashby publishedDate, Lever createdAt), which is also what daysBack filters on.

Use it with AI agents

Callable through the Apify MCP server. Connect your agent (Claude, or any MCP-compatible framework) and it can scrape any mix of Greenhouse, Ashby, and Lever boards through one tool with a single, predictable output schema.

How it works

  1. Detects the ATS for each URL (Greenhouse / Ashby / Lever).
  2. Dispatches to that platform's scraper, applying department/team, daysBack, and maxJobs filters before storing.
  3. Maps every result to one unified record shape, tagged with ats.
  4. Pushes results to the dataset.

Need just one ATS? These are the standalone actors this aggregator is built from:

Author

Built by Damien Alleyne