ATS Job Scraper API: Workday, Greenhouse, Lever, Ashby & Oracle avatar

ATS Job Scraper API: Workday, Greenhouse, Lever, Ashby & Oracle

Pricing

from $1.20 / 1,000 jobs

Go to Apify Store
ATS Job Scraper API: Workday, Greenhouse, Lever, Ashby & Oracle

ATS Job Scraper API: Workday, Greenhouse, Lever, Ashby & Oracle

Scrape open jobs from Workday, Greenhouse, Lever, Ashby and Oracle career sites by company name or URL, or search 14,100+ verified job boards by title, location, remote and minimum salary. One schema, salaries where published, new/closed job feed, no login. $1.50 per 1,000 jobs.

Pricing

from $1.20 / 1,000 jobs

Rating

0.0

(0)

Developer

HireWatch

HireWatch

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Security

Limited permissions

Share

ATS Jobs Scraper API: Workday, Greenhouse, Lever, Ashby & Oracle + Job Search

Get every open job from company career sites built on Workday, Greenhouse, Lever, Ashby and Oracle Recruiting Cloud in one clean, consistent JSON format, with no login and no API key. Type company names (e.g. NVIDIA, Stripe), career-site URLs or domains, or search all 14,152 verified job boards at once by job title, location, remote and minimum salary. You get salary ranges where companies publish them, and every run labels jobs new / unchanged / closed, so a daily schedule becomes a new-jobs feed plus an optional per-company hiring-signal summary. Works from the Apify API and from AI agents through MCP.

Independent tool: not affiliated with or endorsed by Workday, Oracle, Greenhouse, Lever or Ashby. Names are used only to describe compatibility.

Supported applicant-tracking systems (ATS):

Career-site platformWhat you pasteExample
Workdaythe career-site URL or the company name (5,027 sites in the directory)https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite or NVIDIA
Oracle Recruiting Cloudthe Candidate Experience URLhttps://jpmc.fa.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1001/jobs
Greenhouseboard URL or just the company namehttps://boards.greenhouse.io/stripe or Stripe
Leverboard URL or just the company namehttps://jobs.lever.co/palantir or Palantir
Ashbyboard URL or just the company namehttps://jobs.ashbyhq.com/ramp or Ramp

Want a specific display name? Write Name | URL, e.g. JPMorgan Chase | https://jpmc.fa.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1001/jobs.

You can also paste a company's own careers page (e.g. https://acme.com/careers) or just its domain (e.g. figma.com). The Actor looks for an embedded or linked board from the list above and uses it.

Two ways to use it

  1. Name the companies. Type company names, website domains or job-board URLs, and get every open job at those companies.
  2. Search all companies. Turn on searchAllCompanies and the Actor searches a built-in directory of 14,152 verified job boards (5,027 Workday, 4,806 Greenhouse, 1,528 Lever, 2,791 Ashby), biggest employers first, with your filters: title keywords, location, remote only, posted date and minimum salary. It works like a live job search API across company career sites. There's no cached database: every board is read at run time, so closed jobs never show up.
{
"searchAllCompanies": true,
"titleKeywords": ["data analyst", "analytics"],
"locationKeywords": ["Remote", "United States"],
"minSalary": 100000,
"salaryCurrency": "USD",
"postedWithinDays": 14,
"maxItems": 200
}
  • maxCompanies sets how many boards are searched (default 100, about 1–3 minutes). Raise it for wider coverage.
  • Search-all runs stop at maxItems matching jobs (500 if you leave it at 0) and output job rows only, without company summaries.
  • On Workday sites the Actor uses Workday's own keyword search with your title keywords and reads at most 100 jobs per site, so a search stays fast.
  • Every board in the directory was checked live against its public jobs API on 2026-10-20 and had at least one open job. Boards that close later are skipped and listed in RUN_REPORT, so they never fail the run.
  • For a daily new-jobs feed, schedule a search with "outputMode": "changesOnly". After the first run, each run returns only jobs that are new (or closed) since the previous one.

How to scrape ATS jobs from Workday, Greenhouse, Lever, Ashby and Oracle

  1. Click Try for free (or Start) on this page. Apify's free plan includes monthly credit, so a first test costs nothing.
  2. In Companies, type company names, domains or careers-page URLs, e.g. NVIDIA and Stripe. Or leave it empty and turn on Search all companies.
  3. Optional: add title keywords, location keywords, remote only, posted within N days or a minimum salary.
  4. Click Start. Small runs finish in seconds; a whole large company takes a few minutes.
  5. Download the jobs as JSON, CSV, Excel or HTML, or read them through the API. Add a schedule to get new jobs every day.

