# Workday Jobs Feed: postings from any career site | $1.50/1K (`cleanfeedsapi/workday-jobs-feed`) Actor

Live job openings from Workday career boards via the career site's own CXS jobs JSON (public, paginated). Pass board slugs or paste careers URLs. One row per job: title, location, department, apply URL, dates, stable id. No login, no HTML scrape, no proxies. $1.50 per 1,000 jobs. Also reads Greenhou

- **URL**: https://apify.com/cleanfeedsapi/workday-jobs-feed.md
- **Developed by:** [CleanFeeds API](https://apify.com/cleanfeedsapi) (community)
- **Categories:** Jobs, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 job rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Feed: every posting from any Workday career site | $1.50/1K

**Quick start**

- Workday jobs scraper alternative: one JSON row per open job on every Workday career site you list, with title, location, apply URL and a stable id, read from the site's own JSON instead of its HTML.
- Minimal input: `{"boards": ["workday:adobe.wd5/external_experienced"]}`
- Run it from the Console, the API, or the Apify MCP server; export JSON, CSV or Excel.

Pull live job openings from **Workday** career boards into one clean JSON dataset, read through the career site's own CXS jobs JSON (public, paginated). No HTML scraping, no login, no proxies, no API key.

Pass board slugs (`workday:adobe.wd5/external_experienced`) or **just paste the careers URL** (`<tenant>.<wdN>.myworkdayjobs.com/<site>`). You get one row per job: title, location, apply URL, stable id.

Raw board data, nine normalized fields, no enrichment; cheaper than multi-ATS and enrichment feeds. This Actor accepts only Workday boards (`workday:<slug>` or a pasted Workday URL). Entries for other platforms are returned as one error row each and skipped. For a mixed list across six ATS platforms use [ats-jobs-feed](https://apify.com/cleanfeedsapi/ats-jobs-feed) ($2 per 1,000).

### Why this instead of scraping or the vendor API

- Workday career sites are JavaScript apps. The job list comes from `https://<tenant>.<wdN>.myworkdayjobs.com/wday/cxs/<tenant>/<site>/jobs`, a POST endpoint the page itself calls. This Actor calls it directly and pages through it 20 postings at a time.
- No key, no tenant credentials. The CXS endpoint is public. Workday's REST and SOAP APIs need a customer account and are not needed here.
- Pasted URLs work, including localized ones. `https://<tenant>.<wdN>.myworkdayjobs.com/<site>` and `https://<tenant>.<wdN>.myworkdayjobs.com/en-US/<site>` are turned into `workday:<tenant>.<wdN>/<site>`.
- Same nine-column schema as the other CleanFeeds ATS feeds, so rows from this Actor and ats-jobs-feed fit one table.
- Postings without a title or URL are dropped before charging, so a malformed entry never costs you a row.

### Input example

```json
{"boards": ["workday:adobe.wd5/external_experienced", "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"], "maxJobsPerBoard": 0}
```

| Field | Type | Default | Notes |
|---|---|---|---|
| `boards` | string list | two sample Workday boards | `workday:<tenant>.<wdN>/<site>` or a Workday careers URL |
| `maxJobsPerBoard` | integer | `500` | `0` = everything the endpoint returns (Workday serves at most 2,000 postings per site query; the reader stops when a page repeats) |

### Filters are applied before billing

`postedAfter` (ISO date or `24h` / `7d`), `titleIncludes` (keep if the title contains any term) and `titleExcludes` (drop if it contains any term) are applied to the rows read from the ATS **before** the pay-per-event charge, so you never pay for jobs you filtered out. Matching is case-insensitive substring; there is no fuzzy or AI matching, so what you see is what was matched. Dates come from the ATS itself (`first_published`, `createdAt`, `publishedAt`, `releasedDate`, `published_at`), not from when we indexed the job; Workday only publishes "Posted N Days Ago", so its `posted_at` has day precision and "30+ days ago" postings have no date and are excluded when `postedAfter` is set.

```json
{ "boards": ["greenhouse:stripe", "lever:spotify"], "postedAfter": "24h", "titleIncludes": ["engineer", "developer"], "titleExcludes": ["intern", "staffing"] }
```

### Output example

```json
{ "source": "workday", "company": "adobe.wd5/external_experienced", "title": "Software Engineer", "location": "San Jose, CA",
  "department": null, "url": "https://adobe.wd5.myworkdayjobs.com/external_experienced/job/San-Jose/Software-Engineer_R123456", "posted_at": null, "updated_at": null, "id": "R123456" }
```

| Field | Meaning |
|---|---|
| `source` | always `workday` |
| `company` | the slug you passed |
| `title`, `location` | as the career site reports them (`locationsText`) |
| `department` | always `null` for Workday; the list payload does not carry it |
| `url` | public job page, built from the site origin and the posting's `externalPath` |
| `posted_at`, `updated_at` | `null` for Workday. The list payload only has a relative "Posted 3 days ago" text, which the Actor does not turn into a guessed date |
| `id` | requisition id from the posting's first bullet field (falls back to `externalPath`), stable across runs, diff it to detect new and closed roles |

A board that fails (bad slug, HTTP error) yields one row with `error` and the other boards continue.

### How much does it cost?

Pay per event: **$1.50 per 1,000 job rows** plus Apify's small Actor-start event. Compute is included. Set a maximum charge per run in the Console and the Actor stops at the limit. The Apify free plan is enough to try it on the sample boards.

### Use cases

- **Recruiting SaaS and talent CRMs**: nightly sync of target accounts' Workday boards.
- **Hiring-intent signals**: diff today's `id`s against yesterday's dataset.
- **AI agents and MCP**: "list open roles at these companies" through the Apify MCP server.
- **Market maps**: location mix per company over time.

### Integrations

- **Apify API**: `POST https://api.apify.com/v2/acts/cleanfeedsapi~workday-jobs-feed/run-sync-get-dataset-items?token=<APIFY_TOKEN>` with the input JSON as the body. The response is the dataset, ready to parse.
- **Scheduling**: open the Actor in the Apify Console, click Schedule, pick a cron (for example daily at 06:00) and the saved input runs on its own. Each run keeps its own dataset.
- **n8n, Make, Zapier**: use the Apify integration in each tool, choose this Actor and pass the same input JSON. No per-Actor setup, no custom code.
- **Apify MCP server for AI agents**: connect the Apify MCP server to Claude, Cursor or any MCP client and ask the agent to run `cleanfeedsapi/workday-jobs-feed` with these inputs.

### Related Actors by CleanFeeds

- [ats-jobs-feed](https://apify.com/cleanfeedsapi/ats-jobs-feed): all six ATS platforms in one Actor, same schema.
- [greenhouse-jobs-feed](https://apify.com/cleanfeedsapi/greenhouse-jobs-feed): Greenhouse boards via the official Job Board API.
- [lever-jobs-feed](https://apify.com/cleanfeedsapi/lever-jobs-feed): Lever postings via api.lever.co.
- [ashby-jobs-feed](https://apify.com/cleanfeedsapi/ashby-jobs-feed): Ashby job boards via the posting API.
- [remote-jobs-feed](https://apify.com/cleanfeedsapi/remote-jobs-feed): RemoteOK and Arbeitnow remote listings in one schema.

Free sample dataset: [cleanfeeds/tech-jobs-daily on Hugging Face](https://huggingface.co/datasets/cleanfeeds/tech-jobs-daily). More feeds at [cleanfeeds.dev](https://cleanfeeds.dev).

### FAQ

**Do I need a Workday API key?** No. The endpoint is public and unauthenticated.

**Is this HTML scraping?** No. It reads the career site's own CXS jobs JSON (public, paginated), the same data the careers page itself loads.

**Where do I find the slug?** Take the careers URL `https://adobe.wd5.myworkdayjobs.com/external_experienced`: tenant `adobe`, data center `wd5`, site `external_experienced`, so `workday:adobe.wd5/external_experienced`. Or paste the URL itself.

**Can I mix ATS platforms in one run?** No. This Actor accepts only Workday boards (`workday:<slug>` or a pasted Workday URL). Entries for other platforms are returned as one error row each and skipped. For a mixed list across six ATS platforms use [ats-jobs-feed](https://apify.com/cleanfeedsapi/ats-jobs-feed) ($2 per 1,000).

**Why is `maxJobsPerBoard` 500 by default here?** Large Workday tenants publish thousands of postings and the endpoint returns 20 per request. The default keeps an empty-input run short. Set `0` to read everything the endpoint serves, which is at most 2,000 postings per site: past that offset Workday returns the last page again, so the reader stops when a page repeats. Tenants with more open roles need several runs with different career-site URLs (regional sites) or a search facet, which this Actor does not do.

**How do I detect new and closed items between runs?** `id` is the Workday requisition id (for example `R123456`) and does not change between runs. Keep each run's dataset and compare `id` sets per `company`: ids present today but not yesterday are new roles, ids present yesterday but not today are closed. Schedule the Actor daily and the diff is a few lines in n8n, Make or a script.

**What happens when a source fails?** A site that returns an HTTP error, a slug that does not match `tenant.wdN/site`, or an unrecognized URL does not stop the run. The Actor logs the failure, pushes one row with `source`, `company` and `error` (the message), and continues with the next board. Error rows are not charged. Filter on `error` to find them.

# Actor input Schema

## `boards` (type: `array`):

Workday boards as workday:<slug> or pasted URLs (<tenant>.<wdN>.myworkdayjobs.com/<site>). This Actor accepts only Workday boards; other platforms are returned as one error row each.

## `maxJobsPerBoard` (type: `integer`):

0 = all

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

Keep only jobs published after this point: an ISO date (2026-11-01) or a relative window (24h, 7d). Applied before billing. Jobs without a publish date are excluded when set (Workday gives day precision only; its "30+ days ago" postings have no date).

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

Keep only jobs whose title contains at least one of these terms (case-insensitive substring). Applied before billing.

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

Drop jobs whose title contains any of these terms (case-insensitive substring). Applied before billing.

## Actor input object example

```json
{
  "boards": [
    "workday:adobe.wd5/external_experienced",
    "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"
  ],
  "maxJobsPerBoard": 500
}
```

# Actor output Schema

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

Default dataset with all job rows (source, company, title, location, department, url, posted_at, updated_at, id).

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

Key-value store record SUMMARY: {boards, jobs} counts for the run.

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

// Run the Actor and wait for it to finish
const run = await client.actor("cleanfeedsapi/workday-jobs-feed").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 = { "boards": [
        "workday:adobe.wd5/external_experienced",
        "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
    ] }

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

```

## MCP server setup

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

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/qVnknWoDuPTTGenDb/builds/W8QPpGz39niY9MZwN/openapi.json
