# Workday Jobs Scraper: All Jobs, Salaries & Only-New Feed (`vantum/workday-jobs-feed`) Actor

Every open job from any Workday career site, even past Workday's 2,000-result cap. Descriptions, salaries, apply links, only-new & closed-job tracking.

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

## Pricing

$0.80 / 1,000 job saveds

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: All Jobs, Salaries & Only-New Feed

Get **every open job** from any company career site that runs on **Workday** (`*.myworkdayjobs.com`, `*.myworkdaysite.com`) as clean JSON, CSV or Excel. That includes sites with more than 2,000 jobs, where Workday itself stops showing results. Each job comes with its full description, exact posting date, all locations, remote type, req ID, apply link and the **salary range** when the posting states one.

Run it on a schedule with **Only new jobs** turned on and it becomes a **job feed**. Each run returns only the postings that appeared since the last run, and you pay only for those. It can also tell you which jobs were closed.

**$0.80 per 1,000 jobs. No start fee.** Failed sites, dry runs and closed-job rows are free.

### Why this one

| | This Actor | Typical Workday scrapers on the Store |
|---|---|---|
| Sites with more than 2,000 jobs | ✅ Gets all of them. It splits the search by Workday's own filters automatically (tested: Target 14,164 of 14,175, NVIDIA 2,689 of 2,689) | Many stop at 2,000 |
| Only new jobs since the last run | ✅ Built in, with memory between runs, and you pay only for new jobs | Usually "compare the IDs yourself" |
| Closed-job detection | ✅ Optional free `closed` rows | Rarely |
| Start from a search URL with filters | ✅ Paste a Workday URL with location or category filters and they are kept | Usually just the site root |
| Start from a company website or name | ✅ Finds the Workday site from `target.com` or from a name such as "Salesforce" (best effort) | Some do names, most need the exact URL |
| Salary range | ✅ Parsed from the description (min, max, currency, hour or year) | Some |
| Dry run (count and price before you pay) | ✅ Free | Rarely |
| Price per 1,000 jobs | **$0.80**, no start fee | About $1 to $3 at the most used ones |

### What you get

One row per job:

```json
{
  "status": "open",
  "company": "NVIDIA",
  "hiringEntity": "2100 NVIDIA USA",
  "tenant": "nvidia",
  "careerSite": "NVIDIAExternalCareerSite",
  "jobId": "Senior-Software-Engineer--AI-Infrastructure_JR2005123",
  "reqId": "JR2005123",
  "title": "Senior Software Engineer, AI Infrastructure",
  "location": "US, CA, Santa Clara",
  "locations": ["US, CA, Santa Clara", "US, WA, Seattle"],
  "locationCount": 2,
  "country": "United States of America",
  "countryCode": "US",
  "remoteType": "Hybrid",
  "timeType": "Full time",
  "postedDate": "2026-10-28",
  "postedOnText": "Posted 3 Days Ago",
  "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-Software-Engineer--AI-Infrastructure_JR2005123",
  "applyUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-Software-Engineer--AI-Infrastructure_JR2005123/apply",
  "descriptionText": "NVIDIA is looking for …\n• Design and build …",
  "salaryMin": 184000,
  "salaryMax": 287500,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "salaryText": "184,000 USD – 287,500 USD",
  "scrapedAt": "2026-10-31T08:00:00Z"
}
```

*(The values are illustrative. The field names and shapes are exactly what the Actor returns.)*

The dataset has ready-made views: **Jobs** (overview), **Details** (with descriptions), **Feed changes** (new and closed) and **Dry run**. A per-site **RUN_SUMMARY** in the key-value store shows how many jobs were listed, saved, new and closed, how a large site was split, and any errors.

### How to use it

1. Add one or more **Career site URLs**, for example `https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`. Any page from the site works: the home page, a search with filters or a single job. You can also paste the company website or careers page (`https://www.target.com`), or type company names under **Company names**.
2. Optional: narrow it down with **Search keywords** or **Posted within N days**, or cap it with **Max jobs per site** (the newest jobs are kept).
3. Run it. To see the job count and price first, turn on **Dry run**, which is free.

#### As a daily "new jobs" feed

1. Turn on **Only new jobs since the last run**.
2. Optional: turn on **First run: just remember current jobs**. The first run is then free and saves nothing, and later runs return only truly new postings.
3. Optional: turn on **Also report closed jobs** to get a free `status: "closed"` row for each job that disappeared.
4. Save it as a task and add a schedule, for example daily at 07:00.

The memory lives in a named key-value store (default `workday-jobs-feed-state`) and is kept per site and per filter combination, so feeds with different keywords don't interfere. Use a different **Feed memory** name for each independent feed.

#### Input example

```json
{
  "startUrls": [
    { "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite" },
    { "url": "https://www.target.com" }
  ],
  "companies": ["Salesforce"],
  "searchText": "data engineer",
  "postedWithinDays": 7,
  "onlyNewJobs": true,
  "reportClosedJobs": true
}
```

### Pricing

Pay per event. You pay only for jobs that are saved to your dataset.

| Event | Price |
|---|---|
| Job saved (`job`) | $0.0008 (= **$0.80 per 1,000 jobs**) |

