# Workday Jobs Scraper & API - Career Sites and Descriptions (`s-r/workday-jobs-scraper`) Actor

Export open jobs from any Workday career site (myworkdayjobs.com): requisition ID, title, location, posting date and URL, plus full description, country and time type on request. Several employers per run, for recruiters, sourcing tools and job boards.

- **URL**: https://apify.com/s-r/workday-jobs-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Jobs, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 job postings

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: export job postings from any Workday career site

Workday Jobs Scraper collects public vacancies from Workday career sites (`myworkdayjobs.com`). Supply career URLs, choose a search phrase and set your limits to export job records with requisition IDs, titles, locations and posting dates. Enable details when you need full descriptions, exact dates, hiring entities and working time information.

Workday runs the career pages of a large share of enterprise employers: chip makers, software companies, banks, consultancies, hospitals and public bodies. Each employer has its own board, and none of them offers a combined export. This actor turns those boards into one consistent dataset, so a recruiter, a sourcing tool or a job board reads every employer the same way.

The actor is useful for recruiters comparing openings across employers, sourcing teams following technical roles, and job aggregators building a consistent job feed. It reads the career sites you supply, so each result can be traced back to a public Workday vacancy URL. It does not require an employer account or an applicant login.

### What the Workday Jobs Scraper does

- Reads one or many Workday career sites in a single run, across Workday data centers.
- Uses the career site's own search, so `search: "cuda"` returns what a candidate would see.
- Returns the requisition ID, title, canonical job URL, location and posting date for every job.
- With `include_details`, adds the full description (plain text and HTML), hiring entity, country code, time type, remote label, extra locations and the exact posting date.
- Follows pagination for you and stops cleanly at the source's own limit.
- Exports to JSON, CSV or Excel, or straight into your pipeline through the Apify API.

### Workday Jobs Scraper input

Use `urls` for one or more career sites. The URL must include the Workday data center, tenant and career site. A working example is `https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite`. You can also paste a URL containing a language prefix or an individual job suffix: collection starts from the associated career site. Query parameters in a pasted URL are ignored; use the separate `search` field for your query.

`startUrls` is an alternative input name. It accepts URL strings or objects containing a `url` property. If both names are supplied, `urls` takes precedence. Duplicate tenant and site pairs are collected once, which helps when several pasted links refer to the same employer board.

Set `search` to the phrase that Workday should search for, such as `cuda`. Leave it empty to request all available vacancies within your limits. The search is performed by the career site. Matching behaviour follows Workday rather than an additional filter invented by this actor.

`max_items_per_site` defaults to 100 and accepts values from 1 to 2000. `max_items` defaults to 1000 and limits the combined results across all sites, up to 10000. Employers are collected in your input order. A small total limit may therefore be satisfied before later employers are reached. Use a sufficiently large total if you want openings from every supplied site.

`include_details` defaults to false. With details disabled, the actor returns the fields available on the job cards. Enabling it adds full descriptions and the other detail fields described below. The actor follows continuation pages automatically; ordinary Apify users do not need to manage a cursor.

A run over three employers, five jobs each:

```json
{
  "urls": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    "https://salesforce.wd12.myworkdayjobs.com/wday/cxs/salesforce/External_Career_Site/jobs",
    "https://accenture.wd103.myworkdayjobs.com/wday/cxs/accenture/AccentureCareers/jobs"
  ],
  "max_items_per_site": 5
}
```

### Output and exports

Each dataset row represents one vacancy. The core fields are `source`, `platform`, `fetched_at`, `job_id`, `title`, `url`, `location` and `posted_at`. `job_id` is the requisition identifier displayed by Workday. It is kept as text even when it contains only digits, so spreadsheet software should preserve it without numeric conversion.

The detail option adds `company`, `country_code`, `employment_type`, `description`, `description_html`, `time_type`, `remote_type`, `additional_locations`, `valid_through`, `workday_id` and `can_apply` where supplied by the employer. Missing detail fields remain null. The company label can be a numbered legal hiring entity rather than a familiar brand name; `tenant` and `site` identify the career board separately.

The plain text description retains the complete job description while removing HTML and decoding character entities. The HTML field preserves the source description for applications that need formatting. Locations remain employer-provided text. When a job card says “5 Locations”, enabling details supplies the main location and a list of additional location names.