What you can use it for

  • Sales & recruiting signals. A company that opens 40 new engineering roles this week is buying tools and services. Schedule a daily run and get only the changes.
  • Market and competitor research. See open headcount by department and location, the remote/hybrid mix, and how fast a company is hiring.
  • Job boards and aggregators. Pull complete, de-duplicated listings straight from the source, with salary ranges where the company publishes them.
  • Investors and analysts. Hiring velocity (new minus closed jobs) is a leading indicator of growth or cutbacks.

Why this Actor

  • One schema for five platforms. Title, department, location(s), country, remote/hybrid/onsite, employment type, posted date, salary, job URL and apply URL.
  • New / closed tracking built in. Each run labels jobs new, unchanged or closed (state is kept in a named key-value store). Use Only changes mode for cheap daily monitoring.
  • Gets more than 2,000 jobs from big Workday sites. Workday's own listing stops at 2,000 results. The Actor splits the listing by job family (or another filter) to collect all of them.
  • Company hiring-signal summary. One optional row per company: open jobs, new and closed since the last run, net change and trend, jobs posted in the last 7 and 30 days, top departments and locations, and remote mix.
  • Polite and reliable. It uses only the public job-listing data that each career page itself loads in your browser. There are no logins and no browser automation. It respects robots.txt and keeps at least 1 second between requests to a site. It retries timeouts, 429 and 5xx responses with exponential back-off and honours Retry-After.
  • Clear errors. Stale or wrong URLs, unknown company names, unsupported pages and sites that disallow crawling are reported per company in the run's RUN_REPORT and status message. One bad input never fails the whole run.

Input examples

All jobs at a few companies (first run):

{
"targets": [
"https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
"https://jpmc.fa.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1001/jobs",
"Stripe",
"Palantir",
"https://jobs.ashbyhq.com/ramp"
],
"maxJobsPerCompany": 0,
"includeCompanySummary": true
}

Daily change feed for engineering roles (schedule this daily):

{
"targets": ["Stripe", "OpenAI", "https://intel.wd1.myworkdayjobs.com/External"],
"maxJobsPerCompany": 0,
"outputMode": "changesOnly",
"titleKeywords": ["engineer", "developer"],
"trackerId": "eng-daily"
}

Hiring signals only (cheapest: one row per company, no job rows):

{
"targets": ["Stripe", "Palantir", "Ramp"],
"includeJobs": false,
"includeCompanySummary": true,
"maxJobsPerCompany": 0
}

Remote jobs with full descriptions:

{ "targets": ["Ramp"], "remoteOnly": true, "includeDescriptions": true }

Fresh roles only, with a hard cap on rows (and cost):

{
"targets": ["Stripe", "Databricks", "https://intel.wd1.myworkdayjobs.com/External"],
"titleKeywords": ["engineer"],
"postedWithinDays": 7,
"maxItems": 200
}

postedWithinDays keeps only jobs posted in the last N days, and jobs without a posted date are left out. maxItems stops the run after that many job rows across all companies.

Output

Job record (real example, trimmed of empty fields)

{
"recordType": "job",
"platform": "ashby",
"companySlug": "ramp",
"companyName": "Ramp",
"jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"globalId": "ashby:ramp:34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"title": "Security Engineer, Cloud",
"department": "Engineering",
"team": "Backend",
"employmentType": "full_time",
"remoteType": "hybrid",
"location": "New York, NY (HQ)",
"locations": ["New York, NY (HQ)", "Remote (Canada)", "Remote (US)", "Miami, FL"],
"country": "USA",
"postedAt": "2026-04-07T17:12:35Z",
"salaryText": "$211.4K – $290.6K • Offers Equity",
"salaryMin": 211400,
"salaryMax": 290600,
"salaryCurrency": "USD",
"salaryInterval": "year",
"url": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"applyUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application",
"changeStatus": "new",
"firstSeenAt": "2026-10-08T03:07:59Z",
"closedAt": null,
"scrapedAt": "2026-10-08T03:07:59Z"
}

Every record has the same fields (missing values are null), including careerSite, requisitionId, legalEntity (Workday hiring entity, with descriptions on), postedAtText, descriptionText and descriptionHtml.

companyName is the name the platform publishes (Greenhouse), the name you searched for, or the label you gave with Name | URL. Otherwise it is the board's slug (e.g. capitalone). changeStatus is new (first time seen; on the very first run every job is new), unchanged, or closed (gone since the previous run, with closedAt set). globalId is stable across runs, so use it as your primary key. When a site's own job count is off by a few (common on Oracle, or when jobs change while the list is being read), a missing job is reported closed only after it has been missing for two runs in a row.

Company summary record (recordType: "company_summary")

