# Workday Jobs Scraper: Career Site Jobs with Salary (`psgameplay121/workday-jobs-feed`) Actor

Get every open job from any Workday career site (myworkdayjobs.com) in one clean schema, with salary, seniority, job function, remote/hybrid, country, tech stack and visa fields added. Handles the 2,000-result cap. Incremental mode returns only new jobs.

- **URL**: https://apify.com/psgameplay121/workday-jobs-feed.md
- **Developed by:** [Vivek Sinha](https://apify.com/psgameplay121) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 job returneds

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: every open job from any Workday career site

Get **every open job from Workday career sites** (the `*.myworkdayjobs.com` and `*.myworkdaysite.com` pages used by NVIDIA, Salesforce, Adobe, Mastercard, Target, Pfizer, Intel, PayPal and thousands of other employers) in **one clean schema**, with the fields recruiters, sales teams and job boards actually need already filled in: **salary, seniority, job function, remote/hybrid/onsite, country, tech stack, years of experience and visa sponsorship**.

Paste a career-site URL, or just a company's Workday tenant name, and the Actor finds the career site for you.

### Why this Actor

- **Beats Workday's 2,000-result limit.** A single Workday search stops at 2,000 jobs. For bigger employers the Actor automatically splits the search by country, job family or location and merges the parts, so you get the whole board, not the first 2,000. The run report tells you if any slice was still too large.
- **Enriched, decision-ready rows.** Every job gets a normalized `jobFunction`, `seniority`, `workplaceType`, `employmentType`, `countryCode`, `salaryMin`/`salaryMax`/`salaryCurrency`/`salaryPeriod` (parsed from the pay-transparency text most US employers must publish), `techKeywords`, `yearsExperienceMin` and `visaSponsorship`. The same schema as our **ATS Jobs Feed** Actor, so you can combine Workday with Greenhouse, Lever, Ashby and others.
- **Pay only for what you need.** Title, location, job function, seniority and posting-age filters run before any detail request or charge. Title keywords are also sent to Workday's own search, and location keywords are matched against the site's country and location lists, so filtered runs are fast and cheap.
- **Incremental monitoring.** Turn on **Incremental mode** and schedule a daily run: the Actor remembers what it saw and outputs **only new jobs**. Unchanged jobs cost no detail requests. Optionally get a free `closed` row when a job disappears.
- **Tenant auto-discovery.** Enter `pfizer` or `target`. The Actor looks up the tenant's data center and career sites and uses the biggest one (or all of them, if you switch on *All career sites of a bare tenant*).
- **Fast and reliable.** It reads the same public JSON the career site itself uses. No browser, no proxy, no captcha, no login.
- **Failures are reported, not hidden.** Every input that could not be resolved, and every career site that failed, is listed in the `RUN_REPORT` record with the reason. You are never charged for failed rows.
- **Privacy by default.** Email addresses inside job text are redacted unless you switch that off.

### Who uses it

- **Sales and RevOps:** find enterprises hiring for the role your product supports. "Hiring 40 data engineers" is a buying signal.
- **Recruiters and staffing agencies:** a daily feed of fresh roles at big-employer accounts.
- **Job boards and aggregators:** back-fill listings with direct-from-employer jobs and real apply links.
- **Market and compensation research:** salary bands, remote share and tech demand across large employers.
- **AI agents and RAG:** clean plain-text descriptions with consistent metadata.

### Input

| Field | What it does |
|---|---|
| `sites` | Career-site URLs (`https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`, `https://wd1.myworkdaysite.com/recruiting/paypal/jobs`), `tenant/site` pairs (`target.wd5/targetcareers`), or a bare tenant name (`pfizer`). |
| `allSitesForTenant` | A bare tenant can have several career sites. Off = the biggest one only. On = all (duplicates removed). |
| `titleKeywords` / `excludeTitleKeywords` | Keep or drop jobs by title words. |
| `locationKeywords` | e.g. `India`, `Germany`, `Austin`, `Remote`. |
| `workplaceTypes` | `remote`, `hybrid`, `onsite`. |
| `jobFunctions` | `engineering`, `data-ml`, `product`, `design`, `sales`, `marketing`, `customer`, `operations`, `finance`, `people-hr`, `legal-compliance`, `security`, `it`, `other`. |
| `seniorities` | `intern`, `junior`, `mid`, `senior`, `staff`, `principal`, `lead`, `manager`, `director`, `vp`, `c-level`. |
| `postedWithinDays` | Only jobs posted in the last N days. |
| `includeDescriptions` | On (default) = full details per job. Off = list-only rows (title, location, posted-ago text, URL), much faster. |
| `descriptionFormat` | `text` (default), `html`, `both` or `none`. |
| `incremental`, `stateKey`, `emitClosedJobs` | Monitoring mode. Use one `stateKey` per watchlist. |
| `maxJobsPerSite`, `maxJobs` | Hard caps. You can also set a maximum charge per run. |

Example:

```json
{
  "sites": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite", "target.wd5/targetcareers", "pfizer"],
  "titleKeywords": ["data engineer", "machine learning"],
  "locationKeywords": ["United States", "India"],
  "postedWithinDays": 30,
  "incremental": true,
  "stateKey": "enterprise-data-hiring"
}
```

### Output (real example, description shortened)

```json
{
  "recordType": "job",
  "jobKey": "workday:salesforce:JR350071",
  "ats": "workday",
  "companySlug": "salesforce",
  "companyName": "Salesforce",
  "careerSite": "External_Career_Site",
  "jobId": "JR350071",
  "title": "Deployment Strategist",
  "jobFunction": "other",
  "seniority": "mid",
  "employmentType": "full-time",
  "workplaceType": "hybrid",
  "location": "Ireland - Dublin",
  "countryCode": "IE",
  "hiringEntity": "SFDC Ireland Limited",
  "salaryMin": null,
  "yearsExperienceMin": 4,
  "techKeywords": ["Python", "Java", "JavaScript", "LLM", "RAG", "Salesforce"],
  "postedAt": "2026-10-28T00:00:00.000Z",
  "daysSincePosted": 0,
  "jobUrl": "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site/job/Ireland---Dublin/Deployment-Strategist_JR350071",
  "applyUrl": "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site/job/Ireland---Dublin/Deployment-Strategist_JR350071/apply",
  "descriptionText": "To get the best candidate experience, please consider applying for a maximum of 3 roles…",
  "descriptionWordCount": 1214,
  "changeType": null
}
```

Export as JSON, CSV, Excel or XML, or connect via API, webhooks, Make, Zapier, n8n or MCP.

### Pricing

Pay per event, with no subscription: a flat price per job row returned (after your filters; in incremental mode only new or changed jobs). Rows for jobs that closed (incremental mode) are free. Set a maximum charge per run and the Actor stops cleanly when it is reached. See the pricing box on this page for the current price.

### FAQ

**Is this legal?** The Actor only reads the public job-listing JSON that each Workday career site serves to every visitor, the same data job seekers and search engines see. It does not log in, bypass protections or collect candidate data. Job descriptions can still mention people, so email addresses are redacted by default. You are responsible for how you use the data.

**My company wasn't found.** Paste the full career-site URL from your browser (the address of the page that lists the jobs). Some employers show Workday jobs inside their own website (for example careers.company.com). Open one job's "Apply" link: if it goes to a `myworkdayjobs.com` address, use that address.

**How accurate is the posting date?** With full details on, the date is the posting's start date from Workday. In list-only mode Workday only shows "Posted 3 days ago", and anything older than 30 days shows as "30+ days ago" with no exact date.

**How does remote/hybrid work?** Most Workday sites have no structured field for it. The Actor reads it from the job text where employers state it ("hybrid role", "Work Model for this Role"), and otherwise falls back to the location. Treat jobs with no clear statement as best-effort `onsite`.

**How accurate are seniority and function?** They are rule-based labels from the job title. They work well for common titles; treat edge cases as best-effort. Salary is only returned when the employer publishes it in the job text.

**Does incremental mode catch edited descriptions?** It detects new jobs and changed titles or locations. A description-only edit is not detected, in exchange for not re-fetching every job on each run.

**Which other platforms are covered?** Workday here. For Greenhouse, Lever, Ashby, Workable, SmartRecruiters and Recruitee, use our **ATS Jobs Feed** Actor.

# Actor input Schema

## `sites` (type: `array`):

One per line. Paste a Workday career-site URL (https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite, https://wd1.myworkdaysite.com/recruiting/paypal/jobs), a 'tenant/site' pair (target.wd5/targetcareers), or just the tenant name (pfizer). A bare tenant is looked up automatically and its main career site is used.

## `allSitesForTenant` (type: `boolean`):

A bare tenant name can have several career sites (e.g. external, early careers, country-specific). Off = scrape only the biggest one. On = scrape all of them (duplicates are removed).

## `titleKeywords` (type: `array`):

Keep only jobs whose title contains at least one of these words (case-insensitive). Also sent to Workday's own search to skip irrelevant jobs. Leave empty for all jobs.

## `excludeTitleKeywords` (type: `array`):

Drop jobs whose title contains any of these words, e.g. intern, contract.

## `locationKeywords` (type: `array`):

Keep jobs whose location contains any of these, e.g. India, Germany, Austin. Matched against the site's country and location lists first, so you only fetch what you need.

## `workplaceTypes` (type: `array`):

Keep only these workplace types (detected from ATS fields and text).

## `jobFunctions` (type: `array`):

Keep only these normalized job functions.

## `seniorities` (type: `array`):

Keep only these normalized seniority levels (detected from the title).

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

0 = any age. Workday shows exact dates only on each job; listings with '30+ days ago' are treated as older than 30 days.

## `includeDescriptions` (type: `boolean`):

On = one extra request per job to get the full description, salary, exact posting date and country. Off = list-only rows (title, location, posted-ago text, URL), much faster.

## `descriptionFormat` (type: `string`):

How to return the job description. Plain text is best for search, AI and spreadsheets.

## `maxDescriptionChars` (type: `integer`):

Longer descriptions are cut to this length.

## `redactEmailAddresses` (type: `boolean`):

Replaces any email address found in job text with \[email redacted].

## `incremental` (type: `boolean`):

Remembers jobs seen in earlier runs with the same state key and outputs only jobs that are new or whose title/location changed. Ideal for scheduled daily runs: you are only charged for new jobs, and unchanged jobs cost no detail requests.

## `stateKey` (type: `string`):

Use a different key per watchlist so runs don't share memory.

## `emitClosedJobs` (type: `boolean`):

In incremental mode, add a free row with changeType = closed for jobs that disappeared since the last run.

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

0 = no limit.

## `maxJobs` (type: `integer`):

0 = no limit. You can also cap spend with the run's maximum charge setting.

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

How many job-detail requests to run at the same time per page. Lower this if a site starts rate-limiting.

## Actor input object example

```json
{
  "sites": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "target.wd5/targetcareers",
    "pfizer"
  ],
  "allSitesForTenant": false,
  "postedWithinDays": 0,
  "includeDescriptions": true,
  "descriptionFormat": "text",
  "maxDescriptionChars": 20000,
  "redactEmailAddresses": true,
  "incremental": false,
  "stateKey": "default",
  "emitClosedJobs": false,
  "maxJobsPerSite": 0,
  "maxJobs": 0,
  "maxConcurrency": 5
}
```

# Actor output Schema

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

All rows returned by this run.

## `runReport` (type: `string`):

Summary of the run: career sites found, jobs returned, coverage and any errors.

# 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 = {
    "sites": [
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
        "target.wd5/targetcareers",
        "pfizer"
    ]
};

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

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

```

## MCP server setup

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

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/WCNweFkc03mohLoXo/builds/RljjOXxVbgNNm1Iia/openapi.json
