ATS Job Feed — Greenhouse, Lever & Ashby in one schema avatar

ATS Job Feed — Greenhouse, Lever & Ashby in one schema

Pricing

from $2.00 / 1,000 job postings

Go to Apify Store
ATS Job Feed — Greenhouse, Lever & Ashby in one schema

ATS Job Feed — Greenhouse, Lever & Ashby in one schema

Pull live job postings from Greenhouse, Lever and Ashby career boards and get them back in one normalized schema. Official public endpoints only — no browser, no proxy, no API key.

Pricing

from $2.00 / 1,000 job postings

Rating

0.0

(0)

Developer

tokyo cat

tokyo cat

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Pull live job postings straight from company career boards and get them back in one normalized schema, whichever applicant tracking system the company uses.

Most job scrapers cover a single ATS and hand you that vendor's raw JSON. If you aggregate postings from more than one, you end up writing the mapping layer yourself — categories.commitment on Lever, employmentType on Ashby, nothing at all on Greenhouse. This Actor does that mapping for you.

  • Three ATS platforms — Greenhouse, Lever, Ashby
  • Official public endpoints only — no browser, no proxy, no API key, no login
  • One schema — same 28 fields regardless of source
  • Filters run before billing — you are never charged for a posting a filter removes

What you get

Paste board URLs, get structured postings:

{
"ats": "ashby",
"company": "ramp",
"jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"title": "Security Engineer, Cloud",
"department": "Engineering",
"team": "Backend",
"employmentType": "Full-time",
"location": "New York, NY (HQ)",
"locations": ["New York, NY (HQ)", "Remote (Canada)", "Remote (US)", "Miami, FL"],
"isRemote": true,
"workplaceType": "Hybrid",
"country": "USA",
"publishedAt": "2026-04-07T17:12:35.753Z",
"jobUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-...",
"applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-.../application",
"salaryText": "$211.4K - $290.6K",
"salaryMin": 211400,
"salaryMax": 290600,
"salaryCurrency": "USD",
"descriptionHtml": "…",
"descriptionText": "…"
}

Every posting also carries companySlug, requisitionId, departments, updatedAt, language, sourceUrl and scrapedAt.

Timestamps are always ISO 8601 UTC. Missing values are null, never an empty string — so salaryMin === null means the company did not publish a range, not that parsing failed.

Field coverage by ATS

FieldGreenhouseLeverAshby
title, location, jobUrl, applyUrl
department
team
employmentType
isRemoteinferred from location
workplaceType
country
publishedAt
updatedAt
salaryMin / salaryMaxwhen publishedwhen published
descriptionHtml / descriptionText

Dashes mark data the platform does not expose publicly. Nothing is guessed.

Input

{
"boards": [
"https://job-boards.greenhouse.io/stripe",
"https://jobs.lever.co/palantir",
"ashby:ramp"
],
"titleKeywords": ["engineer"],
"titleExcludeKeywords": ["manager", "director"],
"remoteOnly": true,
"postedAfter": "2026-07-01",
"maxJobs": 500
}
OptionWhat it does
boardsBoard URLs or ats:slug pairs. Duplicates across forms are collapsed.
includeDescriptionFull posting body as HTML and text. Default true.
includeCompensationPosted salary ranges. Default true.
titleKeywords / titleExcludeKeywordsCase-insensitive title matching.
locationKeywordsMatch any of the posting's locations, e.g. Tokyo, Remote.
departmentKeywordsMatch department or team.
remoteOnlyKeep only postings the ATS flags remote.
postedAfterISO date. Postings without a publish date are kept.
maxJobsPerBoard / maxJobsHard caps on how much a run can charge.
concurrencyBoards fetched in parallel. Default 5.

Finding a board

The slug is the last part of the company's careers URL.

ATSCareers URLboards entry
Greenhousejob-boards.greenhouse.io/stripegreenhouse:stripe
Leverjobs.lever.co/palantirlever:palantir
Ashbyjobs.ashbyhq.com/rampashby:ramp

You can paste the URL itself — the ATS is detected automatically.

Pricing

You are charged per job posting saved to the dataset, plus the standard Actor start event.

Charging happens on the same call that writes the posting, so:

  • Filtered-out postings cost nothing.
  • A board that 404s or times out costs nothing.
  • If a run is aborted, you keep — and pay for — only what was already saved.

maxJobs and maxJobsPerBoard put a ceiling on any single run, and the Actor stops cleanly when it hits the maximum run cost you set in Apify Console.

Common uses

  • Job boards and aggregators — refresh listings from a roster of companies on a schedule.
  • Recruiting and talent research — track which teams a set of companies is hiring for, and when.
  • Compensation benchmarking — collect published salary bands across Ashby and Lever boards.
  • Hiring-signal lead generation — a company opening five sales roles is a company with budget.
  • AI agents and RAG pipelines — a stable, flat schema that needs no per-vendor mapping.

Notes and limits

  • Only publicly listed postings are returned. Confidential and internal-only roles are not exposed by these endpoints and are not accessible to this Actor.
  • No personal data is collected. Postings describe roles, not people.
  • Greenhouse returns the entire board in one request; large boards (500+ postings) come back in a few seconds. Lever is the slowest of the three.
  • Turning includeDescription off makes Greenhouse boards roughly 10x smaller. Lever and Ashby return descriptions either way.
  • Boards that cannot be read are recorded in the BOARD_ERRORS record in the run's key-value store, with the reason for each.

Development

npm install
npm test # unit tests, no network
apify run # end-to-end against live boards

Input for local runs goes in storage/key_value_stores/default/INPUT.json.