Without details, posting dates are inferred from phrases such as “Posted Today”, “Posted Yesterday” or “Posted 6 Days Ago”, counted back from `fetched_at` in UTC. A phrase such as “Posted 30+ Days Ago” does not identify an exact day, so its date remains null. With details enabled, `posted_at` uses the exact source date when available and `posted_at_exact` is true. Use that flag when building date-sensitive alerts.

Results are available in the default Apify dataset and can be exported to JSON, CSV or Excel. The OUTPUT record contains run counts and warnings. If an individual detail cannot be retrieved, its real job card is retained and a warning explains the missing enrichment.

#### Example row without details

A real row from the three-employer run above, fetched on 5 October 2026:

```json
{
  "source": "workday-jobs-scraper",
  "platform": "workday",
  "fetched_at": "2026-10-05T20:12:22Z",
  "job_id": "JR2026198",
  "title": "Senior ASIC Timing Engineer",
  "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-ASIC-Timing-Engineer_JR2026198-1",
  "company": null,
  "location": "4 Locations",
  "country_code": null,
  "posted_at": "2026-10-05",
  "employment_type": null,
  "description": null,
  "input_url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
  "tenant": "nvidia",
  "site": "NVIDIAExternalCareerSite",
  "site_total": 2000,
  "locations_count": 4,
  "additional_locations": null,
  "country": null,
  "posted_at_exact": false,
  "posted_on_text": "Posted Today",
  "valid_through": null,
  "time_type": null,
  "remote_type": null,
  "description_html": null,
  "workday_id": null,
  "can_apply": null
}
```

The same run returned Salesforce rows such as `JR362689` “Customer Success Manager- Marketing Cloud” in “Colombia - Bogota” and Accenture rows such as `R00359515` “Google Edge Mid Market Delivery Executive” in “Roma”, all in the same shape.

#### Example row with details

A real row with `include_details: true`, fetched on 5 October 2026. The run also returned `input_url`, `tenant`, `site`, `site_total`, `locations_count`, `posted_on_text`, `source` and `platform` as above. `description` held the full 4,779-character plain text and `description_html` the 6,346-character original; both are left out here for length.

```json
{
  "fetched_at": "2026-10-05T20:12:49Z",
  "job_id": "JR2015832",
  "title": "Senior Software Engineer, Platform Engineering",
  "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-Software-Engineer--Platform-Engineering_JR2015832",
  "company": "2100 NVIDIA USA",
  "location": "US, CA, Santa Clara",
  "country_code": "US",
  "posted_at": "2026-10-05",
  "employment_type": "FULL_TIME",
  "additional_locations": [],
  "country": "United States of America",
  "posted_at_exact": true,
  "valid_through": null,
  "time_type": "Full time",
  "remote_type": null,
  "workday_id": "f5877f187ed5100e646f8e2e2a1e0000",
  "can_apply": true
}
```

### Source limits

Workday caps a single search at 2000 vacancies. A site reporting that total may have more openings than the search exposes. The actor reports the ceiling in warnings and stops before the source starts repeating earlier pages. Narrow your `search` or use separate targeted queries when collecting a large employer.

`employment_type` is derived from working time and is `FULL_TIME`, `PART_TIME` or null. The source does not expose internship or fixed-term classifications reliably on every individual job. Structured salary ranges, inferred cities and employer domains are not supplied. Those limits help keep the dataset tied to values the career site actually provides.

### Use cases for a Workday jobs scraper

- **Recruiters and agencies**: follow the openings of target employers every morning and see new requisitions the day they are posted.
- **Sourcing and talent-intelligence tools**: feed a consistent job posting stream into your matching or alerting product without writing a Workday integration per employer.
- **Job boards and aggregators**: add enterprise employers that publish only on Workday, with stable requisition IDs for deduplication.
- **Sales teams**: treat hiring as a buying signal. A company opening ten data-engineering roles is a lead for data tooling.
- **Labour-market research**: count openings per employer, country or keyword over time, using `posted_at` and `site_total`.

### Using the Workday jobs API

Every Apify actor is also an API. Start a run with a POST to the actor's run endpoint with the input above, then read the dataset as JSON, CSV or Excel. For short runs, the synchronous endpoint returns the dataset items in the same call. Schedules and webhooks let you run the same employer list daily and push new rows to your own system. The official Apify clients for Python and JavaScript wrap the same calls.

