ATS Job Listings API Scraper avatar

ATS Job Listings API Scraper

Pricing

from $1.50 / 1,000 job records

Go to Apify Store
ATS Job Listings API Scraper

ATS Job Listings API Scraper

Query an index of 1,639 verified company job boards — 60,983 open roles across Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee and Workable — no company list, no login, no API key. Filter by title, location, remote and posting date: every remote senior backend role posted this week, in one run.

Pricing

from $1.50 / 1,000 job records

Rating

0.0

(0)

Developer

K O

K O

Maintained by Community

Actor stats

0

Bookmarked

5

Total users

4

Monthly active users

a day ago

Last modified

Share

Job Postings Aggregator — Six ATS Platforms, One Schema

No company list needed. Pick a verified company bundle - top tech, AI/ML, devtools, fintech, YC-backed or remote-first - and hit Start. Every company in a bundle was checked against its live board, so you never have to research a board slug to get a result.

Covers six ATS platforms in one feed — Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee and Workable — twice the board coverage of the nearest combo-ATS listing on the Store (which covers three: Greenhouse, Lever and Ashby). Filters run before you're charged: titleIncludes, locationIncludes and remoteOnly are applied inside the fetch loop, before any record reaches the dataset or a billable event, so you only pay for postings that actually match.

Pain points

  • Each ATS has its own API, its own field names, its own quirks — Lever hands you epoch milliseconds, Recruitee a non-standard timestamp, SmartRecruiters pages by offset and nests every value behind {label}. Wiring up even three or four of these yourself is real integration work.
  • Tracking a target-company list across more than one ATS means running several separate scrapers and merging their output into one schema yourself.
  • Filtering after the fact — pulling everything, then throwing away what you didn't want — means paying for records you never use.
  • Watching a list of companies for genuinely new roles across multiple platforms means storing what you already pulled, per platform, and diffing every run yourself.

What we solve

  • One schema, six ATS platforms. Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee and Workable all normalize to the same 12-field record — no per-platform integration work.
  • Filters run before billing. titleIncludes, locationIncludes and remoteOnly are checked inside the fetch loop, before a record is normalized, pushed, or charged — postings that don't match never cost you anything.
  • Per-source failure isolation. A source that fails (bad slug, unreachable API) is skipped with a logged warning — the rest of your source list still comes back.
  • Dedup built in, namespaced correctly. onlyNewSinceLastRun (default on) tracks the last 20,000 ids seen, keyed by ats:company:id — so the same numeric id from two different platforms, or two different companies, never collides or gets silently skipped.

Who uses it

Recruiters and sourcers tracking a list of target companies, niche and aggregator job boards, sales teams watching accounts for hiring signals, and labor-market/HR-tech products that need one consistent jobs schema instead of five or six different APIs.

Company bundles - no company list needed

You do not need to know a single board slug to run this. Pick a bundle in presetLists, hit Start, and you get live postings straight away.

BundleBoardsWhat it covers
top-tech83Large, well-known technology employers.
ai-ml75AI labs, ML infrastructure and applied-AI companies.
devtools65Developer tools, infrastructure, observability and security.
yc-backed62Y Combinator alumni, from recent batches to public companies.
fintech56Payments, banking, lending, crypto and financial infrastructure.
remote-first54Companies that hire remote-first or distributed by default.

Every slug in a bundle was checked against its live board on 2026-08-24 - a 200 response with at least one open role. Each bundle file carries its own verifiedAt date, and any board that stops answering is reported in the run's FAILED_TARGETS record instead of silently shrinking your results.

Bundles merge with anything you list yourself and are deduped, so you can start from a bundle and add your own companies to it.

Search every board we know - no company list at all

Turn on Search every board we know and you do not supply companies, slugs or bundles. The run queries our index of 1,639 verified boards - 60,983 open roles at the last check on 2026-08-24 - and applies your title, location and remote filters across all of them.

Ask it things a company list cannot answer:

  • every remote senior backend role posted this week
  • everything matching "machine learning" across every board in the index
  • new postings only, across the whole index, on a daily schedule
ATSBoards
greenhouse617
ashby615
lever224
workable66
smartrecruiters59
recruitee58

Every board in the index answered its ATS with at least one open role when the index was built. Boards are fetched most-active first and capped by Maximum boards to search (default 200), because each board is one request. The index is rebuilt on a refresh sweep; a board that stops answering three sweeps running is retired from it, and anything that fails during your run is reported in FAILED_TARGETS rather than silently shrinking your results.

Input

