# Workday Jobs Extractor (`jakob_jerich/workday-jobs-extractor`) Actor

Extract all job postings from any Workday career site (myworkdayjobs.com): title, locations, parsed salary range, posting date, remote type and full description. Gets past the 2,000-result cap. New-jobs-only monitoring mode. $1 per 1,000 jobs.

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

## Pricing

$1.00 / 1,000 job extracteds

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 Extractor

Extract **every job posting from any Workday career site** (`*.myworkdayjobs.com` and `*.myworkdaysite.com`) as clean, structured data: title, location(s), country, remote type, time type, exact posting date, **parsed salary range** and full description.

Paste one or more career-site URLs and get the jobs. No login, cookies or proxies are needed: the Actor reads the same public JSON that the career site loads in your browser.

### Why this Workday scraper

- **Gets all jobs from big employers.** Workday caps a search at 2,000 results. Past that it quietly repeats the first page, so simple scrapers return at most 2,000 jobs (with duplicates). This Actor detects the cap and splits the search by Workday's own filters (job family, worker type, country, …), then de-duplicates. In our tests NVIDIA returned **2,688 unique jobs** where a naive scraper stops at 2,000.
- **Monitoring mode: pay only for new jobs.** Turn on *Only new jobs* and schedule the Actor. Each run returns, and charges for, only postings that weren't returned before.
- **Salary ranges parsed into numbers.** `salaryMin`, `salaryMax`, `salaryCurrency` and `salaryPeriod` are pulled from pay-transparency text such as "184,000 USD - 287,500 USD" or "$45.00 - $60.00 per hour".
- **Filtered URLs work.** Filter the job list on the career site (location, category, …), copy the URL, and the same filters are applied.
- **Many companies in one run**, each with its own status in the run summary. One broken URL doesn't fail the run.
- **Low, simple pricing:** $1 per 1,000 jobs, with no start fee.
- **No personal data.** Recruiter and contact fields are never output, and e-mail addresses are removed from descriptions.

### How to use it

1. Find the company's Workday career site. Its URL looks like `https://<company>.wd5.myworkdayjobs.com/<SiteName>`. Search the web for "<company> myworkdayjobs" if you're unsure.
2. Paste one or more URLs into **Workday career-site URLs**.
3. Optionally add **Search keywords**, a **Posted within (days)** filter or a **Max jobs per site** limit.
4. Click **Start**. Download the results as JSON, CSV, Excel or HTML, or use the API.

#### Example input

```json
{
  "startUrls": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
  ],
  "searchQuery": "data",
  "maxJobsPerSite": 200,
  "postedWithinDays": 7,
  "includeDetails": true,
  "descriptionFormat": "text",
  "onlyNewJobs": false
}
```

| Field | What it does |
|---|---|
| `startUrls` | Workday career-site URLs. Locale prefixes (`/en-US/`) and filter query strings are handled. |
| `searchQuery` | Keywords, searched with Workday's own search. |
| `maxJobsPerSite` | Limit per site (default 100). `0` = all jobs. |
| `postedWithinDays` | Only jobs posted in the last N days. |
| `includeDetails` | `true` (default) opens each job for description, salary, exact date, country, remote type. `false` returns a fast list (title, location, URL, posted label). |
| `descriptionFormat` | `text`, `html` or `both`. |
| `onlyNewJobs` | Monitoring mode: return only jobs not returned by earlier runs with the same settings. |
| `monitorName` | Keeps separate "already seen" memories for different schedules. |
| `maxConcurrency` | Parallel job-page requests (default 8). |

#### Example output

```json
{
  "jobId": "JR2019886",
  "title": "Principal Data Scientist - Cloud Gaming and AI",
  "tenant": "nvidia",
  "careerSite": "NVIDIAExternalCareerSite",
  "legalEntity": "2100 NVIDIA USA",
  "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Principal-Data-Scientist---Cloud-Gaming-and-AI_JR2019886",
  "applyUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Principal-Data-Scientist---Cloud-Gaming-and-AI_JR2019886/apply",
  "location": "US, CA, Santa Clara",
  "additionalLocations": [
    "US, CA, Remote"
  ],
  "locationsCount": 2,
  "country": "United States of America",
  "remoteType": null,
  "timeType": "Full time",
  "postedOnText": "Posted Yesterday",
  "postedDaysAgo": 1,
  "postedDate": "2026-10-30",
  "salaryMin": 248000,
  "salaryMax": 379500,
  "salaryCurrency": "USD",
  "salaryPeriod": "YEAR",
  "salaryText": "248,000 USD – 379,500 USD",
  "descriptionText": "Join the NVIDIA GeForce NOW cloud team that allows users to play high-quality PC games on various devices, without the need for a dedicated gaming PC or console ...",
  "descriptionHtml": null,
  "workdayJobId": "d0c8efdd0c14101432f6cd1308d50000",
  "jobPostingId": "Principal-Data-Scientist---Cloud-Gaming-and-AI_JR2019886",
  "searchQuery": "data",
  "sourceUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
  "scrapedAt": "2026-10-31T23:16:02+00:00"
}
```

