{"slug": "rtx-ups-and-cvs-health-jobs-api-the-phenom-careers-search-past-10000-jobs", "title": "RTX, UPS and CVS Health jobs API: the Phenom careers search past 10,000 jobs", "summary": "A developer documented how Phenom-powered careers sites for RTX, UPS and CVS Health expose their full job listings through an unauthenticated POST to the /widgets endpoint, which robots.txt does not block. Testing on 2026-10-27 found that sorting by dateCreated rather than postedDate eliminates duplicate and missing results, and that CVS Health's 19,664 listings cannot be paged past a 10,000-row window, silently returning empty pages with HTTP 200. The writeup recommends faceting by category or state and deduplicating on jobSeqNo to retrieve jobs beyond that limit.", "body_md": "RTX (`careers.rtx.com`), UPS (` www.jobs-ups.com`) and CVS Health (` jobs.cvshealth.com`) run their careers sites on Phenom. Each site's own search is one `POST` to `/widgets`, with no key and no login, and robots.txt leaves it alone: it disallows `*/apply`, `*/jobcart`, `*/chatbot` and `*/px-widgets`, not `/widgets`.\n\n```\ncurl -s -X POST \"https://careers.rtx.com/widgets\" -H \"Content-Type: application/json\" \\\n  -d '{\"ddoKey\":\"refineSearch\",\"jobs\":true,\"from\":0,\"size\":500,\"sort\":{\"order\":\"desc\",\"field\":\"dateCreated\"}}' \\\n  | jq '.refineSearch.totalHits, (.refineSearch.data.jobs | length)'\n```\n\nThat printed 4834 and 500. Five things to know, measured on 2026-10-27 with a few seconds between requests.\n\nLeave out `\"jobs\": true` and the answer still carries `totalHits`, 4,834, with no jobs in it. `size` goes to 500: all 49 Phenom sites we read gave 500 rows for `size: 500` (or their whole list), and CVS gave 500 for `size: 1000`. Asking for 100 a page is five times the requests.\n\n`dateCreated`, not `postedDate`\n`postedDate` is a day at midnight, so hundreds of jobs share each value, and the order among them changes from one request to the next. Paging RTX's jobs (4,809 that evening) 100 at a time by `postedDate`, a new connection per request, gave 4,667 distinct jobs in one read and 4,719 in the next: the missing ones were on no page, and others came twice. Panera, read 500 at a time, lost 172 of 6,291. `dateCreated` carries the time to the millisecond:\n\n```\nfor from in $(seq 0 500 4500); do\n  curl -s -X POST \"https://careers.rtx.com/widgets\" -H \"Content-Type: application/json\" \\\n    -d \"{\\\"ddoKey\\\":\\\"refineSearch\\\",\\\"jobs\\\":true,\\\"from\\\":$from,\\\"size\\\":500,\\\"sort\\\":{\\\"order\\\":\\\"desc\\\",\\\"field\\\":\\\"dateCreated\\\"}}\" \\\n    | jq -r '.refineSearch.data.jobs[].jobSeqNo'\n  sleep 3\ndone | sort -u | wc -l\n```\n\nThat printed 4834, all of them. A field the site does not sort on, such as `jobSeqNo`, answers `totalHits` 0 and no error.\n\nCVS Health lists 19,664 jobs. A page answers only while `from` plus `size` stays under 10,000:\n\n```\ncurl -s -X POST \"https://jobs.cvshealth.com/widgets\" -H \"Content-Type: application/json\" \\\n  -d '{\"ddoKey\":\"refineSearch\",\"jobs\":true,\"from\":9900,\"size\":100,\"sort\":{\"order\":\"desc\",\"field\":\"dateCreated\"}}' \\\n  | jq '.refineSearch.totalHits, (.refineSearch.data.jobs | length)'\n```\n\nThat prints 0 and 0, with HTTP 200: the same answer as the end of the list. `from` 9,899 with `size` 100 still answers. A loop that pages until an empty page stops at 9,900 and reports success. Ours did, until this week: it had stored O'Reilly Auto (19,062 jobs) and Dollar Tree (15,519) at exactly 9,900 each.\n\n`counts: true` with the fields you name returns each facet's values and their counts, and `selected_fields` narrows the search to one value:\n\n```\ncurl -s -X POST \"https://jobs.cvshealth.com/widgets\" -H \"Content-Type: application/json\" \\\n  -d '{\"ddoKey\":\"refineSearch\",\"jobs\":true,\"from\":0,\"size\":1,\"counts\":true,\"all_fields\":[\"category\"]}' \\\n  | jq '.refineSearch.data.aggregations[] | select(.field==\"category\") | .value'\n```\n\nCVS's nine categories add up to its total exactly, the largest (Pharmacy) at 7,572, so each pages under the window. O'Reilly files 18,609 of its 19,062 under \"Stores\", so it goes by state: 49 values, the largest 2,345. Skip `city`: the facet lists at most 1,000 values, which added up to 6,795 of CVS's jobs. A job in two states is in two slices, so dedupe on `jobSeqNo`.\n\nThe Apply link names the system underneath. RTX's 500 newest all apply through Workday (`globalhr.wd5`), CVS's through Workday (` cvshealth.wd1`), Eli Lilly's through Workday (` lilly.wd115`). UPS splits: of its 500 newest, 252 apply through Fountain and 248 through Workday. So the same jobs can often be read from Workday too, with a different count: CVS's Workday site said 19,706 the hour Phenom said 19,665. Read one source per employer, or dedupe on the requisition number, `reqId`, which is the number in the Workday address.\n\n[Company Career Page Jobs Scraper](https://apify.com/glitchbound/ats-jobs-scraper) on Apify takes `RTX` or `UPS` by name, or any Phenom careers site as `phenom:jobs.cvshealth.com`, reads 500 a page by `dateCreated`, and slices a site past 10,000 by its facets: O'Reilly Auto came back whole, 19,062 jobs. Every other system's public endpoint, with a tested `curl`, is in [job-board-apis](https://github.com/danielhagever/job-board-apis).", "url": "https://wpnews.pro/news/rtx-ups-and-cvs-health-jobs-api-the-phenom-careers-search-past-10000-jobs", "canonical_source": "https://dev.to/glitchbound/rtx-ups-and-cvs-health-jobs-api-the-phenom-careers-search-past-10000-jobs-42km", "published_at": "2026-10-27 21:02:46+00:00", "updated_at": "2026-10-27 21:12:10.480875+00:00", "lang": "en", "topics": ["ai-crawlers", "structured-data"], "entities": ["RTX", "UPS", "CVS Health", "Phenom", "Workday", "Fountain", "O'Reilly Auto", "Eli Lilly"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/rtx-ups-and-cvs-health-jobs-api-the-phenom-careers-search-past-10000-jobs", "markdown": "https://wpnews.pro/news/rtx-ups-and-cvs-health-jobs-api-the-phenom-careers-search-past-10000-jobs.md", "text": "https://wpnews.pro/news/rtx-ups-and-cvs-health-jobs-api-the-phenom-careers-search-past-10000-jobs.txt", "jsonld": "https://wpnews.pro/news/rtx-ups-and-cvs-health-jobs-api-the-phenom-careers-search-past-10000-jobs.jsonld"}}