# Workday Jobs Scraper — Any Workday Careers Site | $1/1K (`steadyrow/workday-jobs`) Actor

Scrape every open job from any Workday careers site (\*.myworkdayjobs.com): paste the careers URL or tenant/site name. Full descriptions, locations, posting dates and parsed salary ranges. Public site API, no proxy. Server-side keyword search and a monitor mode for new jobs.

- **URL**: https://apify.com/steadyrow/workday-jobs.md
- **Developed by:** [Steadyrow](https://apify.com/steadyrow) (community)
- **Categories:** Jobs, Automation
- **Stats:** 2 total users, 1 monthly users, 75.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 jobs

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 — Any Workday Careers Site | $1/1K

**Paste a Workday careers URL, get the open jobs as clean JSON. $1 per 1,000 jobs.**

Large employers (NVIDIA, Adobe, Salesforce and thousands more) run their careers sites on Workday (`<company>.wd5.myworkdayjobs.com/<site>`). This Actor uses the **public JSON API that the careers site itself calls** to list the jobs, then reads each posting for its full description, every location, posting date and pay range. No browser and no proxy are needed.

- ✅ **Any Workday careers site** — paste the careers URL, a job URL, `tenant.wdN/site`, or just `tenant/site` (the Workday data centre — wd1, wd3, wd5, wd12… — is looked up for you)
- ✅ **Server-side keyword search** — keywords are sent to Workday's own search, so you can pull "engineer" jobs from a 2,000-job site without paging everything
- ✅ **Complete postings** — full description, all locations (Workday's "3 Locations" is expanded), employment type, remote flag, posting date
- ✅ **Pay ranges** parsed from the description text when the posting states one
- ✅ **Monitor mode** — pay only for jobs you have not received before
- ✅ **Filters** — keywords, excluded words, location, remote, posted within N days
- ✅ No login, no CAPTCHA handling, no personal data

> Also want Greenhouse, Lever, Ashby and SmartRecruiters in the same run? Use the combined [ATS Jobs API](https://apify.com/steadyrow/ats-jobs). This is the Workday-only version.

### Use cases

- **Enterprise hiring monitoring** — track what large employers are hiring, by location and team
- **Job boards and aggregators** that need Workday coverage
- **Alerts for new roles** at specific companies (daily monitor run)
- **Labor-market and salary research** across big employers
- **Recruiting-agency lead signals**: which companies open many roles in a region

### Input

```json
{
    "careerSites": [
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
        "adobe.wd5/external_experienced",
        "salesforce/External_Career_Site"
    ],
    "keywords": ["engineer"],
    "excludeKeywords": ["intern"],
    "locations": ["United States", "Remote"],
    "postedWithinDays": 14,
    "maxItemsPerSource": 200,
    "monitorMode": false
}
```

| Field | What it does |
|---|---|
| `careerSites` | **Required.** One per line. Accepted: the careers URL (`https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`, `https://wd3.myworkdaysite.com/recruiting/<tenant>/<site>`), a URL of any job on the site, `nvidia.wd5/NVIDIAExternalCareerSite`, or `nvidia/NVIDIAExternalCareerSite`. A company name alone is not enough — one company can have several Workday sites. |
| `keywords` | Keep jobs whose **title** contains any of these words. Sent to Workday's search, one query per keyword, results de-duplicated. |
| `excludeKeywords` | Drop jobs whose title contains any of these words. |
| `locations` | Keep jobs whose location, any extra location or country contains one of these words (whole-word, case-insensitive). `remote` matches remote jobs. |
| `remote` | `any`, `remote_only` or `exclude_remote`. |
| `postedWithinDays` | Only jobs posted in the last N days (Workday shows the date at day precision). |
| `maxItemsPerSource` / `maxItems` | Limits per site / per run (0 = no limit). |
| `maxConcurrency` | Detail requests in parallel (default 4, max 10). Requests to Workday are rate-limited to about 4 per second regardless. |
| `monitorMode`, `monitorStateName` | Only output jobs not delivered before; name of the store that remembers them. |

#### How to find the careers URL

Open the company's careers page and click "Search for jobs". The address looks like `https://<tenant>.wd5.myworkdayjobs.com/<site>` — paste it as it is, locale segments such as `/en-US/` are fine.

### Output

```json
{
    "job_id": "workday:nvidia:GenAI-Algorithms-Intern---Model-Optimization-for-Inference_JR2027377",
    "ats": "workday",
    "company": "Nvidia",
    "company_board_id": "nvidia",
    "title": "GenAI Algorithms Intern – Model Optimization for Inference",
    "department": null,
    "team": null,
    "location": "Poland, Warsaw",
    "locations": ["Poland, Warsaw", "Poland, Remote"],
    "country": "PL",
    "remote": true,
    "workplace_type": "remote",
    "employment_type": "FULL_TIME",
    "posted_at": "2026-10-20T00:00:00.000Z",
    "updated_at": null,
    "salary_min": 117750,
    "salary_max": 204100,
    "salary_currency": "PLN",
    "salary_period": "YEAR",
    "salary_source": "description",
    "description_text": "…",
    "apply_url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/Poland-Warsaw/GenAI-Algorithms-Intern---Model-Optimization-for-Inference_JR2027377/apply",
    "source_url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/Poland-Warsaw/GenAI-Algorithms-Intern---Model-Optimization-for-Inference_JR2027377",
    "input": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "scraped_at": "2026-10-20T16:50:26.671Z"
}
```

Workday-specific notes:

- Workday does not publish departments or teams; `department` and `team` are `null` (and there is no department filter).
- Salary is parsed from the posting text (`salary_source: "description"`); it is `null` when the text states no range.
- `posted_at` is Workday's posting date at day precision (00:00 UTC).
- `workplace_type` is `remote` when Workday or the title says so, otherwise `null` — Workday does not distinguish hybrid from onsite in its data.
- The company name is derived from the tenant (`nvidia` → `Nvidia`).

### Speed and limits

- Workday needs one request per job for the description, so a run is about **1–2 jobs per second**: 500 jobs take roughly 5 minutes. In our tests 162 NVIDIA internship jobs took about 100 seconds.
- One Workday search returns at most **~2,000 results**. For very large sites add `keywords` (each keyword is a separate search) or use `postedWithinDays` plus monitor mode.
- Requests are limited to about 4 per second per host to stay polite.

### Monitor mode

Turn on **Monitor mode**, save the input as a task and schedule it daily. The first run returns all matching jobs, later runs only jobs not delivered before (state is kept per site in the key-value store `workday-jobs-monitor`). Note that a monitor run still lists the whole site to find new jobs, so combine it with `keywords` or `postedWithinDays` on big sites. Tested: second run returned 0 jobs; after forgetting 3 jobs the third run returned exactly those 3.

### Pricing

| Event | Price |
|---|---|
| Job in the dataset | **$0.001** ($1 per 1,000 jobs) |
| Actor start | $0.002 per run |

500 jobs ≈ $0.50. Jobs removed by your filters and jobs already delivered in monitor mode are free. Use **Maximum cost per run** to cap spending.

### FAQ

**The site "was not found".** Check the URL: it must be the *careers site* (`…/<site>`), not the company's marketing page. For `tenant/site` shorthand the Actor tries the common Workday data centres; if the site is not found, paste the full URL.

**Why is the tenant/site shorthand slower?** It sends one small request per data centre until it finds the site (about a second each at most).

**Is it legal?** The Actor reads public job postings from the same public endpoints the careers site uses, without login or any protection bypass, and outputs no personal data. You are responsible for how you use the data.

# Actor input Schema

## `careerSites` (type: `array`):

One per line. Paste the careers site URL (https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite, https://wd3.myworkdaysite.com/recruiting/<tenant>/<site>), a job URL from that site, `nvidia.wd5/NVIDIAExternalCareerSite`, or just `tenant/site` (`nvidia/NVIDIAExternalCareerSite`; the Workday data centre is looked up for you).

## `keywords` (type: `array`):

Keep jobs whose title contains at least one of these words (whole-word, case-insensitive). Keywords are sent to Workday's own search, so large sites (NVIDIA, Salesforce) are not paged in full. Leave empty to keep all.

## `searchInDescription` (type: `boolean`):

By default keywords are matched against the job title only.

## `excludeKeywords` (type: `array`):

Drop jobs whose title contains any of these words (e.g. Senior, Intern).

## `locations` (type: `array`):

Keep jobs whose location, any of their locations, or country contains one of these words (whole-word, case-insensitive; e.g. London, Germany, US). Use `remote` to match remote jobs.

## `remote` (type: `string`):

Filter by remote eligibility.

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

Only jobs posted in the last N days. 0 = no limit.

## `maxItemsPerSource` (type: `integer`):

Stop after this many jobs from one board. 0 = all jobs.

## `maxItems` (type: `integer`):

Stop the whole run after this many jobs. 0 = no limit.

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

Adds `description_text`. Workday needs one request per job for its locations, date and description in any case, so turning this off only makes the output smaller.

## `includeDescriptionHtml` (type: `boolean`):

Adds `description_html` (cleaned original HTML).

## `monitorMode` (type: `boolean`):

Remembers every job already delivered (per board) and outputs only jobs you have not received before. The first run outputs all matching jobs. Ideal for a daily schedule — you only pay for new jobs.

## `monitorStateName` (type: `string`):

Name of the key-value store that keeps the list of delivered jobs. Use a different name per task if you run several independent monitors.

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

Detail requests run in parallel up to this number. Requests to one ATS host are additionally limited to about 4 per second.

## Actor input object example

```json
{
  "careerSites": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "searchInDescription": false,
  "remote": "any",
  "postedWithinDays": 0,
  "maxItemsPerSource": 20,
  "maxItems": 0,
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "monitorMode": false,
  "monitorStateName": "workday-jobs-monitor",
  "maxConcurrency": 4
}
```

# Actor output Schema

## `results` (type: `string`):

All Workday job postings collected in this run, one row per job.

# 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 = {
    "careerSites": [
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    ],
    "maxItemsPerSource": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyrow/workday-jobs").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 = {
    "careerSites": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"],
    "maxItemsPerSource": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("steadyrow/workday-jobs").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 '{
  "careerSites": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "maxItemsPerSource": 20
}' |
apify call steadyrow/workday-jobs --silent --output-dataset

```

## MCP server setup

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

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/b5JSwoTCW6degrUaf/builds/23hRZhc4wbMTlL29b/openapi.json
