# Workday Jobs Scraper: Career Site Job Postings Feed (`agents001/workday-jobs-scraper`) Actor

Returns open job postings from any company's public Workday career site (myworkdayjobs.com): title, job id, location(s), remote or hybrid, posted date, job URL and optional description, plus a per-company summary with roles by location and new roles since your last run.

- **URL**: https://apify.com/agents001/workday-jobs-scraper.md
- **Developed by:** [Mike Ross](https://apify.com/agents001) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 job records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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: Career Site Job Postings Feed

Get the open jobs from any company that hires through a **Workday career site** (the `myworkdayjobs.com` and `myworkdaysite.com` job lists used by NVIDIA, Adobe, Pfizer, Intel, Salesforce, Cisco, Mastercard and thousands of other employers). You get **one record per job** with title, job id, location or locations, remote or hybrid where the site shows it, the posted date as text and as a parsed date, and the job link. Switch on **Include job description** to add the description as plain text, the exact posting date, every location, the country and the closing date.

Add an optional **summary per company**: open roles, roles by location and job category, remote and hybrid counts, roles posted in the last 7 and 30 days, and how many roles opened or closed since your last run (with `onlyNew` on). Schedule it daily with `onlyNew` on to get only the jobs that appeared since the previous run.

### What you get

**Job records** (`recordType: "job"`), one per open role:

| Field | Example |
|---|---|
| `company`, `companyKey`, `tenant`, `siteId` | `NVIDIA`, `nvidia/nvidiaexternalcareersite`, `nvidia`, `NVIDIAExternalCareerSite` |
| `jobId`, `requisitionId` | `JR2027601`, `JR2027601` |
| `title` | `Solutions Architect - MEP` |
| `location`, `locations`, `locationsText`, `locationCount` | `Australia, Remote`, every listed place, the text shown on the job list (for example `2 Locations`), `1` |
| `country`, `countryCode` | `Australia`, `AU` (with job descriptions on) |
| `workplaceType`, `remoteTypeRaw` | `remote`, `hybrid` or `onsite`, plus the site's own label such as `Flex` |
| `timeType` | `Full time` |
| `postedText`, `postedDate`, `postedDaysAgo`, `postedDatePrecision` | `Posted 3 Days Ago`, `2026-10-20`, `3`, `day` |
| `closingDate`, `hiringEntity` | `2026-11-30`, `AU02 NVIDIA Pty. Ltd` (with job descriptions on) |
| `jobUrl` | Link to the job page |
| `description` | Plain text (with job descriptions on) |
| `isNew`, `firstSeenAt` | Whether the job is new since the previous run with the same input |

`postedDatePrecision` tells you how exact the date is: `exact` comes from the job page, `day` is worked out from "Posted N Days Ago", and `atLeast` means the site only says "Posted 30+ Days Ago", so the date shown is the latest it could be. Turn on job descriptions to get exact dates for every job.

**Company summaries** (`recordType: "companySummary"`), one per company:

| Field | Meaning |
|---|---|
| `openRoles`, `matchingRoles`, `rolesOutput` | All open roles, roles that match your filters, job records returned |
| `rolesByLocation`, `topLocations` | Open roles by primary location |
| `locationFilterCounts`, `rolesByJobCategory` | The career site's own location and job category filters with their counts |
| `remoteRoles`, `hybridRoles`, `onsiteRoles`, `workplaceNotShown` | Workplace mix |
| `postedToday`, `postedLast7Days`, `postedLast30Days` | Recent posting activity |
| `newRolesSinceLastRun`, `closedRolesSinceLastRun`, `netChangeSinceLastRun` | Change since the previous run with the same input (empty on the first run and when `onlyNew` is off) |

The Output tab has three views: **Jobs**, **Company summaries** and **Job details**.

### Who it is for

- **Sales and business development teams** who treat hiring as a buying signal: a company opening ten data roles in Sydney is likely to buy data tools there.
- **Recruiters and staffing firms** tracking new roles at large employers, by country and function.
- **Investors and analysts** watching where large companies are adding or cutting roles.
- **Job seekers and job boards** who want one daily list of new roles from the companies they follow.

### Quick start

1. Click **Start** with the example input. You get up to 25 open roles at each of four example companies (Workday, Adobe, Pfizer and Intel) plus a summary for each.
2. Replace the list with your own career sites. Open the company's job list in a browser and copy the address, for example `https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`. A link to any single job on the site also works, and so does a `myworkdaysite.com/recruiting/<tenant>/<site>` address.
3. Add filters if you only want some roles, for example title `Engineer`, location `Germany`, or posted in the last 7 days.
4. Schedule it daily with **Only jobs not seen in previous runs** switched on, and send the dataset to email, Slack, Google Sheets or your CRM with an Apify integration or webhook.

### Input

| Field | What it does | Default |
|---|---|---|
| `startUrls` | Workday career site URLs. Add ` \| Company name` after a URL to set the company name in the output. Empty runs the example list | example list |
| `keywords` | Keep jobs whose title contains any of these words | none |
| `excludeKeywords` | Drop jobs whose title contains any of these words | none |
| `locations` | Keep jobs where any location contains any of these words | none |
| `workplaceType` | `any`, `remote`, `hybrid`, `remoteOrHybrid` or `onsite` | `any` |
| `postedWithinDays` | Keep jobs posted within this many days. 0 means any age | `0` |
| `onlyNew` | Return only jobs not returned before for this input | `false` |
| `includeDescription` | Open each returned job for its description, exact date, all locations, country and closing date | `false` |
| `includeCompanySummary` | Add one summary record per company | `true` |
| `maxJobsPerCompany` | Cap per company, newest first. 0 means no limit | `0` |
| `maxItems` | Cap on job records per run. 0 means no limit | `1000` |
| `stateStoreName` | Key-value store for the `onlyNew` history | `agents001-workday-jobs-feed-state` |
| `requestDelaySecs` | Minimum gap between requests to the same Workday host | `0.3` |

Example:

```json
{
    "startUrls": [
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite | NVIDIA",
        "https://workday.wd5.myworkdayjobs.com/Workday"
    ],
    "keywords": ["Engineer", "Architect"],
    "locations": ["Australia", "New Zealand"],
    "onlyNew": true,
    "includeDescription": true,
    "maxItems": 200
}
```

### Output example

```json
{
    "recordType": "job",
    "company": "NVIDIA",
    "companyKey": "nvidia/nvidiaexternalcareersite",
    "tenant": "nvidia",
    "siteId": "NVIDIAExternalCareerSite",
    "jobId": "JR2027601",
    "requisitionId": "JR2027601",
    "title": "Solutions Architect - MEP",
    "location": "Australia, Remote",
    "locations": ["Australia, Remote"],
    "locationsText": "Australia, Remote",
    "locationCount": 1,
    "country": "Australia",
    "countryCode": "AU",
    "workplaceType": "remote",
    "workplaceTypeSource": "location",
    "remoteTypeRaw": null,
    "timeType": "Full time",
    "postedText": "Posted 10 Days Ago",
    "postedDate": "2026-10-13",
    "postedDaysAgo": 10,
    "postedDatePrecision": "exact",
    "closingDate": null,
    "hiringEntity": "AU02 NVIDIA Pty. Ltd",
    "jobUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/Australia-Remote/Solutions-Architect---MEP_JR2027601",
    "description": "We are currently seeking a Senior MEP / Datacenter Infrastructure Engineer to join our ANZ SA team. ...",
    "isNew": true,
    "firstSeenAt": "2026-10-23T13:05:11Z",
    "scrapedAt": "2026-10-23T13:05:11Z",
    "sourceUrl": "https://nvidia.wd5.myworkdayjobs.com/wday/cxs/nvidia/NVIDIAExternalCareerSite/job/Australia-Remote/Solutions-Architect---MEP_JR2027601",
    "schemaVersion": 1
}
```

A run report is saved in the key-value store as `RUN_SUMMARY`: records returned, sites read, how each site was listed, and any site that could not be read.

### Pricing

This Actor uses **pay per event** pricing, with platform usage included:

- **$1.80 per 1,000 job records** (`job-record` event, $0.0018 each)
- **$5 per 1,000 company summaries** (`company-summary` event, $0.005 each)

You only pay for records saved to your dataset, so filters, `onlyNew`, `maxJobsPerCompany` and `maxItems` keep costs down. Job descriptions cost nothing extra. For example, a daily `onlyNew` run over 20 companies returns only the jobs posted since the previous day plus 20 summaries: $0.10 for the summaries plus $0.0018 per new job. Set a maximum cost per run in the run options and the Actor stops cleanly when it is reached.

### How "only new jobs" works

When `onlyNew` is on, the Actor remembers which job ids it has already returned for this exact input (sites plus filters) in a key-value store in your account called `agents001-workday-jobs-feed-state`. The next run only returns jobs that are not on that list. The first run returns everything that matches. Changing the sites or filters starts a fresh history, and you can keep separate histories by changing **History store name**. The store holds job ids and counts only.

With `onlyNew` off, the Actor does not open or update this store, so every record has `isNew` set to true. If a run stops with a message that it cannot open the store (for example because another Actor in your account already uses that name), enter a different name in **State store name** and run again.

The company summary's "since last run" numbers use the same history, so they are only filled in when `onlyNew` is on.

### Large career sites

Workday's job search returns at most 2,000 results for one search. For bigger sites the Actor splits the search by the site's own filters (job category, job type and so on) and joins the parts, so a site with 2,700 open roles is listed in full. The summary's `listingComplete` field confirms it. With a summary switched on the Actor lists every open job on each site, which takes about 90 seconds for a site with 2,700 roles. With the summary off and a job limit set, it stops as soon as it has enough matching jobs.

### Data source and privacy

All data comes from the public job list that each company publishes on its Workday career site, read through the same JSON requests the career site page makes in your browser. The Actor reads only published, publicly listed jobs and uses no login. Before reading a site it checks that site's `robots.txt` and skips any site the company has marked as off limits, such as internal or talent community sites. It sends a declared user agent and keeps a gap between requests.

The Actor outputs company and job information only. It never returns recruiter or hiring manager fields, and it removes email addresses and phone numbers from job descriptions.

### FAQ

**Where do I find a company's Workday career site?**
Open the company's careers page and click a job. If the address contains `myworkdayjobs.com` or `myworkdaysite.com`, paste it in. The part after the host (for example `NVIDIAExternalCareerSite`) is the site name, and it is case sensitive. Some companies have several sites (campus, experienced hires, a subsidiary); add each one you want.

**The company's careers page is on its own domain. Can I use it?**
Only if the job links lead to a `myworkdayjobs.com` or `myworkdaysite.com` address. Paste that address.

**Why is `workplaceType` empty for many jobs?**
Workday only shows remote or hybrid when the company sets it up. Workday itself does, NVIDIA does not. When the site does not say, a location containing "Remote" counts as remote and everything else stays empty.

**Why does a job show one location when it says "3 Locations"?**
The job list only shows the primary location for jobs with several places. Turn on **Include job description** to get every location. The location filter already handles this, using the site's own location filters.

**I got an error that the tenant was not recognised.**
Check the `wd` number in the address (`wd1`, `wd3`, `wd5`, `wd12` and so on). Copy the address straight from the browser.

**How fresh is the data?**
Live. Each run reads the career sites directly.

**Something looks wrong. What should I do?**
Open an issue on the Actor's Issues tab with the run link and the site URL.

### Disclaimer

This Actor is independent and is not affiliated with, endorsed by or sponsored by Workday, Inc. or any company whose jobs it returns. Product and company names are used only to describe compatibility and belong to their owners. Job data belongs to the companies that publish it; check the original posting before acting on it. You are responsible for using the data in line with the laws and terms that apply to you.

# Actor input Schema

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

One URL per company: the public job list on myworkdayjobs.com or myworkdaysite.com, for example https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite. A link to any job on the site also works. To set the company name shown in the output, add it after a bar: 'https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite | NVIDIA'. Leave empty to run the example list.

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

Only jobs whose title contains any of these words or phrases, for example 'Engineer', 'Account Executive', 'Director'. Case-insensitive.

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

Drop jobs whose title contains any of these words, for example 'Intern'. Case-insensitive.

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

Only jobs where any listed location contains any of these words, for example 'Germany', 'London', 'Remote'. The Actor also uses each site's own location filters, so jobs listed as '3 Locations' are matched correctly. Case-insensitive.

## `workplaceType` (type: `string`):

Keep all jobs, or only remote, hybrid or on-site jobs. Workday sites show this only when the company sets it up; jobs with 'Remote' in the location count as remote. 'On-site' also keeps jobs with no remote or hybrid marking.

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

Only jobs posted within this many days. 0 means any age.

## `onlyNew` (type: `boolean`):

Remember which jobs were already returned for this exact input and only return jobs that are new since then. The first run returns everything that matches. Ideal for scheduled daily runs. Changing the sites or filters starts a fresh history.

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

Open each returned job and add its description as plain text, plus the exact posting date, every location, the country and the closing date. Email addresses and phone numbers are removed. This makes one extra request per job, so runs take longer.

## `includeCompanySummary` (type: `boolean`):

Add one summary record per company: open roles, roles by location and job category, remote and hybrid counts, roles posted in the last 7 and 30 days, and new and closed roles since the previous run. This lists every open job on the site, so very large sites take longer. The change since the previous run needs 'Only jobs not seen in previous runs' to be on.

## `maxJobsPerCompany` (type: `integer`):

Return at most this many jobs per company, newest first. 0 means no limit. The company summary still counts every open role.

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

Stop returning job records after this many in total. 0 means no limit. Company summaries are not counted. You pay per job record returned.

## `stateStoreName` (type: `string`):

Only used when 'Only jobs not seen in previous runs' is on. Name of the key-value store in your account that keeps the list of jobs already seen. Each different input gets its own record inside it. Change it only to keep separate histories. If a run reports that it cannot open the store, enter a different name here.

## `requestDelaySecs` (type: `number`):

Minimum seconds between requests to the same Workday host. Keep this polite.

## Actor input object example

```json
{
  "startUrls": [
    "https://workday.wd5.myworkdayjobs.com/Workday",
    "https://adobe.wd5.myworkdayjobs.com/external_experienced",
    "https://pfizer.wd1.myworkdayjobs.com/PfizerCareers",
    "https://intel.wd1.myworkdayjobs.com/External"
  ],
  "workplaceType": "any",
  "postedWithinDays": 0,
  "onlyNew": false,
  "includeDescription": false,
  "includeCompanySummary": true,
  "maxJobsPerCompany": 25,
  "maxItems": 1000,
  "stateStoreName": "agents001-workday-jobs-feed-state",
  "requestDelaySecs": 0.3
}
```

# Actor output Schema

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

No description

## `companySummaries` (type: `string`):

No description

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

No description

# 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": [
        "https://workday.wd5.myworkdayjobs.com/Workday",
        "https://adobe.wd5.myworkdayjobs.com/external_experienced",
        "https://pfizer.wd1.myworkdayjobs.com/PfizerCareers",
        "https://intel.wd1.myworkdayjobs.com/External"
    ],
    "maxJobsPerCompany": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("agents001/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": [
        "https://workday.wd5.myworkdayjobs.com/Workday",
        "https://adobe.wd5.myworkdayjobs.com/external_experienced",
        "https://pfizer.wd1.myworkdayjobs.com/PfizerCareers",
        "https://intel.wd1.myworkdayjobs.com/External",
    ],
    "maxJobsPerCompany": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("agents001/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": [
    "https://workday.wd5.myworkdayjobs.com/Workday",
    "https://adobe.wd5.myworkdayjobs.com/external_experienced",
    "https://pfizer.wd1.myworkdayjobs.com/PfizerCareers",
    "https://intel.wd1.myworkdayjobs.com/External"
  ],
  "maxJobsPerCompany": 25
}' |
apify call agents001/workday-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,agents001/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/Jd0MfwZhlyx6ubrwf/builds/uhLPEThJtY5TobEbH/openapi.json
