Greenhouse, Lever, Ashby & Workday Jobs API — 8 ATS, $0.60/1K avatar

Greenhouse, Lever, Ashby & Workday Jobs API — 8 ATS, $0.60/1K

Pricing

from $0.60 / 1,000 results

Go to Apify Store
Greenhouse, Lever, Ashby & Workday Jobs API — 8 ATS, $0.60/1K

Greenhouse, Lever, Ashby & Workday Jobs API — 8 ATS, $0.60/1K

Job postings from 8 ATS — Greenhouse, Lever, Ashby, Workday, Eightfold, Workable, SmartRecruiters, Recruitee — in one schema. Salaries annualized across currencies and languages. Every run reports per-source health, so a broken ATS is visible instead of silently missing. No personal data.

Pricing

from $0.60 / 1,000 results

Rating

0.0

(0)

Developer

Juan Carlos Gutiérrez Huérfano

Juan Carlos Gutiérrez Huérfano

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

16 days ago

Last modified

Share

Job Postings Scraper — Greenhouse, Lever, Ashby, Workday, Eightfold, Workable, SmartRecruiters, Recruitee

Pulls open roles straight from companies' own applicant tracking systems and returns one clean schema across all eight, with salary bands parsed into comparable annual figures and an eligibility flag for Latin America.

No personal data is collected or emitted — job postings only.

Supported sources

ATSBoard URLBoard entry
Greenhouseboards.greenhouse.io/stripegreenhouse:stripe
Leverjobs.lever.co/leverdemolever:leverdemo
Ashbyjobs.ashbyhq.com/rampashby:ramp
Workableapply.workable.com/hospitableworkable:hospitable
SmartRecruitersjobs.smartrecruiters.com/Acmesmartrecruiters:Acme
Recruiteetether.recruitee.comrecruitee:tether
Workdaynvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSitepaste the URL
Eightfoldmercadolibre.eightfold.ai/careerseightfold:mercadolibre/mercadolibre.com

Why this exists

Every ATS already publishes its job board as a public JSON endpoint. The hard part was never fetching it; it's that each one names things differently, buries compensation in free prose, and describes location in a dozen incompatible ways. Existing scrapers hand you the raw payload and leave the normalization to you.

This one does the normalization:

  • Salary parsed and annualized. Structured fields when the ATS provides them, otherwise parsed from the description — English, Spanish and Portuguese, multi-currency, with annualizedMin/annualizedMax so an hourly US rate and a monthly Colombian salary sort in the same column. Every band carries the exact rawText it came from, and a confidence of structured or parsed, so you can audit or discard.

  • Work mode classified as remote / hybrid / onsite / unknown — reading the title and body, not just the location string. "Hybrid remote" resolves to hybrid, and a named city with no remote signal resolves to onsite; a bare country stays unknown rather than being guessed at.

  • LATAM eligibility flag. latamFriendly is true when the role sits in a Latin American country or is remote with a scope that includes the region — "Remote - LATAM", "Americas", "must overlap GMT-5", "work from anywhere". US-built job scrapers treat those strings as noise; if you hire in the region, that flag is the product.

    It is deliberately conservative. A role anchored to a non-LATAM country and not marked remote is never flagged, no matter what the description says — a US-based role whose body mentions "our business in the Americas" is a business-scope mention, not a hiring signal, and treating it as one would make the flag worthless.

  • Language detection (es / pt / en) on the posting body.

  • Delta feed. Pass postedAfter with your previous run's timestamp and get only what's new, instead of re-pulling every board in full.

Input

{
"boards": [
"greenhouse:stripe",
"lever:leverdemo",
"ashby:ramp",
"workable:hospitable",
"smartrecruiters:smartrecruiters",
"recruitee:tether"
],
"postedAfter": "2026-07-01T00:00:00Z",
"latamOnly": true,
"withSalaryOnly": false,
"workMode": ["remote"],
"titleIncludes": ["backend", "platform"],
"maxItems": 0,
"companyDomains": ["ramp.com"],
"descriptionMaxChars": 5000,
"failOnAnySourceError": false
}

The slug is whatever appears in the board's public URL — see the table above. Only boards is required; every filter is optional.

Set failOnAnySourceError to true when you would rather have a loud failure than a partial result — useful if you schedule this and act on the output automatically. It is off by default, because most callers would rather have five platforms of data than none.

You can paste the careers URL instead of a slug. Any of the eight boards is accepted as its public URL — https://boards.greenhouse.io/stripe works exactly like greenhouse:stripe. Workday is the reason this exists: its boards need three values (host, tenant and site) that only appear in the URL, and there is no public directory of Workday tenants to look them up in.

Or skip the board entirely and pass a company domain. If you do not know which ATS a company uses — and there is no reason you should — put the website in companyDomains and the Actor works it out:

{ "companyDomains": ["stripe.com", "ramp.com"] }

It probes the six guessable platforms and reports what answered, in the run log and in RUN_SUMMARY:

