# Workday Jobs — Any Employer's Careers Site, One Schema (`alaudinburki/workday-jobs`) Actor

Read any employer's Workday careers site: title, location, requisition ID, posting date and the full description. One keyless schema across thousands of large employers.

- **URL**: https://apify.com/alaudinburki/workday-jobs.md
- **Developed by:** [alaudin burki](https://apify.com/alaudinburki) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 results

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 — Any Employer's Careers Site, One Schema

Read **any employer's Workday careers site** as flat rows: title, location, requisition ID, posting date
and the full description. One keyless schema across thousands of large employers — NVIDIA, Salesforce
and the rest.

### Why one Actor covers thousands of employers

Workday hosts the careers sites of a large share of big companies, and **every one exposes the same two
JSON endpoints** under `/wday/cxs/`. Only the tenant and the site name change, so the input is the
employer's careers URL and everything else is parsed from it.

```json
{ "employers": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"] }
```

Real run: **2,000 postings** from NVIDIA, **1,563** from Salesforce.

### The two things that break a naive version

**1. The host cannot be guessed.** It is `nvidia.wd5.myworkdayjobs.com` for one employer and
`salesforce.wd12.myworkdayjobs.com` for another — the `wdN` number is not derivable from the name. A
guessed host returns 404 and an empty dataset. This Actor parses tenant, site and host from the URL you
give it, and refuses anything that is not a `myworkdayjobs.com` address with a typed error.

**2. `postedOn` is prose, not a date.** It reads *"Posted Today"*, *"Posted 3 Days Ago"* or
*"Posted 30+ Days Ago"*. Converting that to a timestamp would be a guess, so the raw string is kept and
`postedDaysAgo` is set **only when the prose states an exact number** — *"30+ Days Ago"* is `null`,
because 30 is a lower bound, not the number of days.

### What you get

| Field | Example |
|---|---|
| `employer` | nvidia |
| `title` | Senior Software and System Architect |
| `location` | France, Remote |
| `jobReqId` | JR1997578 |
| `postedOn` | Posted Today |
| `description` | the full posting text, tags stripped |

### Details are optional, and their absence is visible

`includeDetails` fetches the posting page for the description — one extra request per row. If a detail
page fails, **the posting is not lost**: the list row is still emitted with `hasDetails: false` and a
null description. A run that returned nothing because one detail call failed would be the wrong trade.

`descriptionChars` records the full length before the 4,000-character cap, so a truncated row is visible
as truncated rather than looking complete.

### Rate limits

Large employers answer **429** under load. Each request is retried up to three times with backoff; a
429 that survives three attempts fails that employer and is reported in `SUMMARY.problems`, without
taking the other employers down.

### Use cases

- **Job seekers** — every opening at a list of target employers, in one sheet.
- **Recruiters** — a competitor's live requisitions, refreshed on a schedule.
- **Market research** — hiring by team and location, with the posting text.

### Limits

- **20 postings per page** is Workday's own limit; `maxPages` bounds how deep a run goes.
- **Workday only.** Greenhouse (#122), Ashby (#123) and Lever are separate Actors — their APIs differ.
- **Facets are not exposed.** The API supports filtering by location and department; this Actor passes
  only free-text search.
- Descriptions are capped at 4,000 characters; `descriptionChars` shows what was cut.

### Verified

**36 unit tests** — URL parsing including the locale segment and the wdN host, the `30+ Days Ago` rule,
HTML-to-text, the row shape and the request body — plus **26 live checks** across NVIDIA and Salesforce:
both list endpoints, both detail endpoints, description extraction, a bad tenant failing with a typed
error, and pagination actually moving.

***

One row per posting, flat, with the employer's own words preserved.

# Actor input Schema

## `employers` (type: `array`):

Public Workday careers pages, e.g. https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite

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

Filter the employer's postings, e.g. engineer. Leave blank for all.

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

One extra request per posting, and it is where the description comes from. Turn off for a fast title list.

## `maxItems` (type: `integer`):

Hard limit across all employers.

## `maxPages` (type: `integer`):

20 postings per page.

## `timeoutSecs` (type: `integer`):

Per request.

## Actor input object example

```json
{
  "employers": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "includeDetails": true,
  "maxItems": 200,
  "maxPages": 5,
  "timeoutSecs": 25
}
```

# Actor output Schema

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

One row per posting, with the 14 fields listed under Views.

# 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 = {
    "employers": [
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
    ],
    "searchText": "",
    "includeDetails": true,
    "maxItems": 200,
    "maxPages": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("alaudinburki/workday-jobs").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 = {
    "employers": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"],
    "searchText": "",
    "includeDetails": True,
    "maxItems": 200,
    "maxPages": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("alaudinburki/workday-jobs").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 '{
  "employers": [
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "searchText": "",
  "includeDetails": true,
  "maxItems": 200,
  "maxPages": 5
}' |
apify call alaudinburki/workday-jobs --silent --output-dataset

```

## MCP server setup

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

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/YhvUaitWerHAr1JOl/builds/o3w9PbeA4cZwTaqM3/openapi.json
