UKG Pro Workforce Ready (SaaShr) Jobs API.
Pull structured job listings — pay ranges, categories, and full descriptions — from any employer board on the SaaShr pod pool through one anonymous JSON endpoint, normalized by Jobo's unified jobs API.
Try the API.
Test Jobs and Feed endpoints against https://connect.jobo.world with live request/response examples, then copy ready-to-use curl commands.
What's in every response.
Data fields, real-world applications, and the companies already running on UKG Pro Workforce Ready (SaaShr).
- Structured Pay Ranges & Period
- Job Categories & Industries
- Employment Type & Required Degree
- Full Descriptions & Requirements
- Remote Status & Geocoordinates
- Configured Custom Fields
- 01Multi-Tenant Board Monitoring
- 02Compensation Benchmarking
- 03Regional Hiring Analysis
- 04Job Aggregation Feeds
How to scrape UKG Pro Workforce Ready (SaaShr).
Step-by-step guide to extracting jobs from UKG Pro Workforce Ready (SaaShr)-powered career pages—endpoints, authentication, and working code.
import re
board_url = "https://secure4.saashr.com/ta/6154221.careers"
m = re.match(
r"^(https://secure\d*\.(?:saashr|entertimeonline)\.com)/ta/(\d{5,12})\.careers$",
board_url,
)
if not m:
raise ValueError("Not a valid SaaShr board URL")
origin, tenant = m.group(1), m.group(2)
print(origin, tenant) # https://secure4.saashr.com 6154221import requests
PAGE_SIZE = 100
headers = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Referer": f"{origin}/",
"X-Requested-With": "XMLHttpRequest",
}
def fetch_page(page: int) -> dict:
url = f"{origin}/ta/rest/ui/recruitment/companies/%7C{tenant}/job-requisitions"
params = {"offset": page, "size": PAGE_SIZE, "sort": "desc", "ein_id": "", "lang": "en-US"}
resp = requests.get(url, params=params, headers=headers, timeout=15)
resp.raise_for_status()
return resp.json()
first = fetch_page(1)
print(first["_paging"]["total"], "open jobs")import math
def fetch_all() -> list[dict]:
first = fetch_page(1)
total = first["_paging"]["total"]
jobs = list(first["job_requisitions"])
pages = math.ceil(total / PAGE_SIZE)
for page in range(2, pages + 1):
jobs.extend(fetch_page(page)["job_requisitions"])
assert len(jobs) == total, f"expected {total}, got {len(jobs)}"
return jobs
all_jobs = fetch_all()for job in all_jobs:
job_id = job["id"]
location = job.get("location") or {}
employee_type = job.get("employee_type") or {}
print({
"id": job_id,
"title": job.get("job_title"),
"city": location.get("city"),
"state": location.get("state"),
"pay_from": job.get("base_pay_from"),
"pay_to": job.get("base_pay_to"),
"pay_period": job.get("base_pay_frequency"),
"employment_type": employee_type.get("name"),
"remote": job.get("is_remote_job"),
"apply_url": f"{origin}/ta/{tenant}.careers?ShowJob={job_id}&lang=en-US",
})def fetch_detail(job_id) -> dict:
url = f"{origin}/ta/rest/ui/recruitment/companies/%7C{tenant}/job-requisitions/{job_id}"
resp = requests.get(url, params={"showMap": 1, "lang": "en-US"}, headers=headers, timeout=15)
resp.raise_for_status()
return resp.json()
detail = fetch_detail(all_jobs[0]["id"])
print(detail.get("job_description"))
print(detail.get("job_requirement"))The parameter is a one-based page index despite its name — pass 1, 2, 3…, keep size fixed at 100, and derive the page count from _paging.total.
Use _paging.total as the source of truth: fetch ceil(total / 100) pages and assert the collected row count equals total before trusting the result.
Only the numbered pods secure{N}.saashr.com and secure{N}.entertimeonline.com expose the anonymous job-requisitions API. The sibling Kronos product uses a separate contract and host.
Send the exact XHR headers (Accept, a pod-root Referer, and X-Requested-With: XMLHttpRequest). If a board still rejects anonymous access, that tenant has gated its careers API.
Treat 404/410 on the detail endpoint as a removal signal and drop the job rather than retrying it.
- 1Pass offset as a 1-based page number with size=100 — never as a row offset.
- 2Trust _paging.total for completeness: collect ceil(total / 100) pages and verify the count matches.
- 3Send the anonymous XHR headers (Accept, pod-root Referer, X-Requested-With) on every request.
- 4Preserve the exact pod host from the board URL; don't normalize secure4/secure7 or swap to www.
- 5Pace requests (~100ms) and keep concurrent detail fetches low to avoid 429s.
- 6Enrich from the detail endpoint for pay, custom fields, and the full description, not just the listing.
One endpoint. All UKG Pro Workforce Ready (SaaShr) jobs. No scraping, no sessions, no maintenance.
Get API accesscurl "https://connect.jobo.world/api/jobs?sources=ukg pro workforce ready (saashr)" \
-H "X-Api-Key: YOUR_KEY" Access UKG Pro Workforce Ready (SaaShr)
job data today.
One API call. Structured data. No scraping infrastructure to build or maintain — start with the free tier and scale as you grow.