{
"presetLists": ["top-tech"],
"sources": ["greenhouse:stripe", "lever:ro", "ashby:Ramp"],
"titleIncludes": ["engineer"],
"locationIncludes": ["remote"],
"remoteOnly": false
}
FieldWhat it does
searchIndexNo company list at all. Query every board in the shipped index and apply your filters across all of them. See the section above.
maxBoardsOnly used with searchIndex. Each board is one request, so this caps run length. Boards are searched most-active first.
presetListsStart here if you have no company list. One or more verified company bundles; every board in them was checked against the live API. Merges with anything you list yourself, deduped.
sourcesList of "<ats>:<company>" entries. Supported ats: greenhouse, lever, ashby, smartrecruiters, recruitee, workable. The company is the slug from that ATS's careers URL. E.g. greenhouse:stripe, lever:ro, ashby:Ramp, workable:walter-careers.
maxPerCompanyStop after this many jobs from each board, so one large employer cannot fill the whole result. Recommended with bundles. Empty = no cap.
postedWithinDaysKeep only postings published in the last N days — 7 gives you this week's roles. Postings on boards that publish no date are left out, because they cannot be shown to be recent. Applied before billing.
titleIncludesKeep only jobs whose title contains one of these keywords (case-insensitive). Empty = all. Applied before billing.
locationIncludesKeep only jobs whose location contains one of these keywords. Empty = all. Applied before billing.
remoteOnlyKeep only remote-flagged roles (or locations mentioning remote). Applied before billing.
onlyNewSinceLastRunRecommended for schedules — skips jobs already returned by a previous run, so you're only charged for genuinely new postings. Default true.
maxItemsStop after this many normalized records.
includeSalaryFill the salary fields from whichever pay data each source ATS publishes. On by default; costs no extra requests.

Output

FieldDescription
jobIdThe posting's id in its source ATS.
atsWhich platform this came from: greenhouse, lever, ashby, smartrecruiters, recruitee, or workable.
companyThe company/account slug you queried.
titleJob title.
locationPrimary location, mapped from that ATS's own location shape.
departmentDepartment/team, mapped from that ATS's own tagging.
employmentTypeEmployment type, mapped from that ATS's own field.
remoteBoolean where the source ATS exposes one; null for ATSs (like Greenhouse) with no explicit remote flag.
postedAtPosting date, normalized to ISO 8601 regardless of the source's native format.
urlPublic posting URL.
applyUrlDirect apply-form URL, where the ATS separates it from the posting URL.
sourceAlways "Jobs Aggregator".
workplaceTypeThe source ATS's own workplace label, where it publishes one.
salaryMin / salaryMaxPay range as plain numbers, so you can sort and filter on it. null when the posting does not state pay — never a guess.
salaryCurrencyISO code (USD, EUR, GBP, …) where the posting makes it clear.
salaryIntervalYEAR, MONTH, WEEK, DAY or HOUR.
salaryTextThe pay exactly as the posting worded it, kept so you can audit the parse.
salarySourceats when the board published structured pay, ats-summary or description when it was read out of the posting text. null when no pay was found.
cityDerived / regionDerived / countryDerived / countryCodeDerivedThe location string split into parts, so "Austin, TX" is filterable by state and country instead of by substring.
locationTypeREMOTE, HYBRID or ONSITE.
seniorityLevelINTERN, JUNIOR, SENIOR, STAFF, PRINCIPAL, MANAGER, DIRECTOR, VP or EXECUTIVE, read from the title. null when the title carries no signal.
employmentTypeNormalizedFULL_TIME, PART_TIME, CONTRACT, INTERN, APPRENTICESHIP or VOLUNTEER — one enum across every ATS, so records are comparable.
daysSincePostedWhole days since the posting went live, precomputed.
organizationUrlThe public careers board this posting came from.

Pay coverage. Pay comes from whichever data each source publishes: structured for Ashby and Recruitee, parsed from the posting body for Greenhouse, Lever and SmartRecruiters. Measured 08/2026 across two Ashby and Lever boards: 174 of 186 postings.

This is a real record, captured live from an Ashby source on 08/21/2026 by running this actor's own client and field-mapping code — not a placeholder:

{
"jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"ats": "ashby",
"company": "Ramp",
"title": " Security Engineer, Cloud",
"location": "New York, NY (HQ)",
"department": "Engineering",
"employmentType": "FullTime",
"remote": true,
"postedAt": "2026-04-07T17:12:35.753+00:00",
"url": "https://jobs.ashbyhq.com/Ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"applyUrl": "https://jobs.ashbyhq.com/Ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application",
"source": "Jobs Aggregator",
"salaryMin": 211400,
"salaryMax": 290600,
"salaryCurrency": "USD",
"salaryInterval": "YEAR",
"salaryText": "$211.4K – $290.6K • Offers Equity",
"salarySource": "ats",
"cityDerived": "NY (HQ)",
"regionDerived": "NY",
"countryDerived": "United States",
"countryCodeDerived": "US",
"locationType": "HYBRID",
"seniorityLevel": null,
"employmentTypeNormalized": "FULL_TIME",
"daysSincePosted": 136,
"workplaceType": "Hybrid",
"organizationUrl": "https://jobs.ashbyhq.com/Ramp"
}

