Workday Jobs API — Every Posting on a Workday Career Site avatar

Workday Jobs API — Every Posting on a Workday Career Site

Pricing

from $0.60 / 1,000 job postings

Go to Apify Store
Workday Jobs API — Every Posting on a Workday Career Site

Workday Jobs API — Every Posting on a Workday Career Site

Every open posting on any Workday career site (*.myworkdayjobs.com) as clean rows: title, requisition id, locations, posted date, time and remote type, country and the full description. Workday's own facets and search, any number of sites. No key, no login, no browser.

Pricing

from $0.60 / 1,000 job postings

Rating

0.0

(0)

Developer

Insight Solutions

Insight Solutions

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Share

Paste any Workday career-site address — anything on *.myworkdayjobs.com, such as https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite, a link to one posting, or just boeing.wd1.myworkdayjobs.com/EXTERNAL_CAREERS — and get one clean row per open posting: title, requisition id, locations, posted date, time type, remote type, country and the full description as text, Markdown or HTML. Filter with Workday's own facets (job category, country, location, time type…) and search box, or with title, location, remote and posted-within-days filters of your own. Any number of sites in one run.

It reads exactly what the career site itself loads in a visitor's browser: Workday's public career-site JSON. No API key, no login, no cookie, no browser. A tenant that only shows its jobs to signed-in users is reported, not worked around.

At a glance

Input — this is the Store prefill; paste it and run:

{ "sites": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite"], "searchText": "", "facets": {},
"listFacets": false, "includeDescription": true, "descriptionFormat": "text", "titleFilter": [],
"titleExclude": [], "locationFilter": [], "remoteOnly": false, "maxJobsPerSite": 20, "maxJobsTotal": 1000,
"maxDetailFetches": 1000, "maxConcurrency": 3, "maxRunSecs": 240, "proxyConfiguration": { "useApifyProxy": true } }

NVIDIA's 20 newest postings with their descriptions — 1 list page and 20 detail documents, about 21 requests.

Output — one job-posting row per posting; the fields you will use most are title, jobId, locations, countryCode, postedAt, timeType, isRemote, descriptionText and url. Then one free site row per site with the total Workday reports. Anything that could not be read — a site id that does not exist, a tenant that refuses anonymous visitors, a facet the site does not have — comes back as a free diagnostic row (ok: false, errorType, error) instead of a charge.

Price — $1 per 1,000 postings (+ $0.001 per run) on the FREE tier, with or without descriptions; site rows, facet rows, diagnostics, filtered-out postings and empty runs free; limited permissions, works over the Apify MCP server (mcp.apify.com) and with x402 agentic payments.

From code — client.actor("insight.solutions/workday-jobs-api").call(run_input={…}) with apify-client, or

POST https://api.apify.com/v2/acts/insight.solutions~workday-jobs-api/run-sync-get-dataset-items
.

Need other ATS platforms too — Greenhouse, Lever, Ashby and the rest? See Career Site Jobs API (insight.solutions/ats-jobs-api), which reads 13 of them, Workday included, in one schema. This Actor does one platform, all the way down: every facet, any number of sites, and descriptions for every posting.


What you get