### How this compares with other options

| option | what you get | trade-off |
|---|---|---|
| This actor | Any Workday career site you choose, live, with requisition IDs and optional full descriptions | You supply the career URLs |
| Pre-built job databases | Broad coverage across many employers in one feed | You depend on their employer list and refresh cycle |
| The Workday HR platform API | Data from inside your own Workday tenant | Needs tenant credentials; not meant for reading other companies' public postings |
| Your own script | Full control | You maintain pagination, the 2000-result ceiling, detail calls and URL variants yourself |
| Copying from the careers page | No setup | Does not scale beyond a handful of jobs |

For employers on Greenhouse, Lever or Ashby, use [ATS Jobs Scraper](https://apify.com/s-r/ats-jobs-scraper). Both actors return `job_id`, `title`, `url`, `location`, `posted_at`, `employment_type` and `description`, so their datasets combine on company name.

### Pricing

The actor uses a run-start event and a job event for each delivered dataset row. Refer to the Pricing tab for current event amounts before starting a large collection. Descriptions use the same job event as listing-only records; enabling details does not add a separate detail event.

Empty searches produce no job events. The run-start event still applies to an execution. Free-plan users receive at most ten rows per run, including when multiple career sites or the `startUrls` alias are used. Charges follow the rows actually delivered after deduplication and the free-plan cap.

### FAQ

#### Can I collect several employers in one run?

Yes. Supply their Workday career URLs in `urls` and choose both a per-site limit and an appropriate combined limit. Different data centers are supported within the same run.

#### How do I find an employer's Workday career URL?

Open the employer's job board and look at the address bar after clicking “Search jobs” or a single vacancy. A Workday board lives on `<tenant>.wd<N>.myworkdayjobs.com/<site>` or `wd<N>.myworkdaysite.com/recruiting/<tenant>/<site>`. Paste that address; a job link from the same board works too.

#### Can I paste the employer's own careers domain?

Use the final Workday URL instead. Custom employer domains that redirect to a Workday board are outside the supported URL forms. Copy the Workday address from the employer's public job board.

#### Is this the official Workday API?

No. The Workday API is for organisations reading data from their own Workday tenant and requires credentials. This Workday jobs scraper reads the public job postings that any candidate can see on an employer's career site, without a login.

#### Why is a job description or posting date null?

Descriptions require `include_details`. A date inferred from “30+ Days Ago” is unknown, while exact detail dates are marked with `posted_at_exact`. Warnings report details that could not be retrieved.

#### Why do I get at most 2000 jobs from one employer?

That is the limit Workday applies to a single search. Split a large employer into narrower searches, for example by role keyword, and run them as separate inputs.

#### Does a zero-result query create billable job rows?

No. A query without matches returns no dataset jobs and no job events. The run-start event is separate and follows the actor's pricing model.

# Actor input Schema

## `urls` (type: `array`):

Workday career URLs, including the wdN data center, tenant and site. Locale, query and job suffixes are ignored. Duplicate tenant/site pairs are collected once.

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

Alias for urls; accepts URL strings or objects with a url property. urls takes precedence when both are supplied.

## `search` (type: `string`):

Server-side Workday search text, for example cuda. An empty string collects all available jobs.

## `max_items_per_site` (type: `integer`):

Maximum returned jobs per career site across all continuation requests. Workday caps each search at 2,000 jobs.

## `max_items` (type: `integer`):

Maximum returned jobs across all sites and continuation requests. Free users receive at most 10 rows.

## `include_details` (type: `boolean`):

Retrieve full plain text and HTML descriptions, exact dates, company, country, time type and remote type. Missing details are reported in warnings.

## `cursor` (type: `string`):

Opaque next_cursor from a previous response. Repeat the original input unchanged; Apify follows cursors automatically.

## Actor input object example

```json
{
  "urls": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "search": "",
  "max_items_per_site": 100,
  "max_items": 1000,
  "include_details": false
}
```

# Actor output Schema

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

One row per Workday vacancy.

## `output` (type: `string`):

Collected row count, warnings, continuation and actual charges.

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

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

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

```

## MCP server setup

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