Every item has the same fields. A field is `null` when the site doesn't provide it, or when *Include full job details* is off. A run summary (jobs per site, errors, whether the 2,000 cap was split) is saved as `OUTPUT` in the run's key-value store.

### Pricing

Pay per event: **$0.001 per job returned** ($1 per 1,000 jobs). There is no start fee, and you don't pay for jobs that monitoring mode skips. You can set a maximum cost per run in Apify; the Actor stops cleanly when that limit is reached.

### Use cases

- **Job boards and aggregators:** feed Fortune 500 openings into your site.
- **Recruiting and sales intelligence:** see which companies are hiring, for which roles, where.
- **Salary benchmarking:** collect pay ranges from pay-transparency postings.
- **Labor-market research:** track hiring trends by company, function or country.
- **Job alerts:** schedule daily runs with *Only new jobs* and send the results to Slack, e-mail or a webhook through Apify integrations.

### FAQ

**Which companies are supported?**
Any employer with a public Workday career site (`myworkdayjobs.com` or `myworkdaysite.com`). Thousands of large companies use Workday, for example NVIDIA, Salesforce, Adobe, Intel and many banks, hospitals and universities.

**How do I find a company's Workday URL?**
Open the company's careers page and click through to its job list. If the address contains `myworkdayjobs.com`, copy it. Searching the web for "company myworkdayjobs" also works.

**Why do I get fewer jobs than the career site shows?**
Check *Max jobs per site* (default 100; set 0 for all) and the *Posted within* filter. For very large sites, the run log says if a search could not be split fully under Workday's 2,000-result cap.

**How does "Only new jobs" work?**
The Actor remembers the jobs it returned for the same combination of URL, keywords, filters and monitor name, in a named key-value store in your Apify account. Later runs skip those jobs.

**Is the salary always available?**
Only when the employer publishes it in the description, which is common for US, Canadian and some EU postings. The parser handles ranges with currency symbols or codes and hourly, monthly or yearly periods. The original snippet is kept in `salaryText` so you can check it.

**Is it legal?**
The Actor reads only public job postings that the company publishes for everyone, through the career site's public endpoints, at a polite rate. It collects no personal data. Make sure your use of the data complies with the laws and terms that apply to you.

### Limits

- Workday's own search and filters are used. Keyword matching is done by Workday, not by this Actor.
- Workday shows posting age as "Posted N Days Ago" in the list. Jobs older than 30 days appear as "30+ Days Ago". With details on, `postedDate` uses the exact posting date Workday provides.
- Sites that require login, or that block automated access, are skipped with a clear message.
- Internal or employee-only career sites are not supported.

# Actor input Schema

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

One or more public Workday career-site URLs, for example https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite or https://wd3.myworkdaysite.com/recruiting/company/Careers. Filtered URLs work too: filter the job list on the career site, then copy the browser URL and the filters (location, job category, ...) are applied.

## `searchQuery` (type: `string`):

Optional keywords, searched with Workday's own search on every site (for example "data engineer"). Leave empty to get all jobs.

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

Maximum number of jobs to return per career site. Set 0 for no limit (all jobs; large employers can have several thousand).

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

Optional. Only return jobs posted within this many days (based on Workday's "Posted N Days Ago" label; Workday shows older jobs as "30+ Days Ago", which counts as 31). Leave empty for all.

## `includeDetails` (type: `boolean`):

Open each job to get the full description, salary range, exact posting date, country, remote type, time type and all locations. Turn off for a fast list of titles, locations and URLs only.

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

Format of the job description: clean plain text, the original HTML, or both.

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

Return only jobs that previous runs with the same URLs, keywords and monitor name have not returned yet. Ideal for scheduled runs: you only pay for new postings. The first run returns everything (up to the max).

## `monitorName` (type: `string`):

Optional label that keeps the "only new jobs" memory separate, e.g. when two schedules watch the same site for different purposes.

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

How many job pages to load in parallel. The default is fast and polite; lower it if a site responds with errors.

## Actor input object example

```json
{
  "startUrls": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
  ],
  "searchQuery": "engineer",
  "maxJobsPerSite": 20,
  "includeDetails": true,
  "descriptionFormat": "text",
  "onlyNewJobs": false,
  "maxConcurrency": 8
}
```

# Actor output Schema

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

All extracted job postings (dataset items).

## `summary` (type: `string`):

Jobs per career site, errors and facet-split info.

# 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://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    ],
    "searchQuery": "engineer",
    "maxJobsPerSite": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("jakob_jerich/workday-jobs-extractor").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://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"],
    "searchQuery": "engineer",
    "maxJobsPerSite": 20,
}

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

```

## MCP server setup

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

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/qscFCdQ63SdtEF2BU/builds/OTEhHOYpJo90UyUqs/openapi.json