A job posting as the list page gives it (the prefill's first row, with includeDescription: false; empty columns left out):

{
"ok": true,
"rowType": "job-posting",
"input": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
"scrapedAt": "2026-10-05T12:00:00.000Z",
"source": "nvidia.wd5.myworkdayjobs.com",
"sourceUrl": "https://nvidia.wd5.myworkdayjobs.com/wday/cxs/nvidia/NVIDIAExternalCareerSite/jobs",
"jobId": "JR2026139",
"title": "Senior Technical Program Manager",
"url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-Technical-Program-Manager_JR2026139",
"company": "Nvidia",
"siteName": "NVIDIAExternalCareerSite",
"locationsText": "US, CA, Santa Clara",
"locations": ["US, CA, Santa Clara"],
"city": "Santa Clara",
"region": "CA",
"countryCode": "US",
"postedOn": "Posted Today",
"postedAt": "2026-10-05",
"postedAtPrecision": "derived",
"rank": 1
}

With includeDescription on (the default), each posting's detail document adds — shown here for an NVIDIA posting in the test fixtures:

{
"applyUrl": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-Deep-Learning-Performance-Engineer_JR1998001/apply",
"locations": ["US, CA, Santa Clara", "US, TX, Austin"],
"remoteType": "Hybrid Remote",
"isRemote": false,
"timeType": "Full time",
"postedAt": "2026-09-01",
"postedAtPrecision": "exact",
"descriptionText": "Optimise deep learning kernels across the NVIDIA stack.\n\n- CUDA\n- Profiling",
"sourceUrl": "https://nvidia.wd5.myworkdayjobs.com/wday/cxs/nvidia/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-Deep-Learning-Performance-Engineer_JR1998001"
}

A site row (free, one per site read):

{
"ok": true,
"rowType": "site",
"company": "Nvidia",
"siteName": "NVIDIAExternalCareerSite",
"url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
"totalPostings": 2000,
"returned": 20,
"filteredOut": 0,
"facetNames": ["jobFamilyGroup", "workerSubType", "timeType", "locationHierarchy2", "locationHierarchy1", "locations"]
}

A facet row (free, with listFacets: true) — one per value, so you can filter by it:

{ "ok": true, "rowType": "facet", "company": "Boeing", "siteName": "EXTERNAL_CAREERS",
"facetParameter": "jobFamilyGroup", "facetLabel": "Job Category",
"valueLabel": "Software Engineering (6J)", "valueId": "8b618a30e00f01c7277572e8143f8b25", "count": 94 }

Every row carries every column — null where it does not apply — so the dataset exports as one table.


Quick start

  1. Open the career site you want in a browser and copy the address bar — any page of it.
  2. Paste it into Workday career sites. Add as many as you like.
  3. Run. Each posting arrives as a row; each site adds one free site row with the total Workday reports.

To filter with Workday's own categories, run once with List facets on and Max postings per site at 1. The free facet rows list every category, country and location the site offers, with its id and count. Put the names you want into Facets and run again.


Any Workday address works

You pasteIt reads
https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSitethe site
https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSitethe same site (the locale is skipped)
https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite/job/US-CA-Santa-Clara/Senior-Technical-Program-Manager_JR2026139the whole site that posting is on
nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSitethe same site
workday:nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSitethe same site (Career Site Jobs API's spelling)
https://nvidia.wd5.myworkdayjobs.com/wday/cxs/nvidia/NVIDIAExternalCareerSite/jobsthe same site (the API address itself)

The same site given twice is read once. A query string (?q=…) is ignored — search and filters come from the inputs, so a run means the same thing for every site in it. Anything that is not a Workday career site — another ATS, a company homepage, a host with no site id — comes back as a free invalid-input row and the other sites still run.


Input

FieldDefaultWhat it does
sitesprefill: NVIDIAWorkday career-site addresses (see above).
searchText""Passed to the site's own search box, e.g. engineer.
facets{}Workday's own filters: { "jobFamilyGroup": ["Engineering"], "locationCountry": ["Germany"] }. A facet is named by its facetParameter or its label; a value by its id or name, ignoring case.
listFacetsfalseAlso return a free facet row per facet value of each site.
includeDescriptiontrueFetch each posting's detail document: description, every location, time and remote type, country, exact date.
descriptionFormattexttext → descriptionText, markdown → descriptionMarkdown, html → descriptionHtml (sanitized). The other two stay null.
titleFilter / titleExclude[]Keep / drop postings whose title contains any of these (case-insensitive).
locationFilter[]Keep postings with a location containing any of these, across every location the posting lists.
postedWithinDaysemptyKeep postings posted at most this many days ago.
remoteOnlyfalseKeep remote postings only.
maxJobsPerSite200 (prefill 20)Posting rows per site, 1–10,000; list pages stop once it is reached.
maxJobsTotal1000Posting rows per run, across every site.
maxDetailFetches1000Detail documents per run. Beyond it postings still come back, with descriptionText: null and descriptionTruncatedReason: "maxDetailFetches".
maxConcurrency3Sites read at once (different employers only — see Speed).
maxRunSecs240The run's time budget, 30–3,600 s.
proxyConfiguration{ "useApifyProxy": true }Apify datacenter proxy.

A run with no usable site, unreadable facets, or a postedWithinDays that is not a whole number finishes FAILED before a single request — and costs nothing.


Facets: Workday's own filters

Every Workday site has its own facets, and their ids differ per employer — NVIDIA's "Engineering" is not Adobe's. So the Actor reads each site's first page, looks your names up there, and applies the matching ids:

SiteFacets it offered in the capture
NVIDIAjobFamilyGroup (Job Category, 14), workerSubType, timeType, locationHierarchy2 (Office / Remote), locationHierarchy1 (36 countries), locations (130 sites)
AdobejobFamilyGroup (12), workerSubType, timeType, locationCountry (19), locations (69)
BoeingremoteType (Onsite Job / Hybrid Job), jobFamilyGroup (48), workerSubType, timeType, locationCountry, locations (173), distance
Salesforcea custom CF_-_REC_-_…Country… facet (38 countries), jobFamilyGroup (18), workerSubType, timeType, locations (172)
{ "sites": ["https://boeing.wd1.myworkdayjobs.com/EXTERNAL_CAREERS"],
"facets": { "Job Category": ["Software Engineering (6J)"], "remoteType": ["Hybrid Job"] } }

Several values of one facet mean any of them; several facets mean all of them, as on the career site. A value a site does not list comes back as a free facet-not-found row naming the first 20 values it does list; the facet's other values still apply. A facet with no matching value — or a facet the site does not have at all — skips that site with the same free row, rather than reading it unfiltered and charging for postings you did not ask for.

jobFamilyGroup, timeType and remoteType are also filled from the facets when that is certain: the run filtered on exactly one value, or the site lists only one value and every posting carries it (Boeing: "Full time", 770 of 770).


Output reference

ColumnRowsMeaning
ok, rowType, input, error, errorType, scrapedAt, source, sourceUrlallThe envelope. rowType is job-posting, site, facet or diagnostic; input is the sites entry as you gave it; sourceUrl is the Workday API address the row came from.
jobIdpostingThe requisition id Workday shows on the list (JR2026139), else the detail's jobReqId.
title, url, applyUrlpostingapplyUrl is url + /apply when the detail was read and lists the posting as open.
company, siteNameposting, site, facetThe tenant title-cased (Nvidia) and the site id.
locationsTextpostingThe list's own wording — a place, or a count like 2 Locations.
locationspostingEvery place named, in Workday's wording. A count is never an entry; the detail document supplies the names.
city, region, countryCodepostingBest-effort, from the primary location; the country from the detail when read (ISO alpha-2).
remoteType, isRemotepostingWorkday's label as the employer words it, and true / false / null. Hybrid is not remote.
timeType, jobFamilyGrouppostingSee Facets for when jobFamilyGroup is known.
postedOn, postedAt, postedAtPrecisionpostingSee Posted dates.
descriptionText, descriptionMarkdown, descriptionHtmlpostingOne of them, per descriptionFormat.
descriptionTruncatedReasonpostingWhy a requested description is missing: maxDetailFetches, detail-unavailable or deadline. Null otherwise.
rankposting1-based position on the site, in Workday's order.
totalPostings, returned, filteredOut, facetNamessiteThe total Workday reported for your search and facets, what this run returned and filtered out, and every facet the site offers.
facetParameter, facetLabel, valueId, valueLabel, countfacetOne facet value.

Diagnostic errorTypes: invalid-input, board-not-found (HTTP 404, Workday's S21 "not found"), board-unavailable (HTTP 422 from a tenant that does not answer anonymous visitors, a refusal from two exit IPs, or a 5xx that failed again on its retry), facet-not-found, timeout, deadline and http.


Posted dates

Workday's list says when a posting went up in words — "Posted Today", "Posted 5 Days Ago", "Posted 30+ Days Ago" — and the detail document says it exactly (startDate, 2026-09-01).

  • With the detail read, postedAt is that date and postedAtPrecision is exact.
  • Without it, postedAt is counted back from the run's own date (scrapedAt) and is derived: "Today" is the run's date, "Yesterday" one day back, "5 Days Ago" five. "30+ Days Ago" is 31 days back — a lower bound.

postedWithinDays uses the same numbers ("30+" = 31): a "30+" posting is too old for any window under 31 days, and for a wider one the detail's exact date decides. Without search text Workday lists a site's postings newest first (every capture agrees), so a walk with postedWithinDays stops at the first page that is entirely older.


What you are never charged for

  • Every site and facet row.
  • Every diagnostic row: a site id that does not exist, a tenant that refuses anonymous visitors, a facet the site does not have, a timeout, the deadline.
  • Postings dropped by your filters — filters run before the charge, and most run before the detail document is even fetched.
  • A run that returns nothing at all: it finishes SUCCEEDED with zero results and a "0 results. N diagnostic row(s) explain why. Nothing was charged." status message, and bills nothing, start fee included.

Pricing

EventWhat it isFREEBRONZESILVERGOLD
actor-startOnce per run, only after the run has returned a posting$0.001$0.001$0.001$0.001
job-postingOne posting row, with or without its description$0.001$0.001$0.0008$0.0006

$1 per 1,000 postings (+ $0.001 per run).

RunCost
The prefill — NVIDIA's 20 newest postings with descriptions$0.021
1,000 postings with descriptions: 1,000 × 0.001 + 0.001$1.001
The same at GOLD$0.601
A daily monitor of 5 sites finding ~40 new postings$0.041 a day
A site that does not exist, a tenant that refuses anonymous visitors$0.00

Charging is charge-after-push: rows are in your dataset before the event is recorded. ACTOR_MAX_TOTAL_CHARGE_USD is respected — room for each posting is checked before its detail document is fetched, with the start fee kept in reserve — and when it is reached the run stops fetching, says so in its status message, and finishes SUCCEEDED.


Speed, proxy and politeness

Requests to one Workday host go one at a time, 250–600 ms apart, list pages and detail documents alike; a 403 or 429 is retried once from a fresh proxy session, and a second refusal becomes a free row. So:

  • With descriptions on, one site runs at roughly one posting per 1.2–1.5 s — about 200 postings in the default 240-second budget. For a big site raise maxRunSecs, or switch includeDescription off: the list alone is 20 postings per request.
  • Several different employers run in parallel (maxConcurrency, default 3); two sites on one host share its queue.
  • The default proxy is Apify's datacenter pool: NVIDIA, Adobe, Boeing and Salesforce all answered through it in the capture.

Use it from an AI agent, or from code

One JSON object in, one flat array out — the shape agent runtimes want. The Actor runs with limited permissions, uses pay-per-event pricing and never enters Standby, so it works over the Apify MCP server and with x402 agentic payments. The Integrations tab pushes results to Slack, a webhook, Zapier, Make, Google Sheets, Snowflake or BigQuery.

curl -X POST "https://api.apify.com/v2/acts/insight.solutions~workday-jobs-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"sites":["https://adobe.wd5.myworkdayjobs.com/external_experienced"],"searchText":"engineer","postedWithinDays":7,"maxJobsPerSite":100}'
# pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("insight.solutions/workday-jobs-api").call(run_input={
"sites": [
"https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite",
"https://boeing.wd1.myworkdayjobs.com/EXTERNAL_CAREERS",
],
"facets": {"Job Category": ["Software Engineering (6J)", "Engineering"]},
"maxJobsPerSite": 300,
"maxRunSecs": 900,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row["rowType"] == "job-posting":
print(row["company"], row["jobId"], row["title"], row["countryCode"], row["postedAt"], sep=" | ")

(That run applies NVIDIA's "Engineering" and Boeing's "Software Engineering (6J)": each site applies the names it has, and a free facet-not-found row notes the one it lacks.)


FAQ

How many postings does a site have? The site row's totalPostings is what Workday reports on the first page for your search and facets. Workday appears to cap it: NVIDIA reported 2,000 while its Time Type facet counts add up to 2,700. To reach everything on a very large site, split the run by a facet — one country or job category at a time.

Why do some postings have no description? Either the run's maxDetailFetches was reached, the detail document could not be read (the posting was withdrawn, or Workday refused it), or the time budget ran out — descriptionTruncatedReason says which. The row is still there, and still has everything the list carries.

Why is locations empty and locationsText "3 Locations"? Workday's list gives a count for a posting in several places; the names are only in the detail document. Turn includeDescription on.

Why is jobFamilyGroup null? Workday's list does not say which category a posting is in; the Actor fills it only when the facets make it certain (see Facets). Filter on one category and every row carries it.

Does it sign in, or read internal postings? No. It reads what an anonymous visitor sees, never sends a cookie and never asks for credentials. A tenant that does not serve its jobs anonymously — Walmart's answered HTTP 422 in the capture — comes back as a free board-unavailable row.

Does it remove personal data? A posting is the employer's own publication, but recruiters sometimes sign one with a name and a mailbox. E-mail addresses, mailto: links, recruiter sign-off lines and LinkedIn profile links are removed from every description format before the row is written.

Can I monitor a site for new postings? Schedule a run with postedWithinDays: 1 (or 7) and no search text: the walk stops at the first page that is entirely older, so a daily check of a large site is a few requests.


Limitations

  • Workday's career-site API is undocumented and may change. Every captured tenant answered the same shape, but Workday can change it at any time; a shape the Actor does not recognise comes back as a free http row saying so.
  • 20 postings per list request — Workday's own limit 20 (asking for 50 is an HTTP 400) — and descriptions cost one more request each, one at a time per host. Large sites take time; see Speed.
  • Anonymous access only. Some tenants require a signed-in visitor for their job list and answer HTTP 422; you get a free board-unavailable row.
  • totalPostings appears to be capped by Workday (2,000 on NVIDIA); split very large sites by facet.
  • Only *.myworkdayjobs.com career sites are read; the less common myworkdaysite.com form is not.
  • city, region and countryCode are parsed from Workday's location wording, which each employer chooses; they are a careful guess that never invents a country, and locations always keeps the original text.
  • company is the tenant name title-cased ("Nvidia"), not the legal name.
  • The posting date is exact only when the detail document was read; otherwise it is derived from "Posted N Days Ago", and "30+" is a lower bound.

Not affiliated with Workday, Inc., or with any employer whose postings you retrieve. Workday is a trademark of its owner, used only to describe which public career sites this Actor reads.

Our other Actors

Every Insight Solutions Actor is pay-per-result with no browser, no login and no API key, and every one of them returns free diagnostic rows instead of billing for failures. Prices are per 1,000 results.

Video, audio & social

News, documents & the web

Business, finance & jobs

Apps & games