totalOpenJobs, jobsRetrieved, jobsMatchingFilters, newSinceLastRun, closedSinceLastRun, netChange, trend (growing / stable / shrinking), postedLast7Days, postedLast30Days, newestPostedAt, topDepartments, topLocations, remoteTypeCounts, employmentTypeCounts, newJobTitlesSample, closedJobTitlesSample, warnings.

Company summaries are also saved as one JSON record, COMPANY_SUMMARIES, in the run's key-value store. The dataset has three views: Jobs, Company hiring signals, and Jobs with descriptions. A per-company run report (status, counts and error message for each input) is saved as RUN_REPORT in the run's key-value store.

Per-input statuses in RUN_REPORT

ok, not_found (the board or career site does not exist; often a stale URL), robots_disallowed (the site asks crawlers not to fetch that page, so it was skipped), unsupported (no supported job board found), duplicate, error (network or site problem after retries), skipped_charge_limit.

Pricing (pay per event)

  • $1.50 per 1,000 job records on the Free plan, $1.40 on Bronze, $1.30 on Silver and $1.20 on Gold and higher Apify plans (per job, including jobs labelled closed)
  • $0.01 per company summary

You pay only for results. Examples:

  • 10 companies, about 5,000 open jobs with summaries: ≈ $7.60
  • Daily changes-only monitoring of 50 companies (about 300 changed jobs a day plus 50 summaries): ≈ $0.95 per day
  • Summaries only for 100 companies: $1.00 per run

Set Maximum cost per run in the run options to cap spending. The Actor stops cleanly when the cap is reached and says so in the status message. Companies whose jobs could not all be delivered keep their previous tracking state, so no change is lost; it is delivered on the next run.

Tips & limits

  • Workday names come from the built-in directory of 5,027 verified Workday sites. If a Workday company isn't found, or for Oracle (always), open the company's "Search jobs" page and copy the URL from your browser.
  • Company-name lookups use the built-in directory first (all four platforms), then check Greenhouse, Lever and Ashby with a few spellings (e.g. Scale AI → scaleai, scale-ai) and pick the board with the most jobs. If the result isn't the board you meant, pass the URL instead.
  • Closed jobs are only reported when the whole board was fetched in both runs. Use maxJobsPerCompany: 0 when you track changes.
  • Speed: in our tests, 11 companies with about 18,900 open jobs took about 2.5 minutes. Listings are fast (about 20 jobs per request on Workday, 200 on Oracle, and the whole board in one request on Greenhouse/Lever/Ashby). Full descriptions on Workday and Oracle need one extra request per job at about 1 per second per site. Use them on filtered or smaller sets.
  • Remote type on Workday is only known when descriptions are fetched. Oracle often leaves the workplace type blank.
  • Posted dates on Workday are approximate when descriptions are off (the listing says "Posted 3 Days Ago"; postedAtText keeps the original text).
  • Salaries come from the board's published pay ranges (Greenhouse pay transparency, Ashby compensation). salaryText keeps the original wording.
  • EU-hosted Greenhouse boards (job-boards.eu.greenhouse.io) are not supported yet.
  • Contact details are never collected. Recruiter and hiring-manager fields are ignored, and e-mail addresses and phone numbers inside descriptions are masked.

Use with AI agents / MCP

This Actor is built to be called by AI agents (Grok Bot, Claude, ChatGPT, Cursor, LangChain and others) through the Apify MCP server or the Apify API.

  • Add only this tool: https://mcp.apify.com?tools=hirewatch/career-sites-jobs-tracker. You can also let your agent find it through search-actors.
  • Keep calls small so they finish fast. The MCP call-actor tool waits up to 45 seconds, so set maxItems (e.g. 50) and maxJobsPerCompany (e.g. 100), and leave includeDescriptions off unless you need the text. Cap spend with maxTotalChargeUsd in callOptions.
  • Read results with get-dataset-items using the run's datasetId. Each row has recordType: job rows share one flat schema, and company_summary rows hold the hiring signals. Per-company errors are in the RUN_REPORT key-value record, so one bad input never fails the whole run.
  • Pay without an Apify account. The Actor uses pay-per-event pricing with limited permissions, so agents can pay per run with agentic payments (x402 / MPP prepaid tokens or Skyfire).

Job search across many companies (no company names needed; maxCompanies: 20 keeps it to roughly 30 seconds, inside the MCP 45-second wait):

{"searchAllCompanies": true, "titleKeywords": ["data engineer"], "remoteOnly": true, "maxCompanies": 20, "maxItems": 50}

Minimal agent call for named companies:

{
"targets": [
"Stripe",
"https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
],
"titleKeywords": [
"engineer"
],
"maxJobsPerCompany": 100,
"maxItems": 50,
"includeCompanySummary": false
}