stripe.com uses greenhouse {"slug":"stripe","jobs":578}
ramp.com uses ashby {"slug":"ramp","jobs":137}
No public job board found for oldco.com {"probes":6}

Workday cannot be resolved this way, for the reason above. Paste its URL instead.

Output

One record per posting:

{
"id": "greenhouse:stripe:7967890",
"source": "greenhouse",
"companySlug": "stripe",
"companyName": "Stripe",
"title": "Consumer Operations Associate",
"url": "https://stripe.com/jobs/search?gh_jid=7967890",
"locationRaw": "Mexico City",
"countryCode": "MX",
"latamFriendly": true,
"workMode": "onsite",
"department": "Operations",
"employmentType": "Full-time",
"postedAt": "2026-07-22T15:16:54-04:00",
"updatedAt": "2026-07-27T11:17:30-04:00",
"salary": {
"min": 120000,
"max": 160000,
"currency": "USD",
"period": "year",
"annualizedMin": 120000,
"annualizedMax": 160000,
"rawText": "$120,000 - $160,000",
"confidence": "parsed"
},
"language": "en",
"description": "...",
"scrapedAt": "2026-07-31T18:00:00Z"
}

id is stable across runs, so you can upsert on it.

companyName comes straight from the ATS for Greenhouse, Workable, SmartRecruiters and Recruitee. Ashby, Lever, Workday and Eightfold do not expose an employer display name anywhere in their public JSON, so for those three it is derived from the board slug (nubank becomes Nubank). companySlug is always the raw ATS value and is the field to join on.

How often salary is filled depends on the market, not on the parser: US postings are usually covered by pay-transparency laws, most LATAM postings are not. On the public LATAM sample below, 6% of postings carry a salary. Use withSalaryOnly if you only want the ones that do.

A RUN_SUMMARY record is written to the key-value store with per-board failures, postings scanned vs emitted, and the filters applied — so a run that returns fewer rows than you expected tells you why.

Every run also writes a SOURCE_STATUS record: one entry per ATS platform, so you can tell a genuinely quiet week apart from a source that stopped answering.

{
"checkedAt": "2026-08-12T12:59:00Z",
"sources": [
{ "ats": "greenhouse", "status": "ok", "boards": 1, "boardsOk": 1,
"jobsFound": 412, "jobsEmitted": 412, "errors": [] },
{ "ats": "ashby", "status": "failed", "boards": 1, "boardsOk": 0,
"jobsFound": 0, "jobsEmitted": 0,
"errors": ["ashby:ramp: HTTP 404 (board not found)"] }
]
}

status is ok, partial (some boards answered, others did not) or failed. The run finishes with a status message like 6/6 ATS OK - 1301 postings, readable from the run list without opening anything.

Live public sample

A scheduled run of this Actor publishes a free, open sample every day, so you can check the exact output shape before paying for anything. It covers LATAM-eligible postings from a curated set of about 70 companies across Ashby, Greenhouse, Lever, Recruitee and Workable.

  • Postings: https://api.apify.com/v2/key-value-stores/crearcode~latam-tech-jobs/records/latest
  • Run metadata and per-source health: same URL ending in /records/meta

No token and no signup. It refreshes daily at 07:00 UTC.

Reliability

Six of the eight are documented public JSON endpoints with no authentication and no anti-bot layer, so there is nothing there that silently degrades when a site ships a redesign. Workday is the exception and worth stating plainly: it sits behind bot management, it pages 20 postings at a time whatever you ask for, it stops at 10,000 postings on the largest tenants, and it needs one extra request per posting to reach the description and the real posting date. Set maxItems when you point it at a company with thousands of openings. Requests retry three times with exponential backoff; a 404 is treated as a permanent "no such board" rather than retried. Boards are fetched five at a time — enough to be fast, not enough to be rude. One failing board does not sink the run; all boards failing does, loudly.

The sources are checked every day. A scheduled run hits one known-good board on each of the six platforms and alerts on any source that errors or returns nothing. If an ATS changes its API, that check fails before your run does.

A typical run across six boards reads well over a thousand postings in about ten seconds.

What this does not do

  • No personal data. No recruiter or hiring-manager names, no contact details, no applicant information. This is a deliberate design constraint, not an oversight.
  • No authenticated scraping and no credential sharing.
  • No aggregator sites. It reads each company's own board directly, which is why the data is first-hand and the uptime is the ATS's rather than a middleman's.
  • companyName is null on Lever. Lever's public postings API does not expose the company's display name, and inventing one from the slug would be a guess. The other five sources return it when the ATS publishes it.

Local development

npm install
npm run build
npm run test:local # offline assertions + live endpoint probe

test:local checks the salary parser and the location, work-mode and LATAM classifiers against fixtures without needing network — including a regression test for the "business in the Americas" false positive — then probes the six live endpoints and reports how many postings each returned.

Issues

Found a bad parse, or want a field in a different shape? Open an issue on the Actor. Include the board entry and the posting URL and it is usually a quick fix.