# Workday Careers URL Finder + Jobs API (`blooming_gator/workday-jobs-api`) Actor

Job postings direct from company career sites on Workday. Verified directory of 1,251 live boards - never guess a slug. Completeness checked against Workday's own published job count and reported per board, so you know if you got all of it.

- **URL**: https://apify.com/blooming\_gator/workday-jobs-api.md
- **Developed by:** [Kaleb Confer](https://apify.com/blooming_gator) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 verified 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?

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 Careers URL Finder + Jobs API

Job postings pulled straight from company career sites running **Workday**, with a
verified directory of **1,251 Workday boards** included so you never have to guess
a company's board slug.

Workday publishes a `total` alongside every page, so completeness here is checked against the vendor's own number rather than asserted. Where that number is Workday's 2,000 cap rather than a real count, this Actor reports the board unverified instead of claiming a completeness it cannot prove.

### Why this exists

Most job data on the market is scraped from aggregators, where postings are
reposted, stale, or routed through a third-party apply flow. These come from the
employer's own Workday board: one hop from the hiring team, with the employer's
real apply URL.

### Completeness is checked, not claimed

Workday publishes a job count alongside its results. This Actor compares that number
against the rows it actually returned, per board, and reports the outcome. When
they disagree, the run says so.

### What you get

| Field | Meaning |
|---|---|
| `company` | Employer name |
| `title` | Role title |
| `location` | Location as the employer wrote it |
| `department` | Team or department, when the board exposes one |
| `url` | Direct apply URL on the employer's board |
| `updated` | Posting or last-updated timestamp from the vendor |
| `board_token` | The Workday board identifier, reusable in later runs |
| `job_id` | Vendor's own job id |
| `verified_complete` | `true`, `false`, or `null` - see below |

Every run also writes a `PROVENANCE` record to the key-value store: per board, how
many postings were fetched, what count the vendor published, and whether the two
matched.

### `verified_complete` is three-valued on purpose

- `true` - the vendor published a count and our row count matched it.
- `false` - the vendor published a count and we did **not** match it. Something is
  wrong; the run tells you rather than hiding it.
- `null` - the vendor publishes no count. Honestly unknown.

Most job scrapers report only what they found. That is indistinguishable from a
board that half-failed. A silent partial result is worse than an error, because
you build on it.

### Input

| Option | What it does |
|---|---|
| `companies` | Company names. Resolved against the verified directory first, then live. |
| `boards` | Exact Workday board tokens, if you already know them. |
| `listKnownBoards` | Return the whole verified directory of 1,251 boards instead of jobs. Free. |
| `allBoards` | Sweep directory boards when no company is given. |
| `keyword` | Case-insensitive filter on job title. |
| `maxBoards` | Cap boards per run (default 5). |
| `maxResults` | Cap rows returned. |

#### Start here

Set `listKnownBoards` to `true`. You get every Workday board we have confirmed live,
and can pick the companies you care about from real tokens instead of guessing.
That run is free: the paid event is a delivered job posting, and a directory row
is not one.

The same directory is browsable on the web, no signup and nothing to run:
https://kalebconfer-sys.github.io/job-board-directory/workday.html

### Pricing

Pay per unique role delivered. Duplicates removed before delivery are not
charged, a failed board is not charged, and listing the directory is free.

### Platform notes

A Workday board is the hardest URL to guess on the whole market and the reason this directory exists. The address is three independent parts - the numbered host, the tenant slug and the career-site path - and none is derivable from a company name: Target is wd5/target/targetcareers, Salesforce is wd12/salesforce/External\_Career\_Site. Guess any part wrong and Workday answers 500 or 502, so a bad guess looks like an outage rather than a missing board. This Actor ships 1,251 tenant addresses that were each confirmed live, advertising 458,588 roles between them. Two limits are Workday's own and are reported, not hidden: pages hold 20 results, and no tenant can be read past offset 10,000, so the two tenants above that ceiling - CVS Health and Lowe's - cannot be delivered whole by anyone.

### Where the directory comes from

Board tokens are harvested from public web crawl archives, then **every one is
re-checked against Workday's own public API before it ships**. A token that was seen
once but no longer resolves does not make it in. Guessing company slugs instead
was measured at a 0.77% hit rate; this approach measured about 67%.

To be exact about what the directory is: a board qualifies when it resolved **and
had at least one open role** at validation time. A real board that happened to be
empty that day is not in here. So treat the count as a floor, not a census.

### Legal

This Actor reads Workday's documented public job board endpoints - the same data any
visitor sees without logging in. No login, no cookies, no terms accepted, no
paywall or access control circumvented. Job postings are published by employers
specifically to be seen.

### Limits

- Coverage is the directory plus anything you name explicitly; it is not every
  Workday board in existence, and this README says so rather than implying totals.
- `updated` is passed through from the vendor and means slightly different things
  on different platforms.
- Rate limits are the vendor's, not ours. Errors are reported per board.

# Actor input Schema

## `companies` (type: `array`):

Company names to look up on Workday. Matched against the verified directory first.

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

Exact board tokens, if you already know them.

## `listKnownBoards` (type: `boolean`):

Ignore everything else and return all 1,251 confirmed-live Workday boards.

## `allBoards` (type: `boolean`):

If no company is given, pull jobs from the directory up to Max boards.

## `keyword` (type: `string`):

Case-insensitive substring match on job title.

## `maxBoards` (type: `integer`):

How many boards to pull in one run. Keeps a run bounded and predictable in cost. A Workday tenant holds up to 2,000 roles, so this default is deliberately small: the general default of 25 would bill an exploratory run about $250.

## `maxResults` (type: `integer`):

Capped at 500 by default here, because Workday boards are large enough that an uncapped first run is a surprise bill. Set 0 for no cap.

## Actor input object example

```json
{
  "companies": [],
  "boards": [],
  "listKnownBoards": false,
  "allBoards": false,
  "maxBoards": 5,
  "maxResults": 500
}
```

# Actor output Schema

## `roles` (type: `string`):

One row per unique role.

## `provenance` (type: `string`):

Per board: fetched, vendor count, match.

# 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 = {
    "companies": [],
    "boards": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("blooming_gator/workday-jobs-api").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 = {
    "companies": [],
    "boards": [],
}

# Run the Actor and wait for it to finish
run = client.actor("blooming_gator/workday-jobs-api").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 '{
  "companies": [],
  "boards": []
}' |
apify call blooming_gator/workday-jobs-api --silent --output-dataset

```

## MCP server setup

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

```

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/uAYqyzI1Vcz2ImFPt/builds/dBWbeHtRWCjXi9gez/openapi.json