Other HireWatch jobs Actors

ActorBest for
Workday Jobs ScraperWorkday career sites (*.myworkdayjobs.com) by company name or URL, including sites with more than 2,000 jobs
Greenhouse Jobs ScraperGreenhouse boards by company name or domain, with published salary ranges
Lever Jobs ScraperLever boards (jobs.lever.co) by company name or domain, with salaries and remote/hybrid type
Ashby Jobs ScraperAshby boards (jobs.ashbyhq.com), popular with startups and AI companies, with salary ranges
Workday, Greenhouse, Lever, Ashby & Oracle Jobs ScraperMixed lists across all five platforms in one run and one schema, plus job search across all of them
Website Tech Stack Detector + DMARC/SPF CheckerFind out what the hiring companies' websites are built with

All of them use the same output schema and the same new/closed tracking, so you can combine their datasets.

How much does it cost to scrape ATS jobs?

You pay only for job records in your dataset. There is no monthly fee and no charge for jobs your filters remove.

Job recordsFree plan ($1.50 / 1,000)Gold+ plans ($1.20 / 1,000)Typical use
100$0.15$0.12a quick check of one company
1,000$1.50$1.20every job at a few mid-size companies
10,000$15.00$12.00a weekly market-wide search
100,000$150.00$120.00a large job board backfill

Optional company summaries cost $0.01 each. Set Maximum cost per run in the run options (or maxItems) and the run stops cleanly at your budget.

Integrations and API

Run it from your own code, a no-code tool or a schedule:

  • Schedules: run daily or hourly from the Schedules tab, with "outputMode": "changesOnly" for a new-jobs feed.
  • No-code: Make, Zapier, n8n, Google Sheets, Slack, Airbyte and webhooks are available under Integrations.
  • Export: JSON, CSV, Excel, XML, RSS or HTML from the dataset, or stream rows through the API.
  • AI agents: use it as an MCP tool (see below).

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("hirewatch/career-sites-jobs-tracker").call(run_input={"targets": ["NVIDIA", "Stripe"], "maxItems": 100})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
print(job["title"], job["location"], job["url"])

JavaScript / Node.js (npm install apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('hirewatch/career-sites-jobs-tracker').call({ targets: ['NVIDIA', 'Stripe'], maxItems: 100 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

cURL (runs the Actor and returns the jobs in one request):

curl -X POST "https://api.apify.com/v2/acts/hirewatch~career-sites-jobs-tracker/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"targets": ["NVIDIA"], "maxItems": 50}'

FAQ

How do I get all open jobs at a company? Put its name in targets, e.g. ["NVIDIA", "Stripe"], and set maxJobsPerCompany to 0. A careers-page URL or the company's website domain works too.

Can I search jobs without knowing the companies? Yes. Turn on searchAllCompanies and add title keywords, a location or a minimum salary. This Actor searches the built-in directory of verified boards.

Do I need a login, cookies or an API key for the job site? No. Only public job postings are read, the same data the company's careers page shows to every visitor.

Can I get only new jobs every day? Yes. Schedule the Actor with "outputMode": "changesOnly". Each run then returns jobs that are new or closed since the previous run.

Can I filter by salary? Yes. minSalary (yearly; hourly and monthly pay is converted, full time), salaryCurrency and onlyWithSalary keep only jobs that publish pay.

How do I use it from code or an AI agent? Call hirewatch/career-sites-jobs-tracker through the Apify API with the JSON input shown above or the Apify MCP server. See the AI agents section above.

Is there an official Workday, Greenhouse, Lever or Ashby jobs API? Each platform has its own public job-board feed, every one works differently, and finding the right board for a company is the hard part. This Actor finds the board from a company name, reads it, and returns one clean schema with salaries, filters and new/closed tracking.

How is this different from LinkedIn or Indeed scrapers? Jobs come straight from the employer's own careers site, so they are complete, up to date and free of reposts and recruiter spam, and closed jobs are flagged closed on the next run.

Can I export to Excel or Google Sheets? Yes. Download CSV or Excel from the dataset, or use the Google Sheets integration to append new jobs automatically.

This Actor reads only publicly available job postings, which companies publish so they can be found. It does not log in, does not bypass any access control, and follows each site's robots.txt. Job postings are not personal data, but you are responsible for how you use the results. Check the terms of the sites involved and the laws that apply to you. The Actor is not affiliated with or endorsed by Workday, Oracle, Greenhouse, Lever, Ashby, or any company whose jobs it lists. Product names are used only to describe compatibility.

Support

Found a site that doesn't work, or need another platform (SmartRecruiters, iCIMS, SuccessFactors…)? Open an issue on the Actor's Issues tab with the URL. Issues are usually answered within a few days.