# Workday Jobs Scraper: Enterprise Career Sites (`arman-bd/workday-jobs-scraper`) Actor

Scrape any Workday-powered careers site through its public CxS endpoint. title, location, posted date, requisition ID and apply URL. No login, no proxy, no browser.

- **URL**: https://apify.com/arman-bd/workday-jobs-scraper.md
- **Developed by:** [Arman Hossain](https://apify.com/arman-bd) (community)
- **Categories:** Jobs, Lead generation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 job scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## Workday Jobs Scraper: Enterprise Career Sites

![Workday Jobs: Enterprise requisitions from any Workday tenant, paged in full](https://api.apify.com/v2/key-value-stores/ZQOcNAOHrIgTacAmy/records/workday-jobs-scraper.jpg)

**Workday Jobs Scraper** pulls every open requisition from any **Workday**-powered careers site through the public **CxS** endpoint, title, location, posted date, requisition ID, apply URL and, optionally, the full plain-text description.

Most of the Fortune 500 runs hiring on Workday, and every careers site is backed by a JSON search API that the site's own front end calls. This Actor calls it directly: **no browser, no proxies, no login, no rate-limit games.**

**Agent skill: [SKILL.md](https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/workday-jobs-scraper.md)**

```
https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/workday-jobs-scraper.md
```

### What you get

| Output field | Meaning |
|---|---|
| `tenant`, `site` | The Workday tenant and job-posting site ID parsed from the careers URL |
| `company` | The tenant slug, Workday's list endpoint publishes no separate display name |
| `jobId` | The posting-ID slug (`Senior-Engineer_JR2018715`), stable across runs |
| `title` | Job title |
| `locationsText` | Location as Workday renders it, a place name, or `"3 Locations"` for multi-site reqs |
| `location` | Resolved primary location (only with `includeJobDetails`) |
| `postedOn` | Workday's relative posting label, e.g. `"Posted 14 Days Ago"` |
| `postedDate`, `timeType`, `remoteType` | Exact posting date, Full time/Part time, and remote type (only with `includeJobDetails`) |
| `requisitionId` | The company's requisition number, e.g. `JR2018715` |
| `externalPath`, `applyUrl` | Workday's internal path and the public apply link |
| `description` | Full description as clean plain text (only with `includeJobDetails`) |
| `scrapedAt` | Run timestamp |

A `RUN_SUMMARY` record in the key-value store holds per-run counts, the filters used, unparseable inputs and any site that failed.

### Common use cases

- **Track Fortune-500 hiring at scale.** A single run snapshots thousands of enterprise requisitions.
- **Monitor layoffs and backfills.** Diff requisition IDs week over week to see what disappears and what reopens.
- **Feed executive-search pipelines.** Filter on title keywords and location to build a live target list.
- **Competitive intelligence.** Measure which functions and geographies a competitor is investing in.
- **Job aggregators.** Ingest hundreds of enterprise careers sites on a schedule.

### Quick start

Two enterprise sites, first 200 roles each:

```json
{
 "careerSites": [
 "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
 "https://adobe.wd5.myworkdayjobs.com/external_experienced"
 ]
}
```

Engineering roles in Europe, with full descriptions:

```json
{
 "careerSites": ["https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"],
 "searchText": "software engineer",
 "locationFilter": ["ireland", "united kingdom", "germany"],
 "maxJobsPerSite": 100,
 "includeJobDetails": true
}
```

Fast, lightweight sweep for change detection:

```json
{
 "careerSites": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"],
 "maxJobsPerSite": 0,
 "includeJobDetails": false
}
```

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `careerSites` | array | - | **Required.** Workday careers URLs. Locale segments (`/en-US/`) and full CxS API URLs are both accepted and normalised. |
| `searchText` | string | `""` | Keyword handed to Workday's own search. Server-side, so it also cuts the number of pages fetched. |
| `locationFilter` | array | `[]` | Keep only jobs whose location text contains one of these terms. Applied after fetching. Empty = all. |
| `maxJobsPerSite` | integer | `200` | Stop paginating at this many jobs per site. `0` = every job the site returns. |
| `includeJobDetails` | boolean | `false` | Fetch each job's CxS record for description, exact posted date, time type and remote type. One extra request per job. |

`searchText` narrows on the server and `locationFilter` narrows afterwards, so combining them is the cheapest way to reach a specific slice. `includeJobDetails` with `maxJobsPerSite: 0` on a 2,000-role tenant means 2,100 requests, set a cap first.

### Finding the careers URL

Open the company's careers site and copy the URL from the address bar. Everything the Actor needs is in it:

```
https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite
 ^tenant ^datacentre ^site ID
```

The **datacentre** segment (`wd1`, `wd3`, `wd5`, `wd12` …) is assigned per tenant by Workday. It cannot be guessed and it is not always `wd5`, always take it from the real URL. Likewise the **site ID** is chosen by the employer (`NVIDIAExternalCareerSite`, `external_experienced`, `External_Career_Site`), so it must be copied, not invented. A wrong site ID returns a clear `not found: Job_Posting_Site_ID` error, which lands in `RUN_SUMMARY.failures`.

### Output example

```json
{
 "tenant": "nvidia",
 "site": "NVIDIAExternalCareerSite",
 "company": "nvidia",
 "jobId": "Director--Engineering---Software-Engineering_JR2021061",
 "title": "Director, Engineering, Software Engineering",
 "locationsText": "2 Locations",
 "location": "Vietnam, Hanoi",
 "postedOn": "Posted 27 Days Ago",
 "postedDate": "2026-07-10",
 "timeType": "Full time",
 "requisitionId": "JR2021061",
 "externalPath": "/job/Vietnam-Hanoi/Director--Engineering---Software-Engineering_JR2021061",
 "applyUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/Vietnam-Hanoi/Director--Engineering---Software-Engineering_JR2021061",
 "description": "NVIDIA is widely recognized as one of the world's most desirable employers …",
 "scrapedAt": "2026-08-06T12:00:00.000Z"
}
```

### API example

```bash
curl -X POST "https://api.apify.com/v2/acts/arman-bd~workday-jobs-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
 "careerSites": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"],
 "searchText": "engineer",
 "maxJobsPerSite": 25
 }'
```

### JavaScript example

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('arman-bd/workday-jobs-scraper').call({
 careerSites: ['https://adobe.wd5.myworkdayjobs.com/external_experienced'],
 searchText: 'engineer',
 locationFilter: ['san jose'],
 maxJobsPerSite: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const job of items) console.log(`${job.title}, ${job.locationsText} (${job.requisitionId})`);
```

### Notes

- **Bad sites don't kill the run.** A wrong tenant, datacentre or site ID is recorded in `RUN_SUMMARY.failures`; the Actor only errors out if *every* site fails. Entries that cannot be parsed at all are listed under `unparseableInputs`.
- **Pagination is fixed at 20.** Workday rejects any `limit` above 20 with HTTP 400, so paging uses `offset` in steps of 20 and stops at your cap, at the reported total, or on a short page.
- **`total` is only read once.** Deep into the offset range Workday starts reporting `total: 0` while still returning rows, so the count from the first page is the one that is trusted.
- **Transient errors are retried.** 429 and 5xx get three attempts with exponential backoff; 404 and 400 fail fast because retrying a wrong site ID never helps.
- **A failed detail fetch costs one field, not one job.** With `includeJobDetails` on, a job page that errors is logged and the row is still saved from the listing data.
- **Descriptions are decoded twice.** Recruiters paste already-encoded markup into Workday, so entities are decoded before tags are stripped and again afterwards. You get real text, not `&lt;p&gt;`.
- **Public data only.** No authentication, no personal data, no access-control bypass.

### FAQ

**Do I need a Workday API key?** No. You supply no credentials.

**Do I need a proxy?** No. Proxy configuration is not required to run this Actor.

**Why is there no job family or department?** Workday's CxS API does not publish one per posting. It exposes a "Job Category" *facet* for filtering, but no per-job value on either the list or the detail record, so this Actor does not invent one. `timeType` and `remoteType` (with `includeJobDetails`) are the classification fields Workday actually returns.

**Why does `locationsText` say "3 Locations"?** That is Workday's own rendering for a requisition open at several sites. Turn on `includeJobDetails` to also get the resolved primary `location`.

**Does it include salary?** Only if the employer writes it into the description. Workday's public endpoint has no structured salary field.

**How many jobs can one site return?** As many as it publishes, pagination continues until your cap or the end of the list. Large tenants advertise 2,000+, so set `maxJobsPerSite` unless you really want all of them.

**Can I get only new or changed jobs?** Run on a schedule and diff on `requisitionId`. Leaving `includeJobDetails` off makes those sweeps roughly 20× cheaper.

**Can I integrate it with something else?** Yes, Apify API, client libraries, webhooks, scheduled runs, dataset exports (JSON/CSV/Excel) or MCP. Output is structured JSON.

# Actor input Schema

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

Workday careers URLs, e.g. https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite. The datacentre segment (wd1, wd5, wd12 …) is assigned per company and must come from the real URL. it cannot be guessed. Locale segments such as /en-US/ are stripped automatically.

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

Keyword passed to Workday's own search before results are returned. Server-side, so it also shrinks the number of pages fetched. Leave empty for every open role.

## `locationFilter` (type: `array`):

Keep only jobs whose location text contains at least one of these terms (case-insensitive). Applied after fetching. Leave empty for all locations.

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

Stop paginating once this many jobs have been fetched from a site. Set 0 for every job the site returns. Large enterprise tenants publish thousands of roles, so a cap keeps runs short.

## `includeJobDetails` (type: `boolean`):

Fetch the per-job CxS record to add the full description, the exact posted date, time type and remote type. Costs one extra request per job. leave off for fast listing-only sweeps.

## Actor input object example

```json
{
  "careerSites": [
    "https://salesforce.wd12.myworkdayjobs.com/External_Career_Site"
  ],
  "searchText": "software engineer",
  "locationFilter": [
    "remote",
    "london"
  ],
  "maxJobsPerSite": 200,
  "includeJobDetails": false
}
```

# Actor output Schema

## `items` (type: `string`):

Every record the run produced.

## `runsummary` (type: `string`):

The RUN\_SUMMARY record from the run's key-value store.

# 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",
        "https://adobe.wd5.myworkdayjobs.com/external_experienced"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("arman-bd/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",
        "https://adobe.wd5.myworkdayjobs.com/external_experienced",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("arman-bd/workday-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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",
    "https://adobe.wd5.myworkdayjobs.com/external_experienced"
  ]
}' |
apify call arman-bd/workday-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=arman-bd/workday-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/RjiLhhaE9SE4KEadT/builds/4NA1U6wOaCph2Ta1I/openapi.json
