# Workday Jobs Scraper (`dataloft/workday-jobs-scraper`) Actor

Scrape every open role from any Workday career site through its official public API. No site ID needed — paste the company website and the board is discovered automatically. Full descriptions, requisition IDs and locations.

- **URL**: https://apify.com/dataloft/workday-jobs-scraper.md
- **Developed by:** [Dataloft Studio](https://apify.com/dataloft) (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 $2.00 / 1,000 job scrapeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Scrape every open role from any Workday career site through Workday's own public API. You do not need the site ID — paste the company website and the scraper finds the board.

### What this scraper does

Workday runs the careers page for a large share of the Fortune 500, and its job data is served by a public JSON API. The awkward part is the URL: every tenant has a site ID like `NVIDIAExternalCareerSite` or `External_Career_Site` that is nowhere on the company's homepage.

This actor removes that problem. Give it `nvidia.com` and it works out the tenant, tries the data centre hosts, probes the known site-ID naming patterns, verifies the board serves jobs, then pulls everything.

### What data you get

| Field | Notes |
|---|---|
| `title`, `company`, `workdayTenant`, `workdaySite` | |
| `id` | the real Workday requisition ID, e.g. `JR2019813` |
| `location`, `locations[]`, `country`, `isRemote` | full location list, not just the summary line |
| `employmentType` | Workday's time type |
| `descriptionHtml`, `descriptionText` | complete posting, both formats |
| `applyUrl`, `jobUrl`, `companyCareerUrl` | |
| `postedAt`, `scrapedAt` | ISO 8601 |

### How to use it

Any of these work in **Workday career sites**:

```
https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite   ← full URL
https://nvidia.wd5.myworkdayjobs.com                            ← site ID discovered for you
nvidia.com                                                      ← company website
```

1. Add one or more of the above.
2. Optionally set **Search term** — it is passed to Workday's own search, so filtering happens on their side and the run is far faster than pulling everything.
3. Add local filters for title, location, keyword, posted-after or remote-only.
4. Run, then export as JSON, CSV or Excel.

#### Input example

```json
{
  "careerSites": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "salesforce.com",
    "cisco.com"
  ],
  "searchText": "software engineer",
  "titleIncludes": ["senior"],
  "locationIncludes": ["remote", "california"],
  "maxTotalJobs": 500
}
```

#### Output example

```json
{
  "id": "JR2019813",
  "title": "ASIC Verification Engineer - GPU",
  "company": "nvidia",
  "workdayTenant": "nvidia",
  "workdaySite": "NVIDIAExternalCareerSite",
  "location": "US, CA, Santa Clara",
  "employmentType": "Full time",
  "isRemote": false,
  "descriptionText": "NVIDIA is seeking elite ASIC Verification Engineers…",
  "applyUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/…",
  "postedAt": "2026-08-24T00:00:00.000Z"
}
```

### Speed

Workday's API returns 20 rows per request and will not return more, however you ask. Rather than walking those pages one at a time, this actor reads the first page to learn the real total and then fetches the rest in parallel — about **4× faster** than sequential paging on a large board.

Full descriptions cost one extra request per posting. Turn **Include full job descriptions** off when you only need an inventory of titles and links.

### How much does it cost to scrape Workday?

You are charged per job saved to your dataset, so postings removed by your filters cost nothing. Use **Max jobs in total** to cap a first run while you check the output.

### Two things worth knowing about Workday

**It reports the total only once.** The first page carries the real count; every page after it reports `0`. A scraper that trusts that field on later pages stops early and quietly returns a fraction of the board. This one takes the total from the first response and holds it.

**Site IDs are not guessable by pattern alone.** They range from `External` to `CISCO_Careers` to `NVIDIAExternalCareerSite`. Discovery tries generic names and tenant-branded variants across every Workday data centre. It resolves most well-known companies; when it cannot, the run tells you which input failed rather than skipping it silently.

### Is it legal to scrape Workday job boards?

This actor calls the same public JSON endpoint your browser calls when you open a company's Workday careers page. It collects **job postings — company information, not personal data**. No candidate data, no logins, no cookies. How you use the output remains your responsibility, including under the relevant terms if you intend to redistribute it.

### Frequently asked questions

**Why did discovery fail for my company?** Either they are not on Workday, or their site ID is fully custom. Open the careers page in a browser, copy the URL, and paste it in — that always works.

**Can I search inside descriptions?** Yes. **Search term** goes to Workday's engine; **Keyword** filters locally against the description text after fetching.

**Do I need a proxy?** Not usually. The option exists for large scheduled runs from a single IP.

**Can I scrape several companies at once?** Yes — add as many career sites as you like. Each is resolved independently, and one failure does not stop the others.

**How do I get only new postings?** Set **Only roles posted after** to your last run date. Workday publishes relative dates ("Posted 3 Days Ago"), which are converted to real timestamps.

### Other job scrapers

- **ATS Jobs Scraper** — 11 ATS platforms including Workday, for mixed target lists.
- **Remote Jobs Aggregator** — 7 remote job boards in one deduplicated feed.

### Feedback

Issues and feature requests go in the Issues tab.

# Actor input Schema

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

Any of these work: the full career-site URL (https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite), the same URL without the site ID (https://nvidia.wd5.myworkdayjobs.com), or simply the company website (nvidia.com). When the site ID is missing the scraper probes the known naming patterns and finds it.

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

Passed to Workday's own search, so the filtering happens server-side and the run is much faster than pulling everything. Example: software engineer.

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

Fetches each posting's full description, requisition ID and exact location. Costs one extra request per job — turn it off for a fast inventory of titles and links.

## `remoteOnly` (type: `boolean`):

Keeps only roles the platform flags as remote, or whose location reads as remote.

## `titleIncludes` (type: `array`):

Case-insensitive. A role is kept if its title contains at least one of these, e.g. engineer, designer, product manager.

## `titleExcludes` (type: `array`):

Case-insensitive. Handy for dropping intern, contractor or director-level postings.

## `locationIncludes` (type: `array`):

Case-insensitive match against every location on the posting, e.g. berlin, united states, remote.

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

Full-text filter against title and description, e.g. kubernetes, rust, series b.

## `postedAfter` (type: `string`):

ISO date such as 2026-08-01. Postings without a date are always kept.

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

Cap on jobs saved per career site. 0 means no limit.

## `maxTotalJobs` (type: `integer`):

Hard stop for the run. 0 means no limit.

## `concurrency` (type: `integer`):

How many boards or sites to work through at once.

## `deduplicate` (type: `boolean`):

Drops the same role when it appears more than once, keyed on the apply URL.

## `proxyConfiguration` (type: `object`):

Optional. These are public APIs, so a proxy is rarely needed — use it only for very large scheduled runs from a single IP.

## `maxScanPerSite` (type: `integer`):

Safety limit that applies only when filters are set. A board with 5,000 postings will not be crawled end-to-end just because you asked for 20 engineers — the scan stops here and the run log tells you it did. Raise it if you need to look deeper.

## Actor input object example

```json
{
  "careerSites": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "salesforce.com"
  ],
  "searchText": "",
  "includeDescription": true,
  "remoteOnly": false,
  "titleIncludes": [],
  "titleExcludes": [],
  "locationIncludes": [],
  "keywords": [],
  "maxJobsPerSite": 0,
  "maxTotalJobs": 150,
  "concurrency": 3,
  "deduplicate": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxScanPerSite": 1000
}
```

# Actor output Schema

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

All scraped Workday job postings in the normalized schema (title, company, location, isRemote, compensation, description, applyUrl, postedAt and more).

# 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",
        "salesforce.com"
    ],
    "maxTotalJobs": 150
};

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

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

```

## MCP server setup

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