">
 

Workday's job API tells you there are 2,000 jobs, then says 0 on page two

Iniciado por joomlamz, Hoje at 14:25

Respostas: 0   |   Visualizações: 1

Tópico anterior - Tópico seguinte

0 Membros e 1 Visitante estão a ver este tópico.

Workday's job API tells you there are 2,000 jobs, then says 0 on page two



Tópico: Workday's job API tells you there are 2,000 jobs, then says 0 on page two
Categoria: Tutoriais | Programação & Tecnologia
Idioma Principal: Português (Conteúdo de Tecnologia)

Descrição do Conteúdo / Informações:
-------------------------------------------------------------------------
Workday is where large enterprises actually post. NVIDIA has 2,000 open roles

there, Salesforce 1,477, Adobe 832. It answers an anonymous POST with no key.

It also has two behaviours that are not in any documentation you can read

without an account, and both of them fail silently. One of them costs you 98%

of the board without raising anything.



The number that changes after page one


Ask for the first twenty postings and the response carries a total:

POST /wday/cxs/nvidia/NVIDIAExternalCareerSite/jobs
{"appliedFacets":{}, "limit":20, "offset":0, "searchText":""}

20 jobPostings,  total: 2000

Ask for the next twenty and the count is gone:

offset 20   ->  20 jobPostings,  total: 0
offset 40   ->  20 jobPostings,  total: 0

Not null, not absent. Zero. The postings keep coming; only the count collapses.

Measured on four enterprise tenants:

tenant
total at offset 0
at offset 20
at offset 40

NVIDIA
2000
0
0

Salesforce
1477
0
0

Adobe
832
0
0

Sony
94
0
0

Same shape every time, so this is Workday and not one tenant's configuration.



Why that costs you 98% of the board


Here is the loop everyone writes, and it is not a bad loop:

offset, out = 0, []
while True:
page = fetch(offset)
posts = page["jobPostings"]
if not posts:
break
out += posts
offset += len(posts)
if offset >= page["total"]:      # looks obviously right
break

On page two page["total"] is 0, and 20 >= 0 is true. The loop exits,

reports no error, and hands back what it has.

I ran both versions against NVIDIA:

declared total on page one              2000
the obvious loop collected                40      2%
keeping the first total instead         2000    100%

Forty postings out of two thousand, and nothing anywhere says so. No exception,

no warning, no partial-result flag. Just a job board that looks very quiet.

The fix is one line moved:

offset, out, total = 0, [], None
while True:
page = fetch(offset)
posts = page["jobPostings"]
if not posts:
break
out += posts
offset += len(posts)
if total is None:                # the first answer is the only honest one
total = page.get("total") or 0
if total and offset >= total:
break

Two changes that matter. Keep the first total. And guard on total being

truthy, so a board that never reports a usable count still runs to the empty

page instead of stopping immediately.



The page size is capped at 20, and 21 is a 400


The other undocumented one. limit is not a suggestion:

limit=20  ->  HTTP 200
limit=21  ->  HTTP 400
limit=25  ->  HTTP 400
limit=50  ->  HTTP 400

Exactly twenty. And the failure arrives as a 400, which reads as "your request

body is malformed" rather than "that number is too big", so the natural

reaction is to go looking at your JSON.

Two thousand postings at twenty a page is a hundred round trips. That is the

price, and there is no parameter that lowers it.



You cannot build the URL from a company name


A Workday address carries three separate unknowns:

https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite
^^^^^^ ^^^                    ^^^^^^^^^^^^^^^^^^^^^^^
host   data centre            career site name

The host label is usually the company, but the data centre is wd1 through

wd12 with no pattern, and the site name is whatever whoever set it up typed.

External_Career_Site, external_experienced, SonyGlobalCareers,

NVIDIAExternalCareerSite. Guessing across that space is mostly 404s.

The API path adds a fourth part that the public URL does not show:

public   https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite
api      https://nvidia.wd5.myworkdayjobs.com/wday/cxs/nvidia/NVIDIAExternalCareerSite/jobs
^^^^^^^^^^^^^^^

On all four tenants I checked, that middle segment is the host label again.

Build it with a literal None in there and you get a 422, not a 404, which

at least fails in a way that does not look like a wrong company name.

So take the careers URL from the customer. It is the one thing they always

have, and it is the only reliable source for all three parts.



What the postings look like


Sparse, and worth knowing before you design a schema around it:

{
"title": "Distinguished Software Architect - Deep Learning",
"externalPath": "/job/US-CA-Santa-Clara/...",
"locationsText": "US, CA, Santa Clara",
"postedOn": "Posted Today",
"bulletFields": ["JR2001234"]
}

Five keys. No department, no employment type, no salary, no description, and

postedOn is a relative phrase rather than a date.

Counted across 80 NVIDIA postings:

Posted 30+ Days Ago    20
Posted 5 Days Ago      13
Posted 13 Days Ago     13
Posted 2 Days Ago      12
Posted Today            5
Posted Yesterday        3

Do not parse that into a timestamp. A quarter of them are "30+ Days Ago",

which has no date in it at all, and a timestamp you invented is worse than a

string you kept: the string is obviously approximate and the timestamp is not.

Give it its own field and let the consumer decide.

Measured on 2026-08-02. Four tenants carried a usable count: NVIDIA,

Salesforce, Adobe and Sony. Dell reported 0 at offset 0 as well, which is the

third trap below rather than a fifth data point. I

maintain a set of ATS scrapers that normalise

nine of these systems into one row shape, which is how I ran into all of it.


Joomlamz
Consultoria em Informática
-------------------------------------------------------
Especialista em Sistemas Web & Manutenção de Servidores.
A desenvolver o novo AplPortal com suporte a PHP 8.
Precisa de ajuda profissional? Contacte-me.

Tags: