# Workday Jobs Scraper (`beyotomo/workday-jobs-scraper`) Actor

Scrape every job from any Workday career site (myworkdayjobs.com): salary ranges, remote type, posted date and full description. Gets past the 2,000-job limit. Daily new-jobs monitoring. No login or proxy.

- **URL**: https://apify.com/beyotomo/workday-jobs-scraper.md
- **Developed by:** [Beyotomo Data](https://apify.com/beyotomo) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 job results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Workday Jobs Scraper

Scrape every open job from any company's **Workday career site** (`myworkdayjobs.com` or `myworkdaysite.com`): title, location, country, remote type, posted date, **salary range** and the full description. Paste a career-site URL and get a clean table you can download as Excel, CSV or JSON, or pull through the API.

Thousands of employers run their careers pages on Workday, including NVIDIA, Salesforce and many other large companies. This Actor reads the same public job data the career site shows in your browser, with no login, cookies or proxy.

### Why this scraper

- **Gets every job, not just the first 2,000.** Workday never shows more than 2,000 results for one search. When a site has more, the Actor splits the search by job category, job type or country and joins the results, with no duplicates. In our tests NVIDIA's site returned all 2,793 job listings (titles and links) in under two minutes.
- **Salary ranges as numbers.** US pay-transparency ranges such as "184,000 USD – 287,500 USD" or "$45.50 to $60.00 per hour" become `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryPeriod`.
- **Monitoring mode.** Turn on *Only new jobs* and schedule the Actor daily. Each run returns only openings it hasn't returned before, so you're not charged twice for the same job.
- **Filters that save money.** Keywords, *posted within N days* and *location contains* are applied before you're charged. Filters you set on the career site itself (category, country, job type) are kept when you copy its URL.
- **Pay only for jobs you get.** $1.00 per 1,000 jobs. Set a maximum cost per run and the Actor stops cleanly at that limit.

### Who uses it

- **Job boards and aggregators** filling listings straight from employers' own career sites.
- **Recruiters and staffing agencies** watching target companies for new openings.
- **Sales teams** using hiring as a buying signal (for example, a company hiring data engineers).
- **Analysts and researchers** tracking hiring trends, pay ranges and locations across employers.
- **Job seekers** getting a daily list of new roles at the companies they care about.

### How to use it

1. Open the company's careers page and click through to its job list. The address looks like `https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`.
2. Optionally filter on the site (location, category), then copy the URL from the address bar.
3. Paste one or more URLs into **Career site URLs**, set any filters, and click **Start**.
4. Download the results or connect them to Google Sheets, Zapier, Make or a webhook from the run's **Integrations** tab.

#### Input example

```json
{
  "startUrls": [
    { "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite" },
    { "url": "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site" }
  ],
  "searchText": "data engineer",
  "postedWithinDays": 7,
  "locationContains": ["India", "Remote"],
  "maxJobsPerSite": 500,
  "includeDescription": true,
  "onlyNewJobs": false
}
```

| Field | What it does |
|---|---|
| `startUrls` | Workday job-list URLs. Site filters in the URL are kept. |
| `searchText` | Keywords, searched like the site's own search box. |
| `postedWithinDays` | Only jobs posted in the last N days (0 = today). |
| `locationContains` | Keep jobs whose location, extra locations or country contains any of these words. |
| `maxJobsPerSite` | Stop after this many jobs per URL. 0 = no limit. Default 100. |
| `includeDescription` | Fetch full details: description, exact date, country, remote type, job ID, salary. On by default. |
| `includeHtml` | Also return the description's original HTML. |
| `onlyNewJobs` | Monitoring mode: return only jobs not returned by earlier runs. |
| `maxConcurrency` | Parallel requests (1–20, default 8). |
| `proxyConfiguration` | Not needed for most sites. |

### Output

Each job is one row. A shortened real example:

```json
{
  "title": "Senior Site Reliability Engineer - Kubernetes Platform",
  "company": "nvidia",
  "hiringOrganization": "2100 NVIDIA USA",
  "jobReqId": "JR2013271",
  "location": "US, CA, Santa Clara",
  "additionalLocations": ["US, TX, Austin", "US, NC, Durham"],
  "country": "United States of America",
  "remoteType": null,
  "timeType": "Full time",
  "postedDate": "2026-11-05",
  "postedDaysAgo": 0,
  "postedText": "Posted Today",
  "salaryMin": 184000,
  "salaryMax": 287500,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "salaryText": "184,000 USD – 287,500 USD",
  "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-Site-Reliability-Engineer---HPC_JR2013271",
  "descriptionText": "NVIDIA has been transforming computer graphics, PC gaming, and accelerated computing…",
  "careerSite": "nvidia/NVIDIAExternalCareerSite",
  "workdayId": "0b201f8dab7d10015d42015818de0000",
  "scrapedAt": "2026-11-06T07:58:09+00:00"
}
```

- `company` is the company's Workday name; `hiringOrganization` is the legal entity hiring for the role.
- `remoteType` is filled when the company publishes it, for example "Remote", "Hybrid" or "Office - Flexible".
- Salary fields are empty when the description has no pay range. The first range is used when there are several (for example, per level).
- With *Include full job details* off, you get title, location text, posted text, job ID and URL. It's faster, but still costs the same per job.

A **RUN_SUMMARY** record in the run's key-value store lists, for each URL, how many jobs were listed, saved, skipped as already seen or filtered out, plus any error.

### Pricing

**$1.00 per 1,000 jobs** ($0.001 per job saved). There's no start fee, and jobs that your filters remove aren't charged.

| Example | Jobs | Cost |
|---|---|---|
| Try it: 50 jobs from one company | 50 | $0.05 |
| Every job at NVIDIA | ~2,800 | ~$2.80 |
| Daily new-jobs feed from 20 companies (~30 new jobs each per day) | ~600 a day | ~$0.60 a day |

Set **Maximum cost per run** in the run options to cap any run.

### Monitoring new jobs

1. Turn on **Only new jobs (monitoring mode)**.
2. Save the input as a **Task** and add a daily **Schedule**.
3. The first run returns all current jobs. Every later run returns only jobs that earlier runs didn't return.

The memory is a key-value store named `workday-jobs-monitor` in your account, with one record per career site and keyword. Delete a record to start that site fresh. If a run is stopped early (by your job limit or cost limit), the jobs it didn't reach are returned next time.

### FAQ

**Which URLs work?** Any Workday career site whose address ends in `.myworkdayjobs.com` or `.myworkdaysite.com`. Some companies show Workday jobs on their own domain. Click through to a job and the address usually changes to a `myworkdayjobs.com` one; use that.

**Do I need a proxy?** Usually not. The Actor sends a modest number of requests and retries politely on rate limits. Turn on Apify Proxy only if a site starts refusing requests.

**Why are some fields empty?** Each company chooses what to publish. Remote type, salary and extra locations are only filled when the company provides them.

**Is it legal?** The Actor reads publicly available job postings that companies publish for anyone to see. It doesn't log in and doesn't collect applicant data. You are responsible for how you use the data, including any site terms and data-protection laws that apply to you.

**Something broke or a field is missing?** Open an issue on the Actor's **Issues** tab with the URL you used. Workday sites change from time to time; reported issues are investigated and fixed.

*This Actor is independent and isn't affiliated with or endorsed by Workday, Inc.*

# Changelog

This Actor's version history is a separate document: https://apify.com/beyotomo/workday-jobs-scraper/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

One or more Workday job-list pages, for example https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite. Filters you pick on the career site itself (location, job category, job type) are kept when you copy its URL. Supported addresses end in .myworkdayjobs.com or .myworkdaysite.com.

## `searchText` (type: `string`):

Optional. Searched the same way as the career site's own search box, for example "data engineer". Applies to every URL that doesn't already contain a search.

## `postedWithinDays` (type: `integer`):

Optional. Only return jobs posted in the last N days. 0 means today only, 7 means the last week.

## `locationContains` (type: `array`):

Optional. Keep a job only if its location, extra locations or country contains one of these words, for example "Remote", "India", "Bengaluru". Not case-sensitive. Most accurate with "Include full job details" on, because the job list alone sometimes shows only "3 Locations".

## `maxJobsPerSite` (type: `integer`):

Stop after saving this many jobs from each URL. 0 means no limit (every job the site lists).

## `includeDescription` (type: `boolean`):

Fetch each job's page for the description, exact posted date, country, remote type, job ID and salary range. Turn off for a faster title-and-link list.

## `includeHtml` (type: `boolean`):

Adds the original HTML of the description next to the plain-text version.

## `onlyNewJobs` (type: `boolean`):

Remembers which jobs earlier runs returned and saves only jobs that weren't returned before. The first run returns everything. Schedule the Actor daily to get a feed of new openings. The memory is kept per career site and keyword, in a key-value store named workday-jobs-monitor.

## `maxConcurrency` (type: `integer`):

How many job pages to fetch at the same time. The default is gentle on the career site and fast enough for most runs.

## `proxyConfiguration` (type: `object`):

Not needed for most career sites. Turn on Apify Proxy only if a site starts refusing requests.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    }
  ],
  "maxJobsPerSite": 50,
  "includeDescription": true,
  "includeHtml": false,
  "onlyNewJobs": false,
  "maxConcurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `jobs` (type: `string`):

Every job saved by the run, one row per job.

## `runSummary` (type: `string`):

Per career site: jobs listed, saved, skipped as already seen or filtered out, and any error.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
        }
    ],
    "maxJobsPerSite": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("beyotomo/workday-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite" }],
    "maxJobsPerSite": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("beyotomo/workday-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    }
  ],
  "maxJobsPerSite": 50
}' |
apify call beyotomo/workday-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,beyotomo/workday-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dFhdR514lQq8OEc0R/builds/T21iNjaG0GKEd0WKQ/openapi.json