Free: dry runs, the first-run baseline, `closed` rows, sites that fail or cannot be found, and jobs that close while the run is reading them. In **Only new jobs** mode you pay only for new jobs. If you set a maximum cost per run, the Actor stops cleanly at that limit and never goes over it. If the platform restarts a run, jobs that were already saved are not saved or charged again.

Examples: NVIDIA's whole site (about 2,700 jobs) costs about $2.15. A daily feed that sees 30 new jobs a day across 10 companies costs about $0.72 per month.

### Use it from code

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("vantum/workday-jobs-feed").call(run_input={
    "startUrls": [{"url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"}],
    "onlyNewJobs": True,
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], job["location"], job["applyUrl"])
```

### Tips

- **Full job details** is on by default and costs the same. Turning it off is faster, but you get only the title, location, req ID and URL. Without details, a job open in several places shows `locationCount` instead of a location, and jobs older than 30 days have no exact date.
- A Workday search URL keeps its filters, for example `…/NVIDIAExternalCareerSite?locationHierarchy1=…`. That's the easiest way to get "all jobs in Germany" or "all engineering jobs".
- Company-name lookup tries Workday's data centers and common site names. If a name isn't found, paste the careers URL. It is always faster and exact.
- Big sites (10,000+ jobs) take a few minutes to list. Use **Dry run** to see the size first.

### Limitations

- Workday only. For other job systems (Greenhouse, Lever, SuccessFactors…) use a different Actor.
- Salary is read from the description text. Many postings, especially outside the US, don't state pay, and those fields stay empty instead of being guessed.
- If a site has more than 2,000 jobs in a combination that Workday cannot split any further (very rare), the run warns you in the log and the summary. In that case no jobs are marked closed for that site.
- It reads only public job postings. It does not log in, apply or read anything behind an account.

### FAQ

**Do I need a Workday account or an API key?** No. It reads the same public JSON that the career site's own page loads in your browser.

**Do I need proxies?** No. Workday serves its public job data to everyone. Polite concurrency (8 parallel requests by default) and automatic retries handle rate limits.

**Is `jobId` stable?** Yes. It is Workday's own job path ID and doesn't change while the job is open. Use it as a primary key.

**What happens to a job that's reposted?** Workday usually gives a reposted job a new ID, so the feed reports it as new.

**Why does `postedDate` sometimes differ from "Posted N Days Ago"?** With full details on, `postedDate` is Workday's exact start date. Without details it is calculated from the "Posted N Days Ago" text and is left empty for "30+ Days Ago".

### Open-source components

Python with [HTTPX](https://www.python-httpx.org/) (BSD-3-Clause), [Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/) (MIT), [lxml](https://lxml.de/) (BSD-3-Clause) and the [Apify SDK](https://docs.apify.com/sdk/python/) (Apache-2.0). It uses no third-party data sets. Workday is a trademark of Workday, Inc. This Actor is not affiliated with or endorsed by Workday.

# Actor input Schema

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

Workday career sites, e.g. https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite (also myworkdaysite.com). A search URL with filters (location, category…) keeps those filters. You can also paste a company website or careers page (e.g. https://www.target.com) and the Actor finds its Workday site.

## `companies` (type: `array`):

Optional. Company names such as Salesforce or Amgen. The Actor tries to find their Workday career site automatically (best effort). A URL above is always faster and more reliable.

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

Optional. Workday's own keyword search, e.g. data engineer. Applied to every site.

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

Optional. Only jobs posted in the last N days (0 = today). Leave empty for all open jobs.

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

0 = no limit (every open job). Newest jobs are saved first.

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

Remembers the jobs it has seen per site (in the key-value store named below) and saves only jobs that are new since the previous run. You pay only for new jobs. Ideal for a daily schedule.

## `firstRunBaseline` (type: `boolean`):

With 'Only new jobs': the first run saves nothing and charges nothing. It only remembers today's jobs, so the next runs return truly new postings.

## `reportClosedJobs` (type: `boolean`):

With 'Only new jobs': adds a free row with status 'closed' for each remembered job that is no longer listed.

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

Named key-value store that keeps the seen jobs between runs. Use a different name for each independent feed. Letters, digits and dashes.

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

Opens each job for the full description, exact posting date, all locations, remote type and salary range. Off is faster but gives only title, location, req ID and URL. Same price either way.

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

Adds the original HTML description (descriptionHtml) next to the clean text.

## `dryRun` (type: `boolean`):

Lists every site and reports how many jobs would be saved and the estimated price, without opening jobs, saving them or charging anything. Does not update the feed memory.

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

Requests to Workday at the same time. 8 is fast and polite; lower it if a site rate-limits you.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    }
  ],
  "maxJobsPerSite": 20,
  "onlyNewJobs": false,
  "firstRunBaseline": false,
  "reportClosedJobs": false,
  "stateStoreName": "workday-jobs-feed-state",
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "dryRun": false,
  "maxConcurrency": 8
}
```

# Actor output Schema

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

No description

## `details` (type: `string`):

No description

## `allFields` (type: `string`):

No description

## `summary` (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": [
        {
            "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
        }
    ],
    "maxJobsPerSite": 20
};

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

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

```

## MCP server setup

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