Note what's missing next to the source-specific record: no compensationSummary (Ashby), no departments/offices array or requisitionId (Greenhouse), no workplaceType/allLocations/country (Lever), no requirementsHtml/benefitsHtml/countries (Workable). The unified schema trades platform-specific depth for one consistent shape across all six sources — see Which actor do I want? below if you need that depth back.

Which actor do I want?

  • Tracking companies across more than one ATS, or don't want to run five separate scrapers? You're in the right place — this is the only actor in this family that covers all six platforms in one normalized feed.
  • Need Greenhouse's multi-department/multi-office tagging or its internal requisition id? Use Greenhouse Jobs Scraper.
  • Need Lever's remote/hybrid/onsite distinction, every location tag, or a country field? Use Lever Jobs Scraper.
  • Need Ashby's published salary/compensation data? Use Ashby Jobs Scraper — this aggregator fetches Ashby's compensation payload too but drops the field to keep its schema consistent across all six sources.
  • Need Workable's description/requirements/benefits split, or its deduplicated country array? Use Workable Jobs Scraper.
  • Want the free CRM/Notion/HubSpot/Airtable/Supabase sync feature? It currently ships on the four single-board actors above (syncEnabled input), not yet on this one.

Pricing (Pay-Per-Event)

  • query — charged once per run for the poll across your sources.
  • job-record — charged per normalized job pushed, after filtering. This is the primary event.
  • apify-actor-start (Apify-managed) — covers baseline compute per run.

A daily monitor of a target-account list with a title filter returns just the handful of relevant new roles for pennies — and the filtered-out postings were never billed in the first place.

Finding company slugs

ATSSlug is the part of the careers URL
Greenhousejob-boards.greenhouse.io/<slug>
Leverjobs.lever.co/<slug>
Ashbyjobs.ashbyhq.com/<slug>
SmartRecruitersjobs.smartrecruiters.com/<slug>
Recruitee<slug>.recruitee.com
Workableapply.workable.com/<slug>

Source & reliability

All six sources are public ATS job-board APIs — no API keys, no proxies. A source that fails (bad slug, unreachable API) is skipped with a logged warning; the rest of your source list still comes back. SmartRecruiters sources page through up to 1,000 postings per company per run (10 pages × 100); the other five ATSs return each company's full board in a single call. Run npm test for the offline self-test covering the source parser and every ATS's field mapping.

FAQ

How am I charged?

A flat query event once per run, plus one job-record event per normalized job actually pushed — after your titleIncludes/locationIncludes/remoteOnly filters are applied. Postings your filters exclude are never normalized, pushed, or charged. With onlyNewSinceLastRun on (the default), a posting already returned in a previous run (tracked by ats:company:id, for the most recent 20,000 seen) is skipped and not re-charged.

Where does the data come from?

Six public ATS job-board APIs — Greenhouse, Lever, Ashby, SmartRecruiters, Recruitee and Workable — the same data each platform's own hosted careers pages are built from. No API keys or proxies required.

How fresh is it?

Live at request time — there's no bundled or cached dataset behind this actor, it calls each source ATS directly on every run. Schedule it (daily or weekly) to keep catching new postings; onlyNewSinceLastRun means a recurring schedule only bills for roles you haven't seen yet.

Which actor do I want?

See Which actor do I want? above — short version: tracking multiple ATS platforms at once, stay here; need one platform's extra fields (salary, department/office arrays, workplace-type detail, or the description/requirements/benefits split), use that platform's single-board actor instead.


Need the rest of the record on these companies?

This actor returns one source. KYB Company Data Enrichment takes a company name and returns what the public record says about it across up to nine sources — state business registries, UCC lien filings, tax warrants and WARN layoff notices, the FMCSA motor-carrier census, the CMS NPI Registry, USAspending federal awards, EPA ECHO compliance, SEC EDGAR filings and CourtListener federal dockets.

Every enriched field carries its source and its match confidence. Only matches above the accept threshold are merged — anything weaker is surfaced as a suggestion and never folded into the record, because a false join is worse than returning nothing.


SEO keywords: jobs aggregator, multi ATS scraper, Greenhouse Lever Ashby scraper, job listings API, job postings API, new jobs feed, hiring signals, recruiting data, job board aggregator, ATS